mirror of https://github.com/n1nj4sec/pupy.git
semi working rust payload with rsa transport
This commit is contained in:
parent
d2605677d8
commit
9ee2022792
|
@ -5,7 +5,7 @@ PUPY=`dirname "$SELF"`/../
|
|||
PUPY=`readlink -f "$PUPY"`
|
||||
|
||||
DOCKER_COMMAND=${DOCKER_COMMAND:-docker}
|
||||
DOCKER_REPO=${DOCKER_REPO:-"alxchk"}
|
||||
DOCKER_REPO=${DOCKER_REPO:-"n1nj4sec"}
|
||||
CLEAN=${CLEAN:-"no"}
|
||||
|
||||
if [ ! -z "$REPO" ]; then
|
||||
|
|
|
@ -183,13 +183,17 @@ zf.writestr(
|
|||
)
|
||||
)
|
||||
|
||||
import platform
|
||||
#TODO: update if needed
|
||||
if 'win' in sys.platform:
|
||||
for root, _, files in os.walk('C:\\Python27\\Lib\\site-packages'):
|
||||
bits='64' if '64' in platform.architecture()[0] else '32'
|
||||
for root, _, files in os.walk('C:\\Python3-'+bits+'\\Lib\\site-packages'):
|
||||
for file in files:
|
||||
if file.lower().endswith((".dll",".pyd")):
|
||||
print("interesting file :", file)
|
||||
if file.lower() in ('pywintypes27.dll', '_win32sysloader.pyd'):
|
||||
if file.lower() in ('_win32sysloader.pyd'):
|
||||
zf.write(os.path.join(root, file), file)
|
||||
if file.lower().startswith("pywintypes") and file.lower().endswith(".dll"):
|
||||
zf.write(os.path.join(root, file), file)
|
||||
|
||||
try:
|
||||
|
|
|
@ -14,7 +14,8 @@ PACKAGES="$PACKAGES https://github.com/alxchk/pyuv/archive/v1.x.zip"
|
|||
PACKAGES="$PACKAGES idna http-parser pyodbc wmi"
|
||||
PACKAGES="$PACKAGES psutil==5.9.2"
|
||||
|
||||
SUFFIX="-310"
|
||||
SUFFIX="-`$PYTHON64 -c 'import sys;sys.stdout.write((chr.__call__(0)[0:0]).join([str(x) for x in sys.version_info[0:2]]));sys.stdout.flush()'`"
|
||||
echo "Building with python version suffix: $SUFFIX"
|
||||
SELF=$(readlink -f "$0")
|
||||
SELFPWD=$(dirname "$SELF")
|
||||
SRC=${SELFPWD:-$(pwd)}
|
||||
|
@ -32,7 +33,7 @@ $PYTHON32 -m pip install -q --upgrade pylzma
|
|||
$PYTHON64 -m pip install -q --upgrade pylzma
|
||||
|
||||
|
||||
SKIP_TO_BUILD=1
|
||||
SKIP_TO_BUILD=0
|
||||
if [ ! "$SKIP_TO_BUILD" -eq "1" ]; then
|
||||
|
||||
echo "[+] Install python packages"
|
||||
|
|
|
@ -566,6 +566,7 @@ class PupyClient(object):
|
|||
pass
|
||||
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
agent.remote_error('Iterate launcher: {}', e)
|
||||
|
||||
finally:
|
||||
|
|
|
@ -81,7 +81,10 @@ def get_pyver(pyver, config):
|
|||
if pyver is not None:
|
||||
if pyver == 2:
|
||||
return '27'
|
||||
elif pyver == 3:
|
||||
elif pyver == 38:
|
||||
# Here will be some default supported Py3 version
|
||||
return '38'
|
||||
elif pyver == 310:
|
||||
# Here will be some default supported Py3 version
|
||||
return '310'
|
||||
elif default:
|
||||
|
@ -557,7 +560,7 @@ def generate_binary_from_template(
|
|||
|
||||
if not os.path.isfile(template):
|
||||
raise ValueError('Template not found ({})'.format(template))
|
||||
|
||||
display(Info("Using template: {}".format(template)))
|
||||
if target.debug:
|
||||
conf['debug'] = True
|
||||
|
||||
|
@ -662,13 +665,8 @@ def get_parser(base_parser, config):
|
|||
pyver = parser.add_mutually_exclusive_group()
|
||||
|
||||
pyver.add_argument(
|
||||
'-2', '--python2', action='store_true',
|
||||
help='Use python2 target'
|
||||
)
|
||||
|
||||
pyver.add_argument(
|
||||
'-3', '--python3', action='store_true',
|
||||
help='Use python3 target'
|
||||
'--python38', action='store_true',
|
||||
help='Use python38 target (windows 7 supported)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
|
@ -973,7 +971,7 @@ def pupygen(args, config, pupsrv, display):
|
|||
os.makedirs(args.output_dir)
|
||||
|
||||
pyver = get_pyver(
|
||||
2 if args.python2 else 3,
|
||||
38 if args.python38 else 310,
|
||||
config
|
||||
)
|
||||
|
||||
|
|
|
@ -43,31 +43,29 @@ class Shares(PupyModule):
|
|||
remote.add_argument("-H", metavar="HASH", dest='hash', default='', help='NTLM hash')
|
||||
remote.add_argument("-d", metavar="DOMAIN", dest='domain', default="WORKGROUP", help="Domain name (default WORKGROUP)")
|
||||
remote.add_argument("-P", dest='port', type=int, choices={139, 445}, default=445, help="SMB port (default 445)")
|
||||
remote.add_argument("-t", dest='target', type=str, help="The target range or CIDR identifier")
|
||||
remote.add_argument("-t", dest='target', type=str, default=None, help="The target range or CIDR identifier")
|
||||
|
||||
|
||||
def run(self, args):
|
||||
|
||||
# Retrieve local shared folders
|
||||
try:
|
||||
if args.local:
|
||||
if self.client.is_windows():
|
||||
shared_folders = self.client.remote('pupwinutils.drives', 'shared_folders')
|
||||
if args.local:
|
||||
if self.client.is_windows():
|
||||
shared_folders = self.client.remote('pupwinutils.drives', 'shared_folders')
|
||||
|
||||
folders = shared_folders()
|
||||
if not folders:
|
||||
return
|
||||
folders = shared_folders()
|
||||
if not folders:
|
||||
return
|
||||
|
||||
self.log(Table([{
|
||||
'Name': share_name,
|
||||
'Path': share_path
|
||||
} for share_name, share_path in folders], ['Name', 'Path']))
|
||||
self.log(Table([{
|
||||
'Name': share_name,
|
||||
'Path': share_path
|
||||
} for share_name, share_path in folders], ['Name', 'Path']))
|
||||
|
||||
else:
|
||||
self.warning('this module works only for windows. Try using: run shares remote -t 127.0.0.1')
|
||||
return
|
||||
|
||||
else:
|
||||
self.warning('this module works only for windows. Try using: run shares remote -t 127.0.0.1')
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
# Retrieve remote shared folders
|
||||
if not args.target:
|
||||
|
|
|
@ -73,10 +73,10 @@ REGISTERED_NAMED_TUPLES_UNPACK = {}
|
|||
MAX_REGISTERED_VERSION = 1
|
||||
|
||||
|
||||
I1 = Struct("!B")
|
||||
I4 = Struct("!L")
|
||||
F8 = Struct("!d")
|
||||
C16 = Struct("!dd")
|
||||
I1 = Struct(">B")
|
||||
I4 = Struct(">L")
|
||||
F8 = Struct(">d")
|
||||
C16 = Struct(">dd")
|
||||
|
||||
_dump_registry = tuple(
|
||||
dict() for _ in xrange(MAX_REGISTERED_VERSION + 1)
|
||||
|
|
|
@ -79,7 +79,7 @@ class Channel(object):
|
|||
"""
|
||||
if self.compress and len(data) > self.COMPRESSION_THRESHOLD:
|
||||
compressed = 1
|
||||
data = zlib.compress(data, self.COMPRESSION_LEVEL)
|
||||
data = zlib.compress(data)
|
||||
else:
|
||||
compressed = 0
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ from pupy.network.lib.rpc.core import SocketStream, Channel
|
|||
|
||||
import threading
|
||||
|
||||
COMPRESSION_ENABLED = False
|
||||
|
||||
class addGetPeer(object):
|
||||
""" add some functions needed by some obfsproxy transports """
|
||||
|
||||
|
@ -56,9 +54,10 @@ class addGetPeer(object):
|
|||
class PupyChannel(Channel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PupyChannel, self).__init__(*args, **kwargs)
|
||||
self.compress = COMPRESSION_ENABLED
|
||||
self.COMPRESSION_LEVEL = 5 if COMPRESSION_ENABLED else 0
|
||||
self.compress = True
|
||||
self.COMPRESSION_LEVEL = 5
|
||||
self.COMPRESSION_THRESHOLD = self.stream.MAX_IO_CHUNK
|
||||
|
||||
self._send_channel_lock = threading.Lock()
|
||||
self._recv_channel_lock = threading.Lock()
|
||||
|
||||
|
@ -71,7 +70,7 @@ class PupyChannel(Channel):
|
|||
return self.stream.wake()
|
||||
|
||||
def recv(self):
|
||||
# print "RECV", threading.currentThread()
|
||||
#print( "RECV", threading.currentThread())
|
||||
with self._recv_channel_lock:
|
||||
data = self._recv()
|
||||
|
||||
|
@ -90,7 +89,7 @@ class PupyChannel(Channel):
|
|||
def _recv(self):
|
||||
""" Recv logic with interruptions """
|
||||
|
||||
# print "RECV! WAIT FOR LENGTH!"
|
||||
#print( "RECV! WAIT FOR LENGTH!")
|
||||
|
||||
packet = self.stream.read(self.FRAME_HEADER.size)
|
||||
# If no packet - then just return
|
||||
|
@ -106,10 +105,10 @@ class PupyChannel(Channel):
|
|||
del packet
|
||||
|
||||
length, compressed = self.FRAME_HEADER.unpack(header)
|
||||
# print "RECV! WAIT FOR LENGTH COMPLETE!"
|
||||
#print( "RECV! WAIT FOR LENGTH COMPLETE!")
|
||||
|
||||
required_length = length + len(self.FLUSHER)
|
||||
# print "WAIT FOR", required_length
|
||||
#print( "WAIT FOR", required_length)
|
||||
|
||||
decompressor = None
|
||||
|
||||
|
@ -122,10 +121,10 @@ class PupyChannel(Channel):
|
|||
packet = self.stream.read(min(required_length, self.COMPRESSION_THRESHOLD))
|
||||
if packet:
|
||||
required_length -= len(packet)
|
||||
# print "GET", len(packet)
|
||||
#print( "GET", len(packet))
|
||||
if not required_length:
|
||||
packet = packet[:-len(self.FLUSHER)]
|
||||
|
||||
#print( "PACKET IS FINALLY ", len(packet))
|
||||
if compressed:
|
||||
packet = decompressor.decompress(packet)
|
||||
if not packet:
|
||||
|
@ -139,7 +138,7 @@ class PupyChannel(Channel):
|
|||
if packet:
|
||||
buf.write(packet)
|
||||
|
||||
# print "COMPLETE!"
|
||||
#print( "COMPLETE!")
|
||||
return buf
|
||||
|
||||
def _send(self, data):
|
||||
|
@ -150,7 +149,7 @@ class PupyChannel(Channel):
|
|||
portion = None
|
||||
lportion = 0
|
||||
|
||||
# print "SEND .. ", ldata
|
||||
#print( "SEND .. ", ldata)
|
||||
|
||||
if self.compress and ldata > self.COMPRESSION_THRESHOLD:
|
||||
portion = data.peek(self.COMPRESSION_THRESHOLD)
|
||||
|
@ -164,11 +163,10 @@ class PupyChannel(Channel):
|
|||
self.stream.write(self.FRAME_HEADER.pack(ldata, compressed), notify=False)
|
||||
self.stream.write(data, notify=False)
|
||||
self.stream.write(self.FLUSHER)
|
||||
# print "SEND .. ", ldata, "DONE"
|
||||
#print( "SEND .. ", ldata, "DONE")
|
||||
return
|
||||
|
||||
del portion
|
||||
|
||||
compressor = zlib.compressobj(self.COMPRESSION_LEVEL)
|
||||
|
||||
total_length = 0
|
||||
|
@ -187,18 +185,22 @@ class PupyChannel(Channel):
|
|||
|
||||
if lportion > 0:
|
||||
total_length += lportion
|
||||
|
||||
#print( "SEND .. ", lportion, "DONE")
|
||||
self.stream.write(portion, notify=False)
|
||||
|
||||
portion = compressor.flush()
|
||||
lportion = len(portion)
|
||||
if lportion:
|
||||
total_length += lportion
|
||||
#print( "SEND .. ", lportion, "DONE")
|
||||
self.stream.write(portion, notify=False)
|
||||
|
||||
del portion, data, cdata
|
||||
|
||||
self.stream.insert(self.FRAME_HEADER.pack(total_length, compressed))
|
||||
# print "SEND WITH TOTAL LENGTH", total_length
|
||||
#print( "SEND WITH TOTAL LENGTH", total_length)
|
||||
#print( "SEND FLUSHER ", len(self.FLUSHER), "DONE")
|
||||
self.stream.write(self.FLUSHER)
|
||||
|
||||
|
||||
|
@ -208,7 +210,7 @@ class PupySocketStream(SocketStream):
|
|||
|
||||
self.MAX_IO_CHUNK = 32000
|
||||
self.KEEP_ALIVE_REQUIRED = False
|
||||
self.compress = COMPRESSION_ENABLED
|
||||
self.compress = True
|
||||
|
||||
#buffers for transport
|
||||
self.upstream = Buffer(
|
||||
|
|
|
@ -73,7 +73,7 @@ class RSA_AESTransport(BasePupyTransport):
|
|||
if lremainder:
|
||||
ltotal += BLOCK_SIZE - lremainder
|
||||
|
||||
data.insert(struct.pack('<I', lctext))
|
||||
data.insert(struct.pack('>I', lctext))
|
||||
data.truncate(ltotal)
|
||||
|
||||
if __debug__:
|
||||
|
@ -112,7 +112,7 @@ class RSA_AESTransport(BasePupyTransport):
|
|||
break
|
||||
|
||||
self.first_block = self.dec_cipher.decrypt(data.read(BLOCK_SIZE))
|
||||
self.size_to_read = struct.unpack_from('<I', self.first_block)[0]
|
||||
self.size_to_read = struct.unpack_from('>I', self.first_block)[0]
|
||||
|
||||
if self.size_to_read == 0:
|
||||
raise ValueError('Zero sized chunk')
|
||||
|
|
|
@ -654,22 +654,36 @@ class PupyServer(object):
|
|||
|
||||
def add_client(self, conn):
|
||||
client = None
|
||||
is_rustc = True
|
||||
|
||||
conn.execute(
|
||||
'import marshal;exec(marshal.loads({}))'.format(
|
||||
reprb(
|
||||
pupycompile(
|
||||
path.join(
|
||||
ROOT,
|
||||
"pupylib",
|
||||
'PupyClientInitializer.py'
|
||||
),
|
||||
path=True, raw=True,
|
||||
target=conn.remote_version
|
||||
if is_rustc:
|
||||
conn.execute(
|
||||
'exec({})'.format(
|
||||
reprb(
|
||||
open(path.join(
|
||||
ROOT,
|
||||
"pupylib",
|
||||
'PupyClientInitializer.py'
|
||||
), 'r').read()
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
conn.execute(
|
||||
'import marshal;exec(marshal.loads({}))'.format(
|
||||
reprb(
|
||||
pupycompile(
|
||||
path.join(
|
||||
ROOT,
|
||||
"pupylib",
|
||||
'PupyClientInitializer.py'
|
||||
),
|
||||
path=True, raw=True,
|
||||
target=conn.remote_version
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
uuid = obtain(conn.namespace['get_uuid']())
|
||||
|
||||
|
|
Loading…
Reference in New Issue