前言

刚学CTF Web,直接做网上的CTF Web题感觉知识点有些零散,因此打算先做做WebGoat。并且尽量把做题的方法和一些感想记录下来。我使用的WebGoat版本为8.1.0。

Introducing

WebGoat

就介绍了一下WebGoat,没什么好说。

WebWolf

告诉你WebGoat和WebWolf的联动关系。

Stage 3

随意输入一个email(邮箱用户名必须和WebGoat的用户名一致,域名可以随便写),然后点击Send e-mail按钮。打开WebWolf的Mailbox选项卡,就可以看到系统发送的那封邮件,就可以获取到unique code了。

Stage 4

告诉你WebWolf的Incoming requests选项卡会记录下所有发送到/landing的请求,可以方便我们测试。

点击Click here to reset your password,会弹出一个重置密码的页面(当然是假的),随便填一个密码,发现提交到WebWolf的\landing路径,于是可以打开WebWolf看到该请求有一个名为uniqueCode的参数,填入即可。

General

HTTP Basics

介绍了一些HTTP的基本概念。

Stage 2

随意输入一个名字点击Go即可。

同时可以打开开发者工具,抓到刚才那个请求,是一个POST请求,也没什么别的参数,就先过吧。

Stage 3

刚才已经知道是POST请求了,第一个框填入POST即可。

第二个magic number刚开始一点头绪也没有,后来发现可以先留空提交,同时抓到提交的那个请求,有一个名为magic_num的GET参数,填入即可。

其实还有一种方法,直接审核元素,找到hidden的input标签。如图:hidden的input标签

HTTP Proxies

主要讲了用代理调试HTTP(S)网页。它介绍的是ZAP,但我用的还是Burp Suite。

Stage 6

先挂上代理,用Burp Suite拦截下提交的请求,按照要求修改下面三处即可。注入修改请求

Developer Tools

主要将开发者工具的使用。

Stage 4

打开开发者工具的控制台,输入webgoat.customjs.phoneHome(),就可以找到类似phoneHome Response is -663132140的文本(电话号码还能是负的???),把电话号码提交即可。

Stage 6

点击”Go”按钮,抓到发送的请求,将其POST的networkNum的值提交即可。

CIA Triad

讲了一些注意事项,看了自己做吧。。

Crypto Basics

从这里开始有一些难度了(可能是我对这一块不熟)。介绍了一些常见的密码的使用。

Stage 2

Base64编码(严格来说它不能算加密),一般看到字符串后面以=结尾,就可以猜一猜Base64了。这是HTTP基本认证用的加密。可以使用这个网站,或者使用命令行:

1
2
3
4
#加密
echo 明文 | base64
#解密
echo 密文 | base64 -d

解题过程:直接将那一串字符Base64解码,冒号前是用户名,冒号后是密码。

Stage 3

介绍了一些其它编码方式。

Html 编码,编码解码点这里

UU编码,和Base64有点类似,编码解码点这里

XOR编码,之前也没见过,看了hints才搜到这个网站 WebSphere Password Decoder。解题只要把那段字符扔到上面的那个网站解密就行了。

Stage 4

讲了一些Hash的方式,Hash是不可逆的,但是可以通过暴力尝试或者查表进行破解。可以使用Hashcat爆破,或者直接去MD5在线解密查询。

Stage 6

介绍一些数字签名的方式。

先将私钥字符串保存到文件private.txt,然后执行openssl rsa -in private.txt -modulus -noout,就可以得到模数了。

然后再用rsa私钥进行加密,echo -n [你得到的模数] | openssl dgst -sha256 -sign private.txt | base64,输出的就是签名了。

echo-n参数是结尾不输出换行,一开始没有加,找了好久都找不到错误。

Stage 8

先按照要求运行docker环境,即docker run -d webgoat/assignments:findthesecret,然后用sudo docker ps查看该容器的名称,然后用sudo docker exec -ti [名称] /bin/bash连接。

我们的目标是获得/root目录下的一个密码文件,文件名叫什么目前还不知道,显然我们需要获得root权限,但是直接su需要密码。因此我们需要修改root的密码。

  1. 先退出docker的bash,用sudo docker container cp [名称]:/etc/shadow ./shadow文件复制出来。

  2. 根据linux密码储存的规则$id$salt$encrypted,我们可以自己生成一个密码。于是用python写了一段代码。

    1
    2
    3
    4
    import crypt,random
    passwd=input("Please input your password: ")
    salt="$6$"+"".join(random.sample('1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',16))
    print(crypt.crypt(str(passwd),salt))

    将输出的字符串写入root所在行的前两个冒号之间(替换掉原来的*)并保存。

  3. sudo docker container cp ./shadow [名称]:/etc/shadow将修改后的shadow文件写入。

  4. 再次用sudo docker exec -ti [名称] /bin/bash连接,su输入你刚才设的密码,就拿到了root权限了。

  5. ls /root可以看到有一个名为default_secret的文件,退出docker的bash,用sudo docker container cp [名称]:/root/default_secret ./将其拷贝出来。

  6. 在按照题目里的要求,输入echo "U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=" | openssl enc -aes-256-cbc -d -a -kfile default_secret,就解密成功了。

  7. 最后答案为Leaving passwords in docker images is not so securedefault_secret。本题就完成了。

最后别忘了关掉docker:sudo docker kill [名称],顺便删掉镜像,节约空间,sudo docker image rm webgoat/assignments:findthesecret --force

这道题就开始有点感觉了,总结一下,就像最终答案所说,不用在docker里面留下密码,外部的用户可以用docker的命令操作容器,相当于有了root权限,里面存储的东西也不一定安全。

Writing new lesson

这一节告诉你怎样写一个自己的课程。

Stage 6

通过阅读给出的代码可得,parameter 1为secr37Value即可。

总结

前面的题目都非常容易,但Crypto Basics的最后两题对我来说还是有一定难度,也花了不少时间。关于密码学的知识以后还有抽空多学学。