Stack Pivoting - EBP2Ret - EBP chaining
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Bu teknik, Base Pointer (EBP)'i manipüle etme yeteneğinden yararlanarak, EBP kaydının dikkatli kullanımı ve leave; ret
talimat dizisi aracılığıyla birden fazla işlevin yürütülmesini zincirleme imkanı sağlar.
Hatırlatmak gerekirse, leave
temelde şunu ifade eder:
And as the EBP is in the stack before the EIP it's possible to control it controlling the stack.
Bu teknik, EBP kaydını değiştirebilirken EIP kaydını doğrudan değiştirme yolunuz yoksa özellikle faydalıdır. Fonksiyonların çalışmayı bitirdiğinde gösterdiği davranışı kullanır.
Eğer fvuln
'ın çalışması sırasında, yığın içinde shellcode'unuzun adresine işaret eden bir sahte EBP enjekte etmeyi başarırsanız (artı pop
işlemi için 4 byte ekleyerek), EIP'yi dolaylı olarak kontrol edebilirsiniz. fvuln
dönerken, ESP bu hazırlanmış konuma ayarlanır ve sonraki pop
işlemi ESP'yi 4 azaltır, etkili bir şekilde orada saldırgan tarafından saklanan bir adrese işaret eder.
2 adresi bilmeniz gerektiğini unutmayın: ESP'nin gideceği yer ve ESP tarafından işaret edilen adresi yazmanız gereken yer.
Öncelikle, rastgele veri/adres yazabileceğiniz bir adresi bilmeniz gerekir. ESP buraya işaret edecek ve ilk ret
çalıştırılacak.
Sonra, rastgele kod çalıştıracak ret
tarafından kullanılan adresi bilmeniz gerekir. Şunları kullanabilirsiniz:
Geçerli bir ONE_GADGET adresi.
system()
adresi, ardından 4 gereksiz byte ve "/bin/sh"
adresi (x86 bit).
jump esp;
gadget'ının adresi (ret2esp) ardından çalıştırılacak shellcode.
Bazı ROP zincirleri.
Kontrollü bellek kısmındaki bu adreslerden önce 4
byte bulunması gerektiğini unutmayın, çünkü pop
kısmı leave
talimatının bir parçasıdır. Bu 4B'yi kötüye kullanarak ikinci sahte EBP ayarlamak ve yürütmeyi kontrol etmeye devam etmek mümkün olacaktır.
Bu tekniğin "Off-By-One Exploit" olarak bilinen özel bir varyantı vardır. EBP'nin en az anlamlı byte'ını yalnızca değiştirebildiğinizde kullanılır. Böyle bir durumda, ret
ile atlanacak adresi saklayan bellek konumu EBP ile ilk üç byte'ı paylaşmalıdır, bu da daha kısıtlı koşullarla benzer bir manipülasyona izin verir.
Genellikle, mümkün olduğunca uzağa atlamak için byte 0x00 değiştirilir.
Ayrıca, yığında bir RET sled kullanmak ve gerçek ROP zincirini en sona koymak yaygındır, böylece yeni ESP'nin RET SLED içinde işaret etmesi ve son ROP zincirinin çalıştırılması daha olası hale gelir.
Bu nedenle, yığının EBP
girişine kontrol edilen bir adres koyarak ve EIP
'de leave; ret
adresi koyarak, ESP
'yi yığından kontrol edilen EBP
adresine taşımak mümkündür.
Artık, ESP
istenen bir adrese işaret ediyor ve yürütülecek bir sonraki talimat bir RET
. Bunu kötüye kullanmak için, kontrol edilen ESP yerine şunları yerleştirmek mümkündür:
&(next fake EBP)
-> leave
talimatından pop ebp
nedeniyle yeni EBP'yi yükle
system()
-> ret
tarafından çağrılır
&(leave;ret)
-> sistem sona erdikten sonra çağrılır, ESP'yi sahte EBP'ye taşır ve tekrar başlar
&("/bin/sh")
-> system
için parametre
Temelde bu şekilde, programın akışını kontrol etmek için birkaç sahte EBP'yi zincirlemek mümkündür.
Bu, ret2lib gibidir, ancak görünür bir faydası olmadan daha karmaşıktır, ancak bazı kenar durumlarında ilginç olabilir.
Ayrıca, bu tekniği bir stack leak ile kazanan bir fonksiyonu çağırmak için kullanan bir challenge örneği var. Bu, sayfanın son yüklemesidir:
Bu yazıda açıklandığı gibi, eğer bir ikili bazı optimizasyonlarla derlenmişse, EBP asla ESP'yi kontrol etmez, bu nedenle EBP'yi kontrol ederek çalışan herhangi bir istismar temelde başarısız olur çünkü gerçek bir etkisi yoktur. Bu, prolog ve epilog değişiklikleri ikili optimize edildiğinde gerçekleşir.
Optimize edilmemiş:
Optimize edilmiş:
pop rsp
gadgetBu sayfada bu tekniği kullanan bir örnek bulabilirsiniz. Bu zorluk için 2 belirli argümanla bir fonksiyon çağrılması gerekiyordu ve bir pop rsp
gadget vardı ve stack'ten bir leak vardı:
ret2esp tekniğini burada kontrol edin:
64 bit, bir ret sled ile başlayan bir rop zinciri ile bir off by one istismarı
64 bit, no relro, canary, nx ve pie. Program, yığın veya pie için bir leak ve bir qword'un WWW'sini sağlar. Önce yığın leak'ini alın ve pie leak'ini geri almak için WWW'yi kullanın. Ardından, .fini_array
girişlerini kötüye kullanarak sonsuz bir döngü oluşturmak için WWW'yi kullanın + __libc_csu_fini
çağrısı (daha fazla bilgi burada). Bu "sonsuz" yazmayı kötüye kullanarak, .bss içinde bir ROP zinciri yazılır ve RBP ile pivotlama ile çağrılır.
ARM64'te, fonksiyonların prologları ve epilogları yığın içinde SP kaydını saklamaz ve geri almaz. Dahası, RET
komutu SP tarafından işaret edilen adrese dönmez, x30
içindeki adrese döner.
Bu nedenle, varsayılan olarak, sadece epilogu kötüye kullanarak SP kaydını kontrol edemezsiniz. Ve SP'yi kontrol etmeyi başarırsanız bile, x30
kaydını kontrol etmenin bir yoluna ihtiyacınız olacaktır.
prolog
epilog
ARM64'te yığın pivotlamaya benzer bir şey gerçekleştirme yolu, SP
'yi kontrol edebilmek (SP'ye geçirilen bir kaydı kontrol ederek veya bir nedenle SP'nin adresini yığından alması ve bir taşma yaşanması durumunda) ve ardından epilogu kötüye kullanarak kontrollü bir SP
'den x30
kaydını yüklemek ve RET
ile ona dönmektir.
Ayrıca, aşağıdaki sayfada ARM64'teki Ret2esp eşdeğerini görebilirsiniz:
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)