ROP - Return Oriented Programing
Return-Oriented Programming (ROP), No-Execute (NX) veya Data Execution Prevention (DEP) gibi güvenlik önlemlerini atlatmak için kullanılan gelişmiş bir sömürü tekniğidir. Bir saldırgan, kabuk kodu enjekte etmek ve yürütmek yerine, genellikle ikili dosyada veya yüklenmiş kütüphanelerde bulunan, "gadget" olarak bilinen kod parçalarını kullanır. Her gadget genellikle bir ret
talimatı ile biter ve veri kaydırmak veya aritmetik işlemler gibi küçük bir işlem gerçekleştirir. Bu gadget'ları bir araya getirerek, bir saldırgan, NX/DEP korumalarını atlayarak keyfi işlemler gerçekleştirmek için bir yük oluşturabilir.
ROP Nasıl Çalışır
Kontrol Akışı Kaçırma: İlk olarak, bir saldırganın bir programın kontrol akışını ele geçirmesi gerekir, genellikle bir tam buffer taşması kullanarak yığında kaydedilen bir dönüş adresini üzerine yazarak.
Gadget Zinciri: Saldırgan daha sonra istenen işlemleri gerçekleştirmek için dikkatlice gadget'ları seçer ve birbirine bağlar. Bu, bir işlev çağrısı için argümanları ayarlamayı, işlevi çağırmayı (örneğin,
system("/bin/sh")
), ve gerekli temizlik veya ek işlemleri ele almayı içerebilir.Yük Yürütme: Kırılgan işlev döndüğünde, meşru bir konuma dönmemek yerine, gadget zincirini yürütmeye başlar.
Araçlar
Genellikle, gadget'lar ROPgadget, ve ropper veya doğrudan pwntools (ROP) kullanılarak bulunabilir.
x 32-bit Örneğinde ROP Zinciri
x86 (32-bit) Çağrı Kuralları
cdecl: Çağrı yapan yığını temizler. İşlev argümanları ters sırayla (sağdan sola) yığına itilir. Argümanlar sağdan sola doğru yığına itilir.
stdcall: Cdecl'ye benzer, ancak yığını temizleme işlemi çağrıyı yapan işlevin sorumluluğundadır.
Gadget'lar Bulma
İlk olarak, ikili dosya veya yüklenmiş kütüphaneler içinde gerekli gadget'ları tanımladığımızı varsayalım. İlgilendiğimiz gadget'lar şunlardır:
pop eax; ret
: Bu gadget, yığının en üst değeriniEAX
kaydedicisine iter ve ardından döner, böyleceEAX
üzerinde kontrol sağlar.pop ebx; ret
: Yukarıdakiyle benzer, ancakEBX
kaydedicisi için,EBX
üzerinde kontrol sağlar.mov [ebx], eax; ret
:EAX
içindeki değeriEBX
tarafından işaret edilen bellek konumuna taşır ve ardından döner. Bu genellikle bir write-what-where gadget olarak adlandırılır.Ayrıca,
system()
işlevinin adresine sahibiz.
ROP Zinciri
pwntools kullanarak, ROP zinciri yürütmesi için yığına hazırlık yaparız ve aşağıdaki gibi devam ederiz, system('/bin/sh')
'yi yürütmeyi amaçlayarak, zincirin aşağıdaki ile başladığına dikkat edin:
Hizalama amaçlı bir
ret
talimatı (isteğe bağlı)system
işlevinin adresi (ASLR devre dışı bırakılmış ve bilinen libc varsayılarak, daha fazla bilgi için Ret2lib)system()
'dan dönen adres için yer tutucu"/bin/sh"
dizesi adresi (system işlevi için parametre)
x64 Örneğinde ROP Zinciri
x64 (64-bit) Çağrı Kuralları
Unix benzeri sistemlerde System V AMD64 ABI çağrı kuralını kullanır, burada ilk altı tamsayı veya işaretçi argüman
RDI
,RSI
,RDX
,RCX
,R8
veR9
registerlara iletilir. Ek argümanlar yığına iletilir. Dönüş değeriRAX
registerına yerleştirilir.Windows x64 çağrı kuralı ilk dört tamsayı veya işaretçi argümanlar için
RCX
,RDX
,R8
veR9
kullanır, ek argümanlar yığına iletilir. Dönüş değeriRAX
registerına yerleştirilir.Registerlar: 64-bit registerlar arasında
RAX
,RBX
,RCX
,RDX
,RSI
,RDI
,RBP
,RSP
veR8
ileR15
bulunur.
Gadget'ları Bulma
Amacımız, RDI registerını ayarlamamıza ( system() fonksiyonuna "/bin/sh" dizesini argüman olarak iletmek için) ve ardından system() fonksiyonunu çağırmamıza izin verecek gadget'lara odaklanmak. Aşağıdaki gadget'ları tanımladığımızı varsayalım:
pop rdi; ret: Yığının en üst değerini RDI'ya çıkarır ve ardından döner. system() için argümanımızı ayarlamak için temel öneme sahiptir.
ret: Basit bir dönüş, bazı senaryolarda yığın hizalaması için kullanışlıdır.
Ve system() fonksiyonunun adresini biliyoruz.
ROP Zinciri
Aşağıda, x64 üzerinde system('/bin/sh')'ı çalıştırmayı amaçlayan bir ROP zinciri oluşturup çalıştırmak için pwntools kullanarak bir örnek bulunmaktadır:
Yığın Hizalaması
x86-64 ABI, bir çağrı talimatı yürütüldüğünde yığının 16 bayt hizalandığını sağlar. LIBC, performansı optimize etmek için SSE talimatları (örneğin movaps) kullanır ve bu hizalamayı gerektirir. Eğer yığın düzgün hizalanmamışsa (yani RSP 16'nın katı değilse), system gibi fonksiyonlara yapılan çağrılar bir ROP zincirinde başarısız olacaktır. Bunun düzeltilmesi için ROP zincirinizde system'i çağırmadan önce basitçe bir ret gadget ekleyin.
x86'ya karşı x64 ana fark
x64, ilk birkaç argüman için kayıtları kullandığından, basit fonksiyon çağrıları için genellikle x86'dan daha az gadget gerektirir, ancak doğru gadget'ları bulup zincirlemek, artan kayıt sayısı ve daha büyük adres alanı nedeniyle daha karmaşık olabilir. x64 mimarisinde artan kayıt sayısı ve daha büyük adres alanı, özellikle Return-Oriented Programming (ROP) bağlamında, hem fırsatlar hem de zorluklar sunar.
ARM64 Örneğinde ROP Zinciri
ARM64 Temelleri ve Çağrı Kuralları
Bu bilgiler için aşağıdaki sayfaya bakın:
Introduction to ARM64v8ROP'a Karşı Korumalar
Yığın Kanaryaları: BOF durumunda, ROP zincirini kötüye kullanmak için geri dönüş işaretçilerini üzerine yazmak için yığın kanaryasını atlamak gereklidir.
Gadget Eksikliği: Yeterli sayıda gadget yoksa ROP zinciri oluşturulamaz.
ROP tabanlı teknikler
ROP'un sadece keyfi kodu yürütmek için bir teknik olduğunu unutmayın. ROP'a dayalı birçok Ret2XXX tekniği geliştirilmiştir:
Ret2lib: Yüklenmiş bir kütüphaneden keyfi parametrelerle keyfi işlevleri çağırmak için ROP'u kullanın (genellikle
system('/bin/sh')
gibi bir şey).
Ret2Syscall: Bir sistem çağrısına, örneğin
execve
, hazırlamak için ROP'u kullanın ve keyfi komutları yürütün.
EBP2Ret ve EBP Zincirleme: İlk olarak akışı kontrol etmek için EBP'yi EIP yerine kötüye kullanacak ve ikincisi Ret2lib'e benzer ancak akışı çoğunlukla EBP adresleriyle kontrol eder (ancak EIP'yi kontrol etmek de gereklidir).
Diğer Örnekler ve Referanslar
64 bit, Pie ve nx etkin, kanarya yok, RIP'yi yalnızca bir
vsyscall
adresiyle üzerine yazarak, sızdıran bayrağı elde etmek için işlevin bir kısmını almak için yığında bir sonraki adrese dönüş yapacak bir kısmi üzerine yazmaarm64, ASLR yok, ROP gadget'ı yığını yürütülebilir yapmak ve yığında shellcode'a atlamak için
Last updated