WebGoat Injection 解题思路 (下)

WebGoat 版本信息

  • WebGoat v8.1.0

SQL Injection (mitigation)

1~4. Immutable Queries

介绍了可以防御SQL注入的三种方法:

  • Static Queries 静态查询语句
  • Parameterized Queries 参数化查询语句
  • Stored Procedures 储存过程

5. Try it! Writing safe code

填空题!!完成一段可以抵御SQL注入攻击的安全代码。

基本按照第四节中的JAVA代码样例即可:

6. Try it! Writing safe code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tring data;
String accountID = "1";
String query = "SELECT first_name, last_name, acct_id, balance FROM user_data WHERE acct_id = ?";
try (Connection connection = DriverManager.getConnection(DBURL, DBUSER, DBPW)){
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, accountID);
ResultSet results = statement.executeQuery();
if (results != null && results.first()) {
results.last(); // Only one record should be returned for this query
} else {
// Handle the error - no records found }
}
} catch (SQLException sqle) {
// Log and handle the SQL Exception }
}

7. Parameterized Queries - .NET

这里又另外展示了一段.NET中的参数话查询代码

8. Input Validation Required?

简单解释了在使用了正确的方法进行SQL语句的查询之后,用户输入校验为什么依然是必要的。

9. Input validation alone is not enough!!

如同标题所说的: 单单使用输入校验是不够的。攻击者总能找到办法针对输入校验进行绕过。这里我们就需要尝试绕过,以此来实现注入。

先简单尝试最普通的注入语句:d' or 1=1 -- 。我们可以看到程序进行了输入校验,不接受输入中包含空格。

尝试用空注释符/**/来代替空格:d'/**/or/**/1=1/**/--

Emmm…答案还是不正确。但是,可以看到,输入的语句已经按照我们所设想的被成功执行了。回忆一下之前相同的一题,好像是要拉去另一张表的内容…

1
d';SELECT/**/*/**/from/**/user_system_data--

嘿嘿!果然,这下就对了!

10. Input validation alone is not enough!! (2)

继续上一题的内容。开发团队在仅使用输入校验这条路上…不撞破南墙不回头了…

先使用上一题的payload进行简单尝试:d';SELECT/**/*/**/from/**/user_system_data--。果然,得到了报错…

仔细看一下最终被执行的SQL命令,不难发现SELECTfrom都被系统删除了。那如果输入的时候将SELECT替换为SESELCETLECT会有什么结果呢?

将输入简单修改为:d';SELSELECTECT/**/*/**/frfromom/**/user_system_data--

Bingo!!系统删除了一个SELECT,然后又刚好剩下了一个SELECT来完成完整的SQL注入。

即使要使用这种方法来抵御SQL注入,也要使用递归删除的方法。直到用户输入完全匹配不到关键词列表中的任何一个为止。

11. Order by clause

Prepared Statement可以有效地阻止SQL注入的发生,但这也并不意味着只要使用了这种方式就可以防止所有的SQL注入。这里举例了一种基于Order语句的注入方式。

1
SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname)

将True改为任意判断语句即可通过返回值的排列顺序获取到数据库的信息。

12. SQL Injection Through Order By Field

目标是通过对ORDER BY进行注入,进而获取到webgoat-prd服务器的IP地址。

通过Burp截取排序相关的请求,可以通过服务器的报错信息得到相关的表明。

首先将payload修改为(CASE+WHEN+(SELECT+SUBSTRING(ip,1,1)+FROM+servers+where+hostname='webgoat-prd')=80+THEN+ip+ELSE+id+END),看看语法是否正确。由于IP地址的前几位都是数字,所以需要爆破的量并不算多。

首先对IP的第一位进行尝试,使用BurpSuite的Intruder功能。

将爆破的值设为数字类型,从0-9。并且简单设置Grep-Payload选项,以此方便我们在结果中进行比对。

好了,这样一眼就可以看出来,IP地址的第一位是1。再对第二第三位进行重复操作。这样子,就可以获得IP地址的前三位为104

提交答案!搞定!

13. Least Privilege

再次强调了最小化权限的重要性。

Path Traversal

路径(目录)遍历攻击

另一种非常常见的注入攻击类型。路径遍历攻击利用网站的漏洞,可以获取目标系统根目录之外的非授权访问。

Path traversal while uploading files

这个练习需要利用当前系统中的图片上传功能,将文件上传到不同于默认上传目录的另一个目录中。

由于目标系统是构建在Linux系统上的,所以往往使用的方法都是利用burp,在上传的文件名之前加上../达到跨路径的目的。

首先随意选择一个文件作为头像进行上传,并使用BurpSuite拦截请求。

将文件名修改为:../../../../../../../home/richard/.webgoat-8.1.0/PathTraversal/test2.php.jpg。即先确保返回到文件系统的根目录,再连接上页面上显示的目标路径,确保路径是正确的。

submit!咿呀??好像不大对头…系统返回的错误信息是:

看来文件并没有传到我们相传的地方。再仔细一想,这个路径应该是根据表格中的Full Name项构建的,所以我应该是找错了注入点。这样的话,那就尝试将用户名修改为../test试试看吧~

Bingo!这下对了!

Path traversal while uploading files (2)

这下进行了一些修改,系统会将输入中的../删除,所以我们要想办法进行绕过。那么先测试一下系统是否递归的删除../了呢?还是只进行了一次匹配?

将Full Name修改为..././test进行尝试。直接成功了…

Path traversal while uploading files (3)

这次系统对于Full Name进行了完整的校验,所以终于轮到对于文件名进行注入了…

再次尝试类似于在第一步尝试中所做的那样,但是现在我们了解了路径情况,所以只要把文件名前加上../就可以了。

顺利通过!!

Retrieving other files with a path traversal

这次更换了一个场景。需要通过利用路径遍历漏洞来读取一个名为path-traversal-secret.jpg的图片。

先来看一下这个系统的功能。点击Show random cat picture系统会随机返回一张喵喵的图片。(啊,好可爱…)

先用BurpSuite来截取一下请求,看看有没有什么发现呗。

Hmm…没有任何参数,仅仅是调用了random-picture这个页面而已。那就只能再进一步看看Response吧!

哦?!在系统响应回来的页面里,我看到了这么一行:Location: /PathTraversal/random-picture?id=2.jpg。好家伙!这个页面同样接受id参数,并且这个参数的值直接是文件名的…

那就不客气了呗,直接请求 http://localhost:9090/WebGoat/PathTraversal/random-picture?id=path-traversal-secret.jpg 这个页面去咯!

嗷呜!失败了!直接是一个400。那就改一下参数:id=2.jpg试试看。

原来.jpg系统是自动添加的。不过同时还有额外收获,我们看到了当路径不存在时,系统会列出当前路径中的文件,而且当前路径中并没有我们想要找的path-traversal-secret.jpg

那么尝试id=../返回上级菜单试试?

提示参数中不接受非法字符,于是乎尝试将../进行URL编码:id=%2E%2E%2F。这下我们终于看到了列出的目录,但是并没有我们想找的图片。再试着多返回一级!终于有发现了!!

这下就离成功不远了!!id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret访问这个页面,终于看到提示:密钥就是用户名的SHA-512的值。

最后计算一下哈希值,提交一下就好了。

1
2
3
4
┌──(richard㉿richard-Kali)-[~/Tools/Forensics]
└─$ echo -ne 'pentester' | sha512sum
f167e76e501a479aa05b927d6dc9e05de8d66a8ebffd411e24dd30ef1e435deec8478a819cd26d1a1eda2fb3a1c18fafeff64b536bc351265b09cd99e967d787 -