在某次威胁分析的过程中,看到攻击方在使用反序列化漏洞拿下资产组内一台暴露在外网的主机之后,就开始使用reGeorg工具进行连接,视图渗透到内网。之前由于我并没有接触过reGeorg工具,出于好奇,就研究了一下这个工具的用途以及原理,于是形成了本篇文章。

1. 是什么

在大多数的文章中,都把reGeorg称为内网代理。实际上,它也确实在渗透的过程中,起到了代理的作用。

考虑一种场景,资产组里有2台机器:主机A、主机B。其中主机A上运行了Web服务,且IP或者端口映射到公网,可以被外部人员访问,主机B是在外网访问不到的。攻击者通过漏洞在主机A上传了Webshell,但同时又出于某些限制并未能得到主机A的主机权限也无法反弹shell,那么他这个时候,也是无法通过常规方法反弹shell或者直接登录主机A从而访问到主机B的。

reGeorg就在这个时候起了作用,攻击者已经有了主机A的webshell权限(即可以在web服务器中上传文件),而主机A可以和主机B通信。那么在主机A上安装reGeorg工具,使得攻击者发出的请求以及目标机器的响应经过A的http转发,达到攻击者可以和主机B进行通信的效果。

2. 怎么用

2.1 搭建环境

为了模拟整个场景,我搭建了一个如下图所示的网络拓扑。attk是攻击主机,victim_a和victim_b是被攻击主机。s1和s2是两个交换机,r1是路由器。

 

初始化后的IP如下:

攻击者IP:192.168.218.227

victim_a IP:192.168.253.16

victim_b IP:192.168.253.42

路由器两个网卡的IP:192.168.218.1,192.168.253.1

掩码都是255.255.255.0。

attk配置路由器不为默认网关,这样attk无法与victim_a和victim_b直接通信。

在victim_a主机上部署java和tomcat。

然后再在路由器做一下端口映射。

这样,就将victim_a的8080端口映射到了路由器的9999端口。

attk直接访问http://192.168.218.1:9999即访问到了victim_a的web服务。

 

从截图可以看出,攻击者无法直接访问victim_a(192.168.253.16),不过可以通过访问192.168.218.1:9999间接访问到victim_a上的web服务。

2.2 安装工具

reGeorg工具的github目录为:https://github.com/sensepost/reGeorg

1.将tunnel.jsp上传victim_a的tomcat的ROOT目录。

2.将reGeorgSocksProxy.py上传到攻击机attk,并执行:

 

3.在攻击机安装sock5客户端privoxy,并连接本地的9999端口

 

Privoxy监听的端口是8118

令http_proxy=127.0.0.1:8118。此时,可以直接以victim_a的内网ip对于它的web服务进行访问:

 

同样,也可以访问与victim_a处于同一个网的victim_b的web服务。

 

3.实现原理

3.1 reGeorgSocksProxy.py

py脚本主要是位于攻击机上,接收socks请求,并通过http请求发送给被攻击主机。同时,当响应体有内容时,将响应回传给socks客户端。

具体步骤如下:

1.从参数中解析得到本地监听端口listen-port,以及连接的已失陷主机上的tunnel.jsp的url

2.判断url是否可以连接成功

3.建立socket,监听本地的listen-port端口

4.根据listen-port端口收到的一个字节是\x05还是\x04判断收到的请求是SOCKS5请求还是SOCKS4请求。(因为SOCKS请求的第一个字节是版本号)

5.当SOCKS请求发过来的是CONNECT命令时,将请求中带有的IP和端口,发送给setupRemoteSession方法。

6.setupRemoteSession方法,主要是在url后面拼接?cmd=connect&target=%s&port=%d参数,将需要连接的IP和端口发送到被攻击主机的tunnel.jsp。

7.当请求的响应码为200,且响应体头部有x-status字段且字段值为OK时,就判定为连接成功,记录cookie信息。

8.成功连接后,启动reader线程和writer线程。

9.reader线程,主要是发送http://victim_ip:port/tunnel.jsp?cmd=read请求。并将响应内容,回传给SOCKS客户端。

10.writer线程,主要是从SOCKS请求中取得数据data,

并发送http://victim_ip:port/tunnel.jsp?cmd=forward请求,将data作为POST请求体发送到被攻击主机。

3.2 tunnel.jsp

tunnel.jsp脚本位于被攻击机上,主要是接受命令,并与内网主机建立socket连接,将命令发送给内网主机并取得响应,响应内容以http响应体返回给攻击机。

1.解析四种命令,CONNECT/DISCONNECT/READ/FORWARD。

2.当收到CONNECT命令时,解析得到指定的内网IP和端口,并使用socket与之建立连接。并在响应中,增加头部X-STATUS:OK。并将socket放入session里,避免http结束后socket连接丢失。

3.当收到READ命令时,从session中取得socket,并尝试从socket读取内容。并将读取的内容,写入到http响应中。

4.当收到FORWARD命令时,从请求中读取命令,并使用socket发送给被连接的内网IP、端口。

5.DISCONNECT命令,只有当reGeorgSocksProxy.py捕获到异常时才会发送,主要就是断开与指定的内网主机的IP、端口的socket连接。

4.特征

1.在url:http://victim_ip:port/tunnel.jsp?cmd=connect&target=%s&port=%d请求发送后,响应内容的头部带有X-STATUS:OK。

2.CONNECT命令之后,有READ、FORWARD命令。且如果请求成功,它们的响应头部也带有X-STATUS:OK。

3.如果使用reGeorg工具,对于内网主机执行命令成功例如READ读取成功。那么除了头部会带上X-STATUS:OK,同时响应体内,也会有读取出来的内容,如截图所示:

本文作者:tammypi, 转自FreeBuf