SwampCTF2025-Forensics

https://2025.swampctf.com/**challenges
请添加图片描述

Homework Help

I accidently lost some of my class notes! Can you help me recover it? (Note: Unzipped size is 4GB)
我不小心丢了一些课堂笔记!你能帮我恢复吗?(Note:解压缩大小为4GB)

用FTK挂载
请添加图片描述

发现hacking文件夹,注意到Hacking Notes.docx 它是一个已被删除但未完全擦除的文件。

恢复数据(前面打×的就是删除恢复的数据)
右键导出文件:
请添加图片描述

阅读:

请添加图片描述

得到

swampCTF{n0thing_i5_3v3r_d3l3t3d}

Preferential Treatment

We have an old Windows Server 2008 instance that we lost the password for. Can you see if you can find one in this packet capture?

我们有一个旧的Windows Server 2008实例,我们失去了密码。你能在这个数据包中找到一个吗?
#流量分析 #cpassword

我们得到的是一个数据包文件: 它是一个 pcacp 文件
请添加图片描述

跟踪tcp流,得到
请添加图片描述

我们关注这个cpassword

cpassword="dAw7VQvfj9rs53A8t4PudTVf85Ca5cmC1Xjx6TpI/cS8WD4D8DXbKiWIZslihdJw3Rf+ijboX7FgLW7pF0K6x7dfhQ8gxLq34ENGjN8eTOI="

使用公开的 Group Policy Preferences cPassword 解密密钥(见下文),并以 AES-256-CBC(IV 全 0)对该值 Base64 解码后的数据进行解密,得到明文:

swampCTF{4v3r463_w1nd0w5_53cur17y}

Python 演示代码(仅供参考):

from Crypto.Cipher import AES
import base64

# 要解密的 cPassword 字符串
cpwd = "dAw7VQvfj9rs53A8t4PudTVf85Ca5cmC1Xjx6TpI/cS8WD4D8DXbKiWIZslihdJw3Rf+ijboX7FgLW7pF0K6x7dfhQ8gxLq34ENGjN8eTOI="

# 官方公开的 32 字节 AES 密钥(MS-GPPREF 文档)
key_hex = (
    "4e9906e8fcb66cc9faf49310620ffee8"
    "f496e806cc057990209b09a433b66c1b"
)
key = bytes.fromhex(key_hex)

# 解密
iv = b'\x00' * 16
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = cipher.decrypt(base64.b64decode(cpwd))
# 去除末尾的 \x00 填充并以 UTF-16LE 解码
password = pt.rstrip(b"\x00").decode('utf-16-le')

print(password)

此处使用的 AES 密钥来源于 Microsoft 的 MS-GPPREF 协议规范:

  • 32 字节 AES 密钥:4e 99 06 e8 fc b6 6c c9 fa f4 93 10 62 0f fe e8 f4 96 e8 06 cc 05 79 90 20 9b 09 a4 33 b6 6c 1b (learn.microsoft.com)

得到

swampCTF{4v3r463_w1nd0w5_53cur17y}

Planetary Storage

My friend found this strange file while perusing his computer, but we can’t read it. Can you figure out what it is and get the information from it?

Difficulty: Easy/Medium

The flag is in the standard format.
我的朋友在浏览他的电脑时发现了这个奇怪的文件,但我们无法阅读它。你能找出它是什么并从中得到信息吗? 难度:简单/中等 flag采用标准格式。

000010.ldb用010打开

请添加图片描述

payload":“eyJrZXkiOiJcIjMzNTc5M2Q1LTRhYzEtNDgyMy05MmM3LWZkM2I1YTZhMmEwN1wiIiwib3AiOiJQVVQiLCJ2YWx1ZSI6ImV5SmtZWFJoSWpwYkluTjNZVzF3UTFSR2V6RndaalV0WWpRMU0yUXRaRFEzTkdJME5UTjlJbDBzSW1sa0lqb2lYQ0l6TXpVM09UTmtOUzAwWVdNeExUUTRNak10T1RKak55MW1aRE5pTldFMllUSmhNRGRjSWlKOSJ9”

base64解密
请添加图片描述

第二次解密:
请添加图片描述

得到

swampCTF{1pf5-b453d-d474b453}

或者用LevelDBDumper解ldb包

附件分析

==这些是 LevelDB 数据库的存储文件。==LevelDB 是由 Google 开发的高性能键值对(Key-Value)存储引擎,常用于需要快速读写的小规模数据存储场景(如浏览器缓存、区块链数据、应用本地存储等)。以下是每个文件的作用详解:


