首页
社区
课程
招聘
[翻译]蓝军测试中PROXY protocol的应用
2020-4-7 20:00 7729

[翻译]蓝军测试中PROXY protocol的应用

2020-4-7 20:00
7729

蓝军测试中PROXY protocol的应用

译者注1:攻防对抗中,关于红蓝军的概念国内外是相反的,故译者会以蓝军替代原文中的red team
译者注2:PROXY protocol(代理协议),是HAProxy的作者Willy Tarreau开发和设计的一个Internet协议,可用于方便且安全地在复杂网络环境下传输完整的客户端连接信息(源IP、目的IP、源端口、目的端口等)。

 

最近,我对学习如何在蓝军测试中使用PROXY protocol非常感兴趣。如果读者熟悉可扩展系统的开发或负载均衡的使用,那么可能已经很了解PROXY protocol了。PROXY protocol的基本概念就是负载均衡器会在原始请求前面加上一行PROXY信息,如下所示:

PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\n
GET / HTTP/1.1\r\n
Host: 192.168.0.11\r\n
\r\n

各字段详细解释如下:

  • PROXY表示PROXY protocol的版本是v1
  • TCP4表示TCP协议。TCP4指的是TCP over IPv4,TCP6指的是TCP over IPv6。
  • 192.168.0.1表示源IP地址,是原始客户端IP地址。
  • 192.168.0.11表示目的IP地址。
  • 56324表示源端口
  • 443表示目的端口
  • \r\n表示PROXY header的结尾
  • GET / HTTP/1.1\r\n表示HTTP请求的开始

在传统的HTTP代理应用场景下,负载均衡器会插入包含源IP地址的X-Forwarded-For header。 如果要在使用HTTPS的情况下保留源IP地址,负载均衡器则需要先解密TLS连接,以便插入header,然后再另启一个的TLS连接将其重新加密传输到后端。老实说,大多数情况下不会出问题。

 

但是在安全攻防场景中,我们会使用“重定向”来替代“负载均衡”的概念。重定向器旨在保护我们的基础设施,但需要注意的是,重定向器可能比其他设施更容易受到威胁。 如果想复现威胁攻击,需要在非主流云服务商的各种服务上使用重定向器。可以考虑我朋友Topher和Mike的sketchyasfuckistan匿名野鸡VPS。

 

如果你使用野鸡云服务商,你可能不想处理在重定向器失效后转移SSL证书的问题,此外,你可能也不会相信服务器上生成的密钥不会在别的地方有备份,或者你是服务器的唯一拥有者。一般来说,你不会太信任这种服务器,这种情况下可以使用dumb TCP重定向器,bluscreenofjeff在蓝军测试基础设施设计中提到了一些。但是,dump TCP重定向器可能会丢失源IP的信息,一旦流量返回到信任的基础设施后,会影响后续判断。

 

PROXY protocol会让TLS重定向器保持dumb,而不会丢失客户端连接的信息。只要重定向器和目标服务器支持PROXY,那么就可以保留原始客户端地址。重定向器接收客户端的TLS连接,将header信息添加到TCP数据包之前,然后将其传输到服务器。服务器(存放TLS密钥的服务器)也必须支持PROXY protocol,否则将会报错。

流程图

流程图

复现步骤

我应该已经做了充分的解释,对吧?你可能只想看配置的部分,那我们直接跳到那部分,我将根据上图做标记。最近一次测试完成于2020年2月15日,测试环境为nginx version: nginx/1.14.0 (Ubuntu),操作系统是Ubuntu 18.04.4 LTS

example.com

将DNS记录指向Untrusted Redirector 1的IP地址。在此例中,即192.168.0.4。

@ 300 IN A 192.168.0.4

Untrusted Redirector 1

这是的入口重定向器。恶意流量触达到该重定向器时会暴露IOC。我们不想它存放任何关键信息,并希望它在需要时尽可能容易地调整。它所做的只是监听443端口并指向Untrusted Redirector 2。

 

