Ret2csu
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)
ret2csu, bir programın kontrolünü almaya çalışırken, genellikle programın davranışını manipüle etmek için kullandığınız gadgets'ları bulamadığınızda kullanılan bir hacking tekniğidir.
Bir program belirli kütüphaneleri (libc gibi) kullandığında, programın farklı parçalarının birbirleriyle nasıl iletişim kuracağını yönetmek için bazı yerleşik işlevlere sahiptir. Bu işlevler arasında, özellikle __libc_csu_init
adı verilen kaybolan gadgets'larımız olarak hareket edebilecek bazı gizli mücevherler bulunmaktadır.
__libc_csu_init
içinde vurgulanması gereken iki talimat dizisi (gadget) bulunmaktadır:
İlk dizi, birkaç kaydın (rbx, rbp, r12, r13, r14, r15) değerlerini ayarlamamıza olanak tanır. Bunlar, daha sonra kullanmak istediğimiz sayıları veya adresleri depolayabileceğimiz slotlar gibidir.
Bu alet, yığın üzerindeki değerleri bu kayıtlara alarak kontrol etmemizi sağlar.
İkinci dizilim, ayarladığımız değerleri kullanarak birkaç şey yapar:
Belirli değerleri diğer kayıtlara taşıma, bunları fonksiyonlarda parametre olarak kullanmamız için hazır hale getirme.
r15 ve rbx'deki değerleri toplayarak belirlenen bir konuma çağrı yapma, ardından rbx'i 8 ile çarpma.
Belki oraya yazmak için herhangi bir adres bilmiyorsunuz ve bir ret
talimatına ihtiyacınız var. İkinci gadget'ın da bir ret
ile biteceğini unutmayın, ancak ona ulaşmak için bazı koşulları yerine getirmeniz gerekecek:
Koşullar şunlardır:
[r12 + rbx*8]
çağrılabilir bir fonksiyonu depolayan bir adrese işaret etmelidir (eğer bir fikriniz yoksa ve pie yoksa, sadece _init
fonksiyonunu kullanabilirsiniz):
Eğer _init 0x400560
adresindeyse, GEF kullanarak bellekte ona işaret eden bir işaretçi arayın ve [r12 + rbx*8]
'in _init'e işaret eden adres olmasını sağlayın:
rbp
ve rbx
aynı değere sahip olmalıdır, atlamayı önlemek için
Dikkate almanız gereken bazı atlanan pops var
rdi
ve rsi
'yi ret2csu gadget'ından kontrol etmenin bir başka yolu, belirli ofsetlere erişmektir:
Daha fazla bilgi için bu sayfayı kontrol edin:
BROP - Blind Return Oriented ProgrammingBir syscall yapmak veya write()
gibi bir fonksiyonu çağırmak istediğinizi hayal edin, ancak rdx
ve rsi
kayıtlarında parametreler için belirli değerlere ihtiyacınız var. Normalde, bu kayıtları doğrudan ayarlayan gadget'lar ararsınız, ancak bulamazsınız.
Burada ret2csu devreye giriyor:
Kayıtları Ayarlayın: İlk sihirli gadget'ı kullanarak yığın üzerindeki değerleri rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) ve r15'e pop edin.
İkinci Gadget'ı Kullanın: Bu kayıtlar ayarlandığında, ikinci gadget'ı kullanırsınız. Bu, seçtiğiniz değerleri rdx
ve rsi
'ye (sırasıyla r14 ve r13'ten) taşımanıza olanak tanır ve bir fonksiyon çağrısı için parametreleri hazırlar. Ayrıca, r15
ve rbx
'i kontrol ederek, programın hesapladığınız adreste bulunan bir fonksiyonu çağırmasını sağlayabilirsiniz ve bu adresi [r15 + rbx*8]
içine yerleştirebilirsiniz.
Bu tekniği kullanan ve burada açıklayan bir örneğiniz var ve bu, kullanılan son istismar:
Not edin ki önceki exploit bir RCE
gerçekleştirmek için değil, sadece win
adlı bir fonksiyonu çağırmak içindir (ROP zincirinde win
adresini stdin'den alarak ve bunu r15'te saklayarak) ve üçüncü bir argüman olarak 0xdeadbeefcafed00d
değerini alır.
Aşağıdaki exploit bu sayfadan çıkarılmıştır; burada ret2csu kullanılıyor ancak çağrıyı kullanmak yerine, karşılaştırmaları atlayarak ve çağrıdan sonra ret
'e ulaşarak çalışmaktadır:
Genellikle bu durumlar da ret2plt + ret2lib ile savunmasızdır, ancak bazen libc'de doğrudan bulduğunuz gadget'larla kolayca kontrol edilebilecek parametrelerden daha fazlasını kontrol etmeniz gerekir. Örneğin, write()
fonksiyonu üç parametre gerektirir ve bunların hepsini doğrudan ayarlamak için gadget bulmak mümkün olmayabilir.