🔑 LevelDB 核心文件解析

文件名类型作用
000002.ldb数据文件存储实际的键值对数据(SSTable 格式),数字编号代表层级(Level 0,1,…)
000007.ldb数据文件同上,不同层级的 SSTable 文件
000010.ldb数据文件同上
000011.log日志文件写入操作的预写日志(Write-Ahead Log),用于崩溃恢复
CURRENT元数据文件指向当前有效的 MANIFEST 文件(如 MANIFEST-000012
CURRENT.bak备份文件CURRENT 文件的备份副本
LOCK锁文件防止多个进程同时操作数据库(独占访问锁)
LOG运行日志LevelDB 引擎的操作日志(非数据日志)
MANIFEST-000012清单文件记录数据库全局状态(文件列表、层级信息、压缩点等元数据)

⚙️ LevelDB 工作机制

  1. 写入流程
    • 数据先写入 *.log 文件(防止崩溃丢失)→ 内存(MemTable)→ 满后转为 *.ldb(磁盘 SSTable)。
  2. 读取流程
    • 优先查内存(MemTable)→ 未命中则逐层扫描 *.ldb 文件(低编号层级优先)。
  3. 压缩合并
    • 定期将小 *.ldb 合并为大文件(减少碎片),更新 MANIFEST 记录新结构。

💻 常见应用场景

软件/系统用途路径示例
Chrome 浏览器存储缓存、IndexedDB 数据~/.config/google-chrome/Default/IndexedDB/
Bitcoin Core存储未花费交易输出(UTXO)~/.bitcoin/chainstate/
Electron 应用本地数据存储(如 VS Code 扩展数据)~/.config/Code/User/globalStorage/...
Android 系统App 私有存储(LevelDB 或 RocksDB)/data/data/<app_package>/databases/

⚠️ 注意事项

  1. 禁止手动修改
    • 直接编辑文件会导致数据库损坏(LevelDB 通过 MANIFEST 严格管理文件依赖)。
  2. 迁移/备份方法
    • 需关闭数据库进程 → 整体复制目录(而非单个文件)。
  3. 查看内容工具
    • 使用专用工具解析(如 Python 的 plyvel 库):
      import plyvel
      db = plyvel.DB('/path/to/db_dir/')  # 打开数据库目录
      for key, value in db:               # 遍历所有键值对
          print(key.decode(), value.decode())
      db.close()
      

为什么会出现这些文件?

您的设备可能安装了以下类型的软件:

  • 🌐 浏览器(Chrome、Edge 的网站数据库)
  • 💰 加密货币钱包(如 Bitcoin Core)
  • 🛠️ 开发工具(VS Code、LevelDB 调试应用)
  • 📱 移动应用(Android 应用的本地存储)

检查文件所在目录即可定位来源应用(如路径含 ChromeBitcoin 等关键词)。


💎 总结

这些文件是 LevelDB 数据库的物理存储结构,包含数据文件(.ldb)、事务日志(.log)和元数据(MANIFEST/CURRENT)。其存在表明某个应用正在使用键值存储引擎管理本地数据。如需操作,务必通过 LevelDB API 或专业工具访问,避免直接修改文件!

MuddyWater

We caught a threat actor, called MuddyWater, bruteforcing a login for our Domain Controller. We have a packet capture of the intrustion. Can you figure out which account they logged in to and what the password is?

Flag format is swampCTF{<username>:<password>}

我们发现了一个名为MuddyWater的威胁行为者,他正在强行登录我们的域控制器。我们有一个数据包捕获的intrustion。你能查出他们登录的账号和密码吗? 标志格式为swampCTF{<username>:<password>}
#分析SMB2认证流程 #SMB使用NTLM认证 #NTLMv2哈希值破解 #提取NTLMv2哈希

我们初步分析发现,这个流量包使用SMB 协议

SMB2 支持多种认证机制:
这个SMB使用的是[[NTLM(NT LAN Manager)]] 认证
NTLM有一个 质询-响应 机制,所以,我们需要找到客户端的“响应”,客户端发送的加密后的挑战响应 是经过hash加密的,我们进行NTLMv2哈希值破解,从而得到 username 与 password

第 1 步 - 筛选

我们看到,这是SMB2
在SMB2 中成功登录会返回一个响应,该响应以十六进制表示。
TATUS_SUCCESS``0x00000000

我们使用这个过滤器:

smb2.nt_status == 0x00000000 && smb2.cmd == 0x01

过滤器解析:

  1. smb2.cmd == 0x01

    • 表示筛选 SMB2 登录请求的响应包SMB2_LOGIN 命令对应操作码 0x01)。

    • SMB2 协议中,客户端发送登录请求后,服务器会返回一个 cmd=0x01 的响应包。

  2. smb2.nt_status == 0x00000000

    • 表示筛选 操作成功的响应STATUS_SUCCESS 的十六进制值为 0x00000000)。

    • 该状态码明确标识登录流程已通过认证。