创建文件/etc/nginx/stream_redirect.conf

stream {
    server {
        listen 443;
        proxy_pass 192.168.0.3:443;
        proxy_protocol on;
    }
}

/etc/nginx/nginx.conf加入下面这一行,并确保它没有被包含在其他代码块中。

include /etc/nginx/stream_redirect.conf

重启nginx,到下一步的Untrusted Redirector 2。sudo systemctl restart nginx

Untrusted Redirector 2

这是我们的中点重定向器,中点重定向器不是必需的,也可将Untrusted Redirector 1直接指向Trusted Ingress。但是,如果你想将example.com与实际的基础设施分离,那最好还是保留中点重定向器。如果你的基础设施托管在目标环境中,也会非常有用,这对于内部蓝军来说并不罕见,“所有秘密都藏在屋子里”。

 

创建文件/etc/nginx/stream_redirect.conf

stream {
    server {
        listen 443;
        proxy_pass 192.168.0.2:443;
    }
}

然后像配置之前的重定向器一样,可以添加include /etc/nginx/stream_redirect.conf/etc/nginx/nginx.conf。或者,可以使用socat或simpleproxy之类的dumb重定向器来代替在此层使用的nginx。该层并不需要知道代理的存在,实际上,如果你尝试在任何中间点上使用proxy_protocol on,可能会导致其失效。

 

重启nginx,到下一步的Trusted Ingress。sudo systemctl restart nginx

Trusted Ingress

这是我们的入口系统,TLS终止于此,并且我们处于受信的环境中。example.com的关键信息位于该系统中,并且PROXY也将在此终止。

 

示例文件/etc/nginx/sites-enabled/example.com.conf

server {
    server_name example.com;

    location / {
        proxy_pass 192.168.0.1:8080;
        proxy_set_header X-Forwarded-For $proxy_protocol_addr;
    }

    listen [::]:443 ssl ipv6only=on proxy_protocol; # managed by Certbot
    listen 443 ssl proxy_protocol; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

注意在X-Forwarded-For中的$proxy_protocol_addr变量,这是PROXY protocol中的源IP地址,
也将其记录在Trusted Ingress nginx日志中。

 

/etc/nginx/nginx.conf中的示例代码片段:

[...]
http {
[...]
    ##
    # Logging Settings
    ##
    log_format proxy '$proxy_protocol_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';
    access_log /var/log/nginx/access.log proxy;
    error_log /var/log/nginx/error.log;
[...]
}

你可能想仅对Trusted Ingress上的特定站点配置使用代理,需要在/etc/nginx/nginx.conf中保留access_log,并添加access_log /var/log/nginx/example.com.access.log proxy;/etc/nginx/sites-enabled/example.com.conf

Downstream Application

如果完全按照此教程操作,则应用程序需要解析X-Forwarded-For header。你可以在nginx层进行客户端IP过滤,将不需要的IP重定向到其他位置,这样的话应用程序甚至不必处理IP。

 

还有一种方法可以解决此问题,以便应用程序不需要解析X-Forwarded-For header,但是需要另外安装一个nginx模块(ngx_http_realip_module),但它不能作为单独的可安装模块使用,我不想在此文章中涉及有关从源代码构建nginx的整个部分。也许这是另一个帖子的主题。

结论

我不知道蓝军成员是否可以通过其他方式解决此问题,但此文所述的方法是一个很好的解决办法,因为它不需要任何中间服务器保存关键信息或获得授权。从技术上讲,服务器之间不太可能会传输错误的客户端IP地址,但仅在中间使用dumb重定向器,不会引入任何其他问题,因为你只会获得重定向器的IP,并且无法基于此直接做决策。因此,无论如何,还是用PROXY protocol吧。

 

照例。。。

 

Hack the planet

 

原文链接:https://0xda.de/blog/2020/02/red-team-proxy-protocol-nginx/

 

翻译:看雪翻译小组 SpearMint


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2020-4-7 20:01 被SpearMint编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回