前言

近期对A Fresh Look On Reverse Proxy Related Attacks 一文进行了深入学习,根据自己的实践结果撰写笔记。

反向代理如何工作?

反向代理是从互联网接收请求并转发到内网服务器,对用户而言无感知存在。一个反向代理功能包含接收请求,处理,并转发到后端。

a) 处理请求

代理机请求处理包含以下几个主要步骤:

  1. 语法
  2. URL 解码
  3. 路径标准化

许多服务器支持常规的路径标准,如:

/long/../path/here -> /path/here
/long/./path/here -> /long/path/here

但是如何处理/..?,在Apache中它相当于/../,但是在Nginx中无任何作用。

/long/path/here/.. -> /long/path/ - Apache
/long/path/here/.. -> /long/path/here/ - Nginx

在Apache Tomcat上同Apache

//空路径,Nginx将其转换成/,但是如果不在首位Apache将其作为一个真实目录对待。

//long//path//here -> /long/path/here - Nginx
//long/path/here -> /long/path/here - Apache
/long//path/here -> /long//path/here - Apache

但是有些web servers支持一些奇怪的特性,比如Tomcat和Jetty支持/..;/特殊路径,或者使用\..\进行遍历。

/long/path/here/..;/ -> /long/path/ - Tomcat

b) 应用规则

基于路径的规则转发

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

c) 转发到后端

取决于代理服务器是否修改请求。

案例

Nginx

是否斜杠结尾

1
2
3
4
location /api/ {
proxy_pass http://backend_server/;
#proxy_pass http://backend_server;
}

带斜杠
http://domain/api/long/ -> http://backend_server/long/

不带斜杠
http://domain/api/long/ -> http://backend_server/api/long/

参考:
https://www.leavesongs.com/PENETRATION/nginx-insecure-configuration.html
https://www.jianshu.com/p/c751250a5112

Haproxy

Haproxy通常用作负载均衡,它极少的处理请求,即不支持URL解码,协议标准化,更不支持绝对URL。

服务端攻击

绕过限制

当攻击者想要访问某些受限功能时。

例1.

当Nginx作为反向代理,Weblogic作为后端服务器时。Nginx通过拒绝访问以/console/开头的路径限制管理界面。

1
2
3
4
5
6
7
8
location /console/ {
deny all;
return 403;
}
location / {
proxy_pass http://weblogic;
}

这里proxy_pass之后没有斜杠,因此请求将不处理转发到后端。但是Nginx将丢弃#之后的所有内容,Weblogic将#作为常规符号。恶意攻击者便可通过发送以下请求访问管理接口。

GET /#/../console/ HTTP/1.1

实例:访问Weblogic控制台
GET /#/../console/login/LoginForm.jsp HTTP/1.1

请求路由错误

例1
1
2
3
location /to_app {
proxy_pass http://weblogic;
}

以上配置,代理请求仅转发到Weblogic唯一后端(http://weblogic/to_app),所以只有当Nginx请求来自于/to_app时才转发到Weblogic上的相同路径。

为了访问其他目录,我们需要知道一下两点:

  1. proxy_pass配置后端没有斜杠
  2. Weblogic支持路径参数(https://tools.ietf.org/html/rfc3986#section-3.3)

区别于Tomcat的/..;/..;/路径遍历,Weblogic则将第一个;之后的所有内容作为路劲参数。

恶意攻击者可以通过以下请求访问任意目录。

1
GET /any_path_on_weblogic;/../to_app HTTP/1.1

Nginx接收到此请求,匹配到/to_app规则,再将/any_path_on_weblogic;/../to_app转发至后端。由于特性,Weblogic认为只是在访问/any_path_on_weblogic路径,当然还可以在;之后增加/../进行深层次遍历。

实例:访问/wls-wsat/CoordinatorPortType
GET /wls-wsat/CoordinatorPortType;/../../to_app HTTP/1.1

实例:在Nginx只转发.do结尾的请求规则到后端时如何访问后端.jsp文件

GET /bea_wls_internal/.shell.jsp;/../../xx.do HTTP/1.1

例2

听说这是一个不会被修复的bug,翻译表示太难了。

当代理服务器规则为location /to_app时,路径/to_app,/to_app/,/to_app_anything(包括特殊符号)都可以匹配该规则。并且/to_app前缀后的字符将与proxy_pass值拼接。

1
2
3
location /to_app {
proxy_pass http://server/any_path/;
}

在以上配置中,如果我们发起/to_app_anything访问请求,代理服务器将转发http://server/any_path/_anything到后端。
结合这些特性,恶意攻击者几乎可以通过以下方式遍历后端任意路径。

1
GET /to_app../other_path HTTP/1.1 -> http://server/any_path/../other_path

实例:访问Weblogic后端console
GET /to_app1../console/login/LoginForm.jsp HTTP/1.1

例3

在某些情况,反向代理服务器根据主机头将请求路由到不同的后端。以Haproxy为例,因为其不能处理绝对URI,便可以通过以下方式访问后端任意主机。

1
2
GET http://unsafe-value/path/ HTTP/1.1
Host: example1.com

不过在大部分情况下(Nginx, Haproxy, Varnish)这是不能做到的,但是Apache在某些配置版本下则可以。由于此漏洞(CVE-2011-3368)太老,我们不再深入研究,这里提供以下两个链接参考。

https://www.exploit-db.com/exploits/17969
https://www.contextis.com/de/blog/server-technologies-reverse-proxy-bypass
https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf

客户端攻击

Web缓存欺骗 Web Cache Deception

1
2
3
4
5
6
7
8
9
10
# Nginx缓存配置
proxy_cache_path /temp levels=1:2 keys_zone=my_cache:10m inactive=120s;
location ~ .*\.(gif|jpg|png|css|js)(.*) {
proxy_cache my_cache;
proxy_pass http://30.3.228.163:7041;
proxy_cache_valid 200 302 60m;
proxy_set_header X-Real-IP $remote_addr;
proxy_ignore_headers Cache-Control Expires Set-Cookie;
add_header Nginx-Cache "$upstream_cache_status";
}

以上配置使得Nginx将缓存指定扩展名文件内容,当我们访问诸如/home.php/nonexistent.css链接时响应内容与访问/home.php相同,Nginx将缓存当前页面信息,恶意攻击者通过访问/home.php/nonexistent.css获取用户敏感信息。

参考资料
https://www.blackhat.com/docs/us-17/wednesday/us-17-Gil-Web-Cache-Deception-Attack-wp.pdf
http://omergil.blogspot.ru/2017/02/web-cache-deception-attack.html

Web缓存中毒 Practical Web Cache Poisoning

通过添加X-Forwarded-Host (XFH)头观察是否在返回包中回显。

反向代理(如负载均衡服务器、CDN等)的域名或端口号可能与处理请求的源服务器有所不同,X-Forwarded-Host 用来确定哪一个域名是最初被用来访问的。

https://i.blackhat.com/us-18/Thu-August-9/us-18-Kettle-Practical-Web-Cache-Poisoning-Redefining-Unexploitable.pdf

HTTP响应拆分(CRLF注入)

-|-|-
CR|回车|\r|%0d
LF|换行|\n|%oa

客户端浏览器通过\r\n来区分http协议的header和body,一旦我们能够控制响应头中的字符,就能修改浏览器解析结果,从而实现恶意行为。

请求走私 HTTP Request Smuggler

https://paper.seebug.org/1048/?from=timeline&isappinstalled=0