Yoga7xm's Blog

reGeorg原理分析

字数统计: 671阅读时长: 2 min
2020/01/03 Share

Abstract

之前内网渗透的时候说过一些通过建立隧道的方式来做穿透,其中http是最为常见的一种。我们通常使用reGeorg+Proxifier组合来将流量传入内网,所以来探究下这个开源工具的实现原理

项目地址:传送门

目录结构

代码分析

tunnel

我们先来看tunnel.php这个文件

dl() 运行时会载入一个PHP扩展,但是在PHP5.3之后默认就被禁用了。如果启用,需配置php.ini

1
enable_dl = On

1. CONNECT

创建一个与内网进行通信的socket。如果建立成功,返回X-STATUS为OK,然后初始化Session,进入下一逻辑

建立一个while循环,将session中要写入的内容取出,不为空的话就将其写入socket缓存中;然后开一个读数据的循环,一直到读不到数据为止,结束循环。

2. READ

客户端发起read操作时,将session中的内容进行输出

3. FORWARD

通过php://input来接收数据,并将其保存至session中,然后会通过之前while循环中的socket_write()写入socket缓存,最后开始socket_read()读取数据并打印出来

4. DISCONNECT

1
2
3
4
5
6
7
8
9
case "DISCONNECT":
{
error_log("DISCONNECT recieved");
@session_start();
$_SESSION["run"] = false;
session_write_close();
return;
}
break;

关闭连接然后删除session

reGeorgSocksProxy

直接来看主函数

1
2
3
if not askGeorg(args.url):
log.info("Georg is not ready, please check url")
exit()

跟进这个askGeorg()

通过GET请求来验证,如果返回的结果包含Georg says, 'All seems fine'说明服务端运行成功

根据传入的地址和端口参数创建一个socket服务端,然后等待客户端连接。跟进这个session类

1
2
3
4
5
6
7
def handleSocks(self, sock):
# This is where we setup the socks connection
ver = sock.recv(1)
if ver == "\x05":
return self.parseSocks5(sock)
elif ver == "\x04":
return self.parseSocks4(sock)

根据socks服务端收到的第一个字节来协商版本。如果是socks4,第一个字节就是4;反之为5,然后解析socks协议

解析socks5协议,拿到目标地址和端口

与tunnel建立session连接,连接成功后取出sessionid存入self.cookie

后续的reader和write发包操作都会带着sessionid实现数据交互

我们来看看tunnel.nosocket.php

nosocket

其实与tunnel类似,不过这里使用了fsockopen()建立socks连接

后面也都是用fwrite替换socket_write()fget替换socket_read()

总结

抓包

流程图

Regeorg

其实tunnel文件就是一个用作中转数据的api,将流量带入目标服务,然后将返回的数据带出

Reference

https://xz.aliyun.com/t/228

https://www.k0rz3n.com/2019/07/27/reGeorg%20%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%E5%88%86%E6%9E%90(%E4%BB%A5%20php%20%E4%B8%BA%E4%BE%8B)/

CATALOG
  1. 1. Abstract
  2. 2. 代码分析
    1. 2.1. tunnel
    2. 2.2. reGeorgSocksProxy
    3. 2.3. nosocket
  3. 3. 总结
  4. 4. Reference