nginx配置错误导致的漏洞
0x00 运行环境ubuntu进入/vulhub-master/nginx/insecure-configuration目录执行以下命令,运行环境。docker-compose up -d运行成功后,Nginx将会监听8080/8081/8082三个端口,分别对应三种漏洞。0x01 CRLF注入漏洞1.前提下面两种跳转情景十分常见:1. 用户访问http://example.co...
0x00 运行环境
ubuntu进入/vulhub-master/nginx/insecure-configuration目录
执行以下命令,运行环境。
docker-compose up -d
运行成功后,Nginx将会监听8080/8081/8082三个端口,分别对应三种漏洞。
0x01 CRLF注入漏洞
1.前提
下面两种跳转情景十分常见:
1. 用户访问http://example.com/aabbcc,自动跳转到https://example.com/aabbcc
2. 用户访问http://example.com/aabbcc,自动跳转到http://www.example.com/aabbcc
http状态码301和302详解及区别:https://blog.csdn.net/zhouchangshun_666/article/details/79354193。
第一种跳转随着现在https的普及,很多站点都强制使用https访问,这样的跳转非常常见。
第二种跳转主要是为了统一用户访问的域名,更加有益于SEO优化。
在跳转的过程中,我们需要保证用户访问的页面不变,所以需要从Nginx获取用户请求的文件路径。查看Nginx文档,可以发现有三个表示uri的变量:
1. $uri
2. $document_uri
3. $request_uri
其中,1和2表示的是解码以后的请求路径,不带参数;3表示的是完整的URI(没有解码)。那么,如果运维配置了下列的代码:
location / {
return 302 https://$host$uri;
}
因为$uri是解码以后的请求路径,所以可能就会包含换行符,也就造成了一个CRLF注入漏洞。(关于CRLF注入漏洞,可以参考文章 :https://www.leavesongs.com/PENETRATION/Sina-CRLF-Injection.html )
2.CRLF的介绍
CRLF是”回车 + 换行”(\r\n)的简称。在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来。所以,一旦我们能够控制HTTP 消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码,所以CRLF Injection又叫HTTP Response Splitting,简称HRS。
CRLF是比XSS危害更大的安全问题,对于CRLF最简单的利用方式是注入两个\r\n,之后在写入XSS代码,来构造一个xss。
举个例子,一般网站会在HTTP头中用Location: http://baidu.com这种方式来进行302跳转,所以我们能控制的内容就是Location:后面的XXX某个网址。
一个正常的302跳转包如下图:
http://192.168.189.139:8080/%0aSet-cookie:JSPSESSID%3Ddrops
repeater模式下修改包的内容(注入一个换行,在http头里注入了cookie,如下图)与url直接(上面)访问抓包,他们的返回包都是一样的。
此时的返回包如下图:
这个时候这样我们就给访问者设置了一个SESSION,造成一个“会话固定漏洞”。
当然,CRLF并不仅限于会话固定,通过注入两个CRLF就能造成一个无视浏览器Filter的反射型XSS。
比如一个网站接受url参数http://192.168.189.137:8080/?url=xxx
,xxx放在Location后面作为一个跳转。如果我们输入的是:
http://192.168.189.137:8080/?url=%0d%0a%0d%0a<img src=1 onerror=alert(/xss/)>
我们的返回包就会变成这样:
之前说了浏览器会根据第一个CRLF把HTTP包分成头和体,然后将体显示出来。于是我们这里这个标签就会显示出来,造成一个XSS。
为什么说是无视浏览器filter的,这里涉及到另一个问题。
浏览器的Filter是浏览器应对一些反射型XSS做的保护策略,当url中含有XSS相关特征的时候就会过滤掉不显示在页面中,所以不能触发XSS。
怎样才能关掉filter?一般来说用户这边是不行的,只有数据包中http头含有X-XSS-Protection并且值为0的时候,浏览器才不会开启filter。
方法一
说到这里应该就很清楚了,HRS不正是注入HTTP头的一个漏洞吗,我们可以将X-XSS-Protection:0注入到数据包中,再用两个CRLF来注入XSS代码,这样就成功地绕过了浏览器filter,并且执行我们的反射型XSS。
所以说HRS的危害大于XSS,因为它能绕过一般XSS所绕不过的filter,并能产生会话固定漏洞。
http://192.168.189.139:8080/url=%0aX-XSS-Protection:%200%0a%0d%0a%0d<img%20src=1%20onerror=alert(/xss/)>
输入上面的url访问,返回如下结果(其他浏览器也是这样),这种方法我没有成功。
方法二
利用字符编码来绕过XSS Filter的方法,当编码是is-2022-kr时浏览器会忽略%0f,这样我们在onerror后面加个%0f就能绕过filter,前提是注入一个<meta charset=ISO-2022-KR>
,输入下面的url后返回结果和上面的一样,也是没有成功。哭哭哭
http://192.168.189.139:8080/url=%0a%0d%0a%0d%0a<meta%20charset=ISO-2022-KR><img%20src=x%20onerror%0f=alert(1)>
修复HRS漏洞的方法是过滤\r 、\n之类的换行符,避免输入的数据污染到其他HTTP头。
回到本题
CRLF注入漏洞可以导致会话固定漏洞、设置Cookie引发的CSRF漏洞或者XSS漏洞。其中,我们通过注入两个\r\n即可控制HTTP体进行XSS,但因为浏览器认为这是一个300跳转,所以并不会显示我们注入的内容。
这个情况下,我们可以利用一些技巧:比如使用CSP头来iframe的地址,这样浏览器就不会跳转,进而执行我们插入的HTML:
这个方法看文章没看懂,太菜了,不会用啊,哭哭哭。
关于上述利用方法,可以参另一篇文章:https://www.leavesongs.com/PENETRATION/bottle-crlf-cve-2016-9964.html
如何修复这个CRLF漏洞?
正确的做法应该是如下:
location / {
return 302 https://$host$request_uri;
}
另外,由$uri导致的CRLF注入漏洞不仅可能出现在上述两个场景中,理论上,只要是可以设置HTTP头的场景都会出现这个问题。
目录遍历漏洞
这个漏洞常见于Nginx做反向代理的情况,动态的部分被proxy_pass传递给后端端口,而静态文件需要Nginx来处理。
假设静态文件存储在/home/目录下,而该目录在url中名字为files,那么就需要用alias设置目录的别名:
location /files {
alias /home/;
}
此时,访问http://example.com/files/readme.txt
,就可以获取/home/readme.txt
文件。
但我们注意到,url上/files
没有加后缀/
,而alias设置的/home/
是有后缀/
的,这个/
就导致我们可以从/home/
目录穿越到他的上层目录:
修改请求为http://example.com/files../
,可以成功跳转到上一层目录下。如下图所示
进而我们获得了一个任意文件下载漏洞。
如何解决这个漏洞?只需要保证location和alias的值都有后缀/
或都没有这个后缀。
add_header被覆盖
Nginx的配置文件分为Server、Location、If
等一些配置块,并且存在包含关系,和编程语言比较类似。如果在外层配置的一些选项,是可以被继承到内层的。
但这里的继承也有一些特性,比如add_header,子块中配置后将会覆盖父块中的add_header添加的所有HTTP头,造成一些安全隐患。
如下列代码,整站(父块中)添加了CSP头:
server {
...
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
location = /test1 {
rewrite ^(.*)$ /xss.html break;
}
location = /test2 {
add_header X-Content-Type-Options nosniff;
rewrite ^(.*)$ /xss.html break;
}
}
父块
test1
/test2的location中又添加了X-Content-Type-Options头,导致父块中的add_header全部失效:
此时,test2的csp就完全失效了,我们成功触发XSS:
http://192.168.189.139:8082/test2#<img src=1 onerror=alert(1)>
在IE浏览器中测试
测试中test1也能触发
在火狐和google结果都一样,没有成功。
更多推荐
所有评论(0)