这将范围缩小到单个数据包:。这是登录成功的确认
请添加图片描述

第 2 步 – 找到 TCP 流:

[[分析 SMB2 认证流程]]

追踪流

tcp.stream == 6670

这显示了完整的 NTLM 登录过程:
请添加图片描述


NTLM 登录流程详解(基于 TCP 流)

当您应用 tcp.stream == 6670 后,典型流程如下:

步骤 1:协议协商(SMB2 Negotiate)
方向数据包类型关键信息
客户端 → 服务器SMB2 Negotiate Request支持协议:SMB 3.1.1
加密能力:AES-128-GCM
服务器 → 客户端SMB2 Negotiate Response选定协议:SMB 3.1.1
要求签名:Enabled

🔍 抓包特征smb2.cmd == 0x00

步骤 2:NTLM 认证交换

(1) 客户端发起认证
[[NTLM(NT LAN Manager)]]
身份验证协议

方向数据包类型关键信息
客户端 → 服务器SMB2 Session Setup Request认证类型:NTLMSSP
包含用户名(明文)
服务器 → 客户端SMB2 Session Setup Response状态:STATUS_MORE_PROCESSING_REQUIRED (0xC0000016)
NTLM 挑战令牌(8字节随机数)

(2) 客户端响应挑战

方向数据包类型关键信息
客户端 → 服务器SMB2 Session Setup RequestNTLM 加密响应
(使用用户密码哈希加密挑战令牌)
服务器 → 客户端SMB2 Session Setup Response您的 Frame 72074
状态:STATUS_SUCCESS (0x00000000)
步骤 3:会话建立
  • 服务器返回 Session ID(例如 0x00000001
  • 可能伴随 Tree Connect 请求(访问共享文件夹)

关键分析点(在 TCP 流中查找)

  1. 用户名暴露
    在首个 Session Setup Request 中查找:
    SMB2 > Security Blob > NTLMSSP > User Name

  2. 认证强度
    检查 NTLMSSP Negotiate Flags

    • NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY → 增强加密
    • 缺失此标志 → 使用弱加密(如 NTLMv1)
  3. 加密响应内容
    在第二个 Session Setup Request 中:
    NTLMSSP > NTProofStr(加密后的密码凭证)

  4. 潜在风险

    • 如果使用 NTLMv1 → 易受破解攻击
    • 若未启用 SMB 签名 → 可能遭受中间人攻击

第 3 步 – 提取哈希值:

从流量中提取NTLMv2哈希并破解步骤参照

https://zhuanlan.zhihu.com/p/52882041

请添加图片描述

找到了hack的登录流
我们把它导入到一个新的流
请添加图片描述

请添加图片描述

将其上传到 apackets,这是一个非常非常方便的提取 NTLMv2 哈希的工具。
请添加图片描述

于是我们得到了:
请添加图片描述

hackbackzip::DESKTOP-0TNOE4V:D102444D56E078F4:EB1B0AFC1EEF819C1DCCD514C9623201:01010000000000006F233D3D9F9EDB01755959535466696D0000000002001E004400450053004B0054004F0050002D00300054004E004F0045003400560001001E004400450053004B0054004F0050002D00300054004E004F0045003400560004001E004400450053004B0054004F0050002D00300054004E004F0045003400560003001E004400450053004B0054004F0050002D00300054004E004F00450034005600070008006F233D3D9F9EDB010900280063006900660073002F004400450053004B0054004F0050002D00300054004E004F004500340056000000000000000000

拿到目标机做SMB文件共享时使用的NetNTLMv2 hash后,可以利用HashCat对该hash进行破解,还原出明文密码。

保存为hack.hash
使用kali的hashcat 进行破解

hashcat -m 5600 hack.hash rockyou.txt --force

hashcat 使用参数说明

  • -m 5600 指定 hash 格式为 NTLMv2
  • wordlist 使用指定字典
  • –force 强制暴力破解
  • –show 输出结果
    请添加图片描述

可以看到,密码为pikeplace

所以,

Username: hackbackzip
Password: pikeplace

得到

swampCTF{hackbackzip:pikeplace}

Proto Proto

#利用udp发送数据 #使用nc进行udp数据交流
Moto Moto likes you. But not enough to explain how his server works. We got a pcap of the client and server communicating. Can you figure out how the server works and retrieve the flag?
摩托摩托喜欢你但不足以解释他的服务器是如何工作的。我们得到了客户端和服务器通信的pcap。你能弄清楚服务器是如何工作的吗?

tips : 题目要求分析数据包中的协议对服务器地址进行交互

请添加图片描述

这两个题是有网站的

请添加图片描述

当我追踪udp流时我发现
请添加图片描述

从网络流中可以看出,客户端发送flag.txt,并由服务器通过 UDP 进行响应

服务端:172.19.0.2
客户端:172.19.0.1
请添加图片描述

从网络流中可以看出,客户端发送flag.txt,并由服务器通过 UDP 进行响应

同样,我们将通过 UDP 将 “flag.txt” 发送到服务器,但我们将通过 nc 将 “flag.txt” 的值作为字节与有效负载一起发送。\x02\x08\x66\x6c\x61\x67\x2e\x74\x78\x74

0208666c61672e747874

发送请求(UDP)

利用nc
┌──(kali㉿kali)-[~/Desktop]
└─$ echo -ne '\x02\x08\x66\x6c\x61\x67\x2e\x74\x78\x74'|nc -u chals.swampctf.com 44254
swampCTF{r3v3r53_my_pr070_l1k3_m070_m070}

  • -ne不要直接打开 Interpret Backslash Escapes 模式 - 这个例子是可以理解的\x02
  • -uNetCat 通过 UDP 发送
  • -ne:这是echo命令的两个选项。
    • -n:表示不输出换行符,即输出内容后不会自动换行。
    • -e:表示启用对转义字符的解释,如\x表示十六进制字符。
  • nc:这是netcat的缩写,是一个功能强大的网络工具,用于读写网络连接。
  • -u:表示使用UDP协议进行通信。
利用xxd
echo -n "0208666c61672e747874" | xxd -r -p | nc -u chals.swampctf.com 44254

echo -n "0208666c61672e747874"

  • echo:这是一个命令行工具,用于在终端输出指定的内容。
  • -n这个选项表示在输出时不换行
  • "0208666c61672e747874":这是要输出的内容,看起来像是一串十六进制编码的字符串。

| xxd -r -p

  • |:这是一个管道操作符,用于将前一个命令的输出作为下一个命令的输入。
  • xxd这是一个工具,用于创建十六进制转储或从十六进制转储中恢复数据。
  • -r:表示恢复模式,即从十六进制转储中恢复数据。
  • -p:表示以纯十六进制格式处理输入。

| nc -u chals.swampctf.com 44254

  • |:再次使用管道操作符,将前一个命令的输出作为下一个命令的输入。
  • nc:这是 netcat 的缩写,一个用于网络工具,可以用于读写网络连接。
  • -u:表示使用 UDP 协议。
  • chals.swampctf.com:这是目标服务器的地址。
  • 44254:这是目标服务器的端口号。

整体解释
这个命令的作用是:

  1. 使用 echo -n 输出十六进制字符串 "0208666c61672e747874"
  2. 将这个十六进制字符串通过 xxd -r -p 转换为原始数据。
  3. 使用 nc -u 将转换后的数据通过 UDP 协议发送到 chals.swampctf.com 的 44254 端口。

得到

swampCTF{r3v3r53_my_pr070_l1k3_m070_m070}

参考链接

https://tonghuaroot.com/2020/03/02/how-to-use-hashcat-to-crack-ntlmv2-hash/

https://blog.youkuaiyun.com/shao65308/article/details/134259523

Proto Proto2

#TLV二进制字段封装格式
Moto Moto heard you were able to reverse his server code, so he set up some “encryption”. Can you figure out the key and retrieve the flag?

Moto Moto听说你能破解他的服务器密码所以他设置了一些“加密”你能找到钥匙找回flag吗?

请添加图片描述

和上一道一样,追踪udp,不过,这次需要我们发送一些“密码”
请添加图片描述

通过对这里的数据格式分析发现,看到了完整的 Tag(wire type 合并)、Length(Varint) 和 Value(三段式)

很像[[Tag–Length–Value(TLV)]] 格式
TLV 是一种二进制字段封装格式

数据格式解析

+--------+---------+-----------------------------+---------+-----------+
| 操作码 | 密钥长度 |          密钥内容           | 文件名长 |  文件名   |
| (1字节)| (1字节) |       (长度由前字段决定)     | (1字节) | (变长)    |
+--------+---------+-----------------------------+---------+-----------+
  • 操作码0x02 可能表示"读取文件"操作
    给定数据 021573757065725f7365637265745f70617373776f726408666c61672e747874 是二进制 payload 的十六进制表示,解析后结构如下:

1. 操作类型标识 (1字节)

  • 02 → 表示特定操作(如文件读取请求)

2. 密钥长度字段 (1字节)

  • 15(十六进制)→ 十进制值为 21
    表示密钥长度为 21 字节

3. 密钥内容 (21字节)

  • 73757065725f7365637265745f70617373776f7264
    转换为 ASCII:"super_secret_password"

4. 文件名长度字段 (1字节)

  • 08(十六进制)→ 十进制值为 8
    表示文件名长度为 8 字节

5. 文件名内容 (8字节)

  • 666c61672e747874
    转换为 ASCII:"flag.txt"

完整解析

字段十六进制值原始值
操作类型02固定操作标识
密钥长度15密钥长度 = 21 字节
密钥内容73757065725f7365637265745f70617373776f7264"super_secret_password"
文件名长度08文件名长度 = 8 字节
文件名666c61672e747874"flag.txt"

传输过程

  1. 序列化(发送端):

    • 程序构建二进制 payload:b"\x02\x15super_secret_password\x08flag.txt"
    • 转换为十六进制字符串:0215737570...747874(便于调试或文本传输)
  2. 传输方式

    • 二进制传输:直接发送原始字节(如 TCP/UDP 套接字、蓝牙)
    • 文本协议传输:转换为十六进制字符串(如 HTTP API、串口通信)
  3. 反序列化(接收端):

    • 按协议解析:
      1. 读取第 1 字节 → 操作类型 (0x02)
      2. 读取第 2 字节 → 密钥长度 (0x15 = 21)
      3. 读取后续 21 字节 → 密钥 (super_secret_password)
      4. 读取下一字节 → 文件名长度 (0x08 = 8)
      5. 读取后续 8 字节 → 文件名 (flag.txt)

关键特点

  • 紧凑结构:长度字段精确控制后续内容,避免分隔符冲突
  • 二进制安全:可传输任意字节(如非 ASCII 密钥)
  • 大端序:长度字段高位在前(byteorder='big'
  • 应用场景:常见于物联网设备通信、自定义协议或硬件交互

传输数据构造脚本

构造可控密钥部分 payload 的 Python 脚本:

def build_payload(custom_key):
    """
    构建自定义密钥的 payload
    :param custom_key: 字符串形式的密钥内容(如 "super_secret_password")
    :return: 十六进制格式的完整 payload
    """
    # 转换为字节并检查长度
    key_bytes = custom_key.encode('utf-8')
    if len(key_bytes) > 255:
        raise ValueError("密钥长度不能超过 255 字节")
    
    # 构建 payload 组件
    operation = b"\x02"  # 固定操作标识
    key_len = len(key_bytes).to_bytes(1, 'big')  # 密钥长度
    filename = b"flag.txt"  # 固定文件名
    filename_len = len(filename).to_bytes(1, 'big')  # 文件名长度
    
    # 组合完整 payload
    payload = operation + key_len + key_bytes + filename_len + filename
    return payload.hex()

# 使用示例
if __name__ == "__main__":
    # 用户输入自定义密钥
    user_key = input("请输入密钥内容: ").strip()
    
    try:
        # 生成 payload
        hex_payload = build_payload(user_key)
        print("\n生成的 payload (十六进制):")
        print(hex_payload)
        
        # 添加空格分隔的格式(可选)
        spaced_hex = ' '.join(hex_payload[i:i+2] for i in range(0, len(hex_payload), 2))
        print("\n格式化输出:")
        print(spaced_hex)
        
        # 原始字节预览(可选)
        print("\n原始字节预览:")
        print(bytes.fromhex(hex_payload))
    except ValueError as e:
        print(f"错误: {e}")

关于端序:什么是大端序和小端序,为什么要有字节序-优快云博客

这里做个说明,长度是不知道的
==计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。在计算机内部,小端序被广泛应用于现代 CPU 内部存储数据;而在其他场景,==比如网络传输和文件存储则使用大端序

所以,在这里因为要用到后面的UDP传输中,所以我们使用大端序

密钥的试探

请添加图片描述

我们把key设置为encryption

请输入密钥内容: encryption

生成的 payload (十六进制):
020a656e6372797074696f6e08666c61672e747874

格式化输出:
02 0a 65 6e 63 72 79 70 74 69 6f 6e 08 66 6c 61 67 2e 74 78 74

原始字节预览:
b'\x02\nencryption\x08flag.txt'

输出了flag的尾部

响应十六进制: 077f4666705641454e785c3037305f6d3037305f35384832425e32635732045f345f6e305f6e307d0a

解码: FfpVAENx\070_m070_58H2B^2cW2_4_n0_n0}

密钥为swampCTF{y0u_kn0w_b3773r_7h4n_7h47}时,输出

响应十六进制: 07695f646f5f7265616c4b652c0c467a70340652686a11624278757f0a33350d32082b345c6d387f14

解码: i_do_realKe,
Fzp4RhjbBxu
+4\m8

再将i_do_real作为密钥输入

响应十六进制: 077377616d704354467b5b0a3d3c7266252235590439490e4242237b57020e55054e7928437306760b

解码: swampCTF{[
=<rf%"5Y9IBB#{WUNy(Csv

此时看到了flag的头部,大致可以猜测这是一个对称加密,加密秘钥为i_do_real_encryption

完整脚本

import socket
import time

# ===== 用户配置区域 =====
SERVER_IP = "127.0.0.1"  # 目标服务器地址
SERVER_PORT = 12345       # 目标服务器端口
CUSTOM_KEY = "i_do_real_encryption"  # 协议密钥
TIMEOUT = 3.0             # 等待响应时间(秒)
# ======================

def build_payload(custom_key):
    """
    构建协议payload(使用大端序处理长度字段)
    """
    # 将密钥转换为字节并验证长度
    key_bytes = custom_key.encode('utf-8')
    if len(key_bytes) > 255:
        raise ValueError("密钥长度不能超过255字节")
    
    # 构建协议数据包(大端序)
    return (
        b"\x02" +  # 固定操作码
        len(key_bytes).to_bytes(1, 'big') +  # 密钥长度(大端序)
        key_bytes +  # 密钥内容
        len(b"flag.txt").to_bytes(1, 'big') +  # 文件名长度(大端序)
        b"flag.txt"  # 固定文件名
    )

def send_udp_payload():
    """发送payload并接收响应"""
    try:
        # 创建UDP套接字
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(TIMEOUT)
        
        # 构建payload
        payload = build_payload(CUSTOM_KEY)
        
        # 发送数据
        sock.sendto(payload, (SERVER_IP, SERVER_PORT))
        print(f"[+] 已发送 {len(payload)} 字节到 {SERVER_IP}:{SERVER_PORT}")
        
        # 等待响应
        print(f"[*] 等待响应 (最多 {TIMEOUT} 秒)...")
        try:
            response, addr = sock.recvfrom(4096)
            print(f"[+] 收到来自 {addr[0]}:{addr[1]} 的响应 ({len(response)} 字节)")
            
            # 显示响应内容
            print(f"响应十六进制: {' '.join(f'{b:02x}' for b in response)}")
            print(f"原始内容: {response}")
            
            # 使用errors='ignore'尝试解码为文本
            try:
                # 忽略无法解码的字节
                decoded = response.decode('utf-8', errors='ignore')
                print(f"可读内容: {decoded}")
            except Exception as e:
                print(f"[!] 解码错误: {e}")
            
            return response
        except socket.timeout:
            print("[!] 超时: 未收到响应")
            return None
    except Exception as e:
        print(f"[!] 错误: {e}")
        return None
    finally:
        sock.close()

if __name__ == "__main__":
    print("===== UDP协议客户端 =====")
    print(f"目标: {SERVER_IP}:{SERVER_PORT}")
    print(f"密钥: {CUSTOM_KEY}")
    
    response = send_udp_payload()
    
    if response is not None:
        print("\n[+] 操作成功完成")
    else:
        print("\n[!] 操作未完成")

得到

swampCTF{m070_m070_54y5_x0r_15_4_n0_n0}

参考学习链接

CTF 报道 |X

swampctf2025 WP-先知社区

SwampCTF-2025-forensic-WRITEUP/SwampCTF 2025 法医 WRITEUP.md 在主要 ·jstQHuy/SwampCTF-2025-法医-WRITEUP

Diephho/SwampCTF2025-Forensics: Writeup Forensics
SwampCTF 2025 Writeup - 铃木的网络日记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值