0x01 Background
Nginx上一些偏门的漏洞,大多数是因为运维大哥的“粗心”配置导致的,一起来看看自己,是不是曾当过这个“粗心”的运维大哥
0x02 CRLF
OWASP - CRLF 介绍 (https://www.owasp.org/index.php/CRLF_Injection)
The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They're used to note the termination of a line, however, dealt with differently in today’s popular Operating Systems. For example: in Windows both a CR and LF are required to note the end of a line, whereas in Linux/UNIX a LF is only required. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.
A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL.
HTTP Splitting
在Nginx配置中,CRLF常出现在HTTP头中不验证用户输入
的场合
- 敏感变量
- add_header
- proxy_set_header
如果在上述一些类似设置header头的变量中存在用户可控的数据,那就要注意是否过滤严谨,不然就会造成CRLF注入
每次调整正则配置,如果都要nginx -s reload
后进行测试的话,难免会比较浪费时间,由于nginx是基于PCRE
,所以可以用grep -P
来帮助我们验证自己的正则表达式。
方法如下:
[root@0akarma ~]# echo 'a.jpg' | grep -P '((?<jpg>[^.]*)\.jpg)?$'
a.jpg
然后我们接着来看下面这个vuln配置
location ~ /static/((?<jpg>[^.]*)\.jpg)?$ {
add_header X-Action $jpg;
return 200 "OK";
}
改成这样就可以解决这个问题了
location ~ /static/((?<action>[^.\s]*)\.json)?$ {
add_header X-Action $action;
return 200 "OK";
}
在讲另外的变量之前先讲讲下面三个比较容易搞错的变量
- $request_uri:包含请求参数的原始URI,并不进行URL解码,如
/admin/login.php?username=admin&password=admin
- $uri:不包含请求参数的当前URI,如
/static/style.css
- \$document_uri:跟上面的
$uri
一样
所以试想一下,下面这三个变量都用的是$uri
或者$document_uri
会发生什么~
- proxy_pass
- return
- rewrite
location /static {
return 302 http://$host$uri;
}
Oh ***
Header Redefinition
Nginx里面有许多地方可以设置header,如server
或location
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
但是如果,他又有一个子级可覆盖父级的特点,所以,如果存在下面这种配置
server {
listen 80;
add_header X-Frame-Options "DENY" always;
location / {
return 200 "index";
}
location /static {
add_header Pragma "no-cache" always;
return 200 "static dir";
}
}
响应头就会是这样
```nginx
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Wed, 24 Apr 2019 14:46:10 GMT
Content-Type: application/octet-stream
Content-Length: 5
Connection: close
X-Frame-Options: DENY
index