BROP - Blind Return Oriented Programming
Reading time: 6 minutes
tip
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!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Temel Bilgiler
Bu saldırının amacı, savunmasız ikili hakkında herhangi bir bilgi olmadan bir ROP'u kötüye kullanabilmektir.
Bu saldırı aşağıdaki senaryoya dayanmaktadır:
- Bir yığın zafiyeti ve bunu tetikleme bilgisi.
- Çöktükten sonra yeniden başlatılan bir sunucu uygulaması.
Saldırı
1. Savunmasız ofseti bul sunucu arızası tespit edilene kadar bir karakter daha göndererek
2. Canary'yi brute-force ile bul
3. Yığın içindeki saklanan RBP ve RIP adreslerini brute-force ile bul
Bu süreçler hakkında daha fazla bilgi bulabilirsiniz burada (BF Forked & Threaded Stack Canaries) ve burada (BF Addresses in the Stack).
4. Durdurma gadget'ını bul
Bu gadget, ROP gadget'ı tarafından ilginç bir şeyin çalıştırıldığını doğrulamayı sağlar çünkü yürütme çökmez. Genellikle, bu gadget yürütmeyi durduracak bir şeydir ve belirli bir ROP gadget'ının çalıştırıldığını doğrulamak için ROP zincirinin sonunda yer alır.
5. BROP gadget'ını bul
Bu teknik ret2csu gadget'ını kullanır. Bunun nedeni, bu gadget'a bazı talimatların ortasında erişirseniz rsi
ve rdi
'yi kontrol eden gadget'lar elde etmenizdir:
Bunlar gadget'lar olacaktır:
pop rsi; pop r15; ret
pop rdi; ret
Bu gadget'lar ile bir fonksiyonun 2 argümanını kontrol etmenin mümkün olduğunu unutmayın.
Ayrıca, ret2csu gadget'ının çok benzersiz bir imzası olduğunu unutmayın çünkü yığından 6 kayıt alacak. Bu nedenle, şöyle bir zincir gönderilir:
'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP
Eğer STOP çalıştırılırsa, bu temelde yığından 6 kayıt alan bir adresin kullanıldığı anlamına gelir. Ya da kullanılan adres de bir STOP adresiydi.
Bu son seçeneği kaldırmak için aşağıdaki gibi yeni bir zincir çalıştırılır ve önceki zincirin 6 kayıt aldığını doğrulamak için STOP gadget'ını çalıştırmamalıdır:
'A' * offset + canary + rbp + ADDR
ret2csu gadget'ının adresini bilerek, rsi
ve rdi
'yi kontrol eden gadget'ların adresini çıkarmak mümkündür.
6. PLT'yi bul
PLT tablosu 0x400000 adresinden veya yığından sızdırılan RIP adresinden (eğer PIE kullanılıyorsa) aranabilir. Tablo girişleri 16B (0x10B) ile ayrılmıştır ve bir fonksiyon çağrıldığında sunucu çökmez, hatta argümanlar doğru olmasa bile. Ayrıca, bir girişin adresini kontrol etmek PLT + 6B ile de çökmez çünkü bu ilk yürütülen koddur.
Bu nedenle, PLT tablosunu aşağıdaki davranışları kontrol ederek bulmak mümkündür:
'A' * offset + canary + rbp + ADDR + STOP
-> çökme yok'A' * offset + canary + rbp + (ADDR + 0x6) + STOP
-> çökme yok'A' * offset + canary + rbp + (ADDR + 0x10) + STOP
-> çökme yok
7. strcmp bulma
strcmp
fonksiyonu rdx
kaydını karşılaştırılan stringin uzunluğuna ayarlar. rdx
'nin üçüncü argüman olduğunu ve daha sonra programı sızdırmak için 0'dan büyük olması gerektiğini unutmayın.
strcmp
'nin PLT'deki konumunu, artık fonksiyonların ilk 2 argümanını kontrol edebildiğimiz gerçeğine dayanarak bulmak mümkündür:
- strcmp(<okunmayan addr>, <okunmayan addr>) -> çökme
- strcmp(<okunmayan addr>, <okunan addr>) -> çökme
- strcmp(<okunan addr>, <okunmayan addr>) -> çökme
- strcmp(<okunan addr>, <okunan addr>) -> çökme yok
Bunu, PLT tablosundaki her girişi çağırarak veya PLT yavaş yolu kullanarak kontrol edebiliriz; bu, temelde PLT tablosundaki bir girişi + 0xb (bu dlresolve
'a çağrıda bulunur) çağırmak ve ardından yığında sorgulamak istediğiniz giriş numarasını (sıfırdan başlayarak) eklemektir:
- strcmp(<okunmayan addr>, <okunan addr>) -> çökme
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
-> Çökecek- strcmp(<okunan addr>, <okunmayan addr>) -> çökme
b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
- strcmp(<okunan addr>, <okunan addr>) -> çökme yok
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
Unutmayın ki:
- BROP + 0x7
pop RSI; pop R15; ret;
'ye işaret eder - BROP + 0x9
pop RDI; ret;
'ye işaret eder - PLT + 0xb dl_resolve'a bir çağrıya işaret eder.
strcmp
'yi bulduktan sonra, rdx
'yi 0'dan büyük bir değere ayarlamak mümkündür.
tip
Genellikle rdx
'nin zaten 0'dan büyük bir değeri barındıracağını unutmayın, bu nedenle bu adım gerekli olmayabilir.
8. Write veya eşdeğerini bulma
Son olarak, ikiliyi sızdırmak için verileri dışarı aktaran bir gadget'a ihtiyaç vardır. Ve bu noktada 2 argümanı kontrol edebiliriz ve rdx
'yi 0'dan büyük ayarlayabiliriz.
Bunu kötüye kullanmak için 3 yaygın fonksiyon vardır:
puts(data)
dprintf(fd, data)
write(fd, data, len(data)
Ancak, orijinal makalede yalnızca write
'den bahsedilmektedir, bu nedenle bunun hakkında konuşalım:
Mevcut sorun, write fonksiyonunun PLT içindeki yerini bilmememizdir ve verileri soketimize göndermek için bir fd numarasını bilmememizdir.
Ancak, PLT tablosunun nerede olduğunu biliyoruz ve davranışına dayanarak write'ı bulmak mümkündür. Ve sunucu ile birçok bağlantı oluşturabiliriz ve bazı bağlantılarımızla eşleşmesini umarak yüksek bir FD kullanabiliriz.
Bu fonksiyonları bulmak için davranış imzaları:
'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Eğer veri yazdırılırsa, puts bulundu'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Eğer veri yazdırılırsa, dprintf bulundu'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Eğer veri yazdırılırsa, write bulundu
Otomatik Sömürü
Referanslar
- Orijinal makale: https://www.scs.stanford.edu/brop/bittau-brop.pdf
- https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop
tip
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!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.