Pupy – Cross-platform RAT and Post-exploitation Tool
Introduction
Pupy is an opensource, cross-platform, multi function Remote Administration and post-exploitation tool written in Python. It’s very modular and supports a wide range of operating systems, payload formats and network transports.
Pupy: Opensource, Cross-platform Remote Administration & Post-exploitation Tool
Pupy has an embedded Python interpreter, which allows its modules to load remote python code, python packages and python C-extensions from memory. It can communicate using different transports and has a lot of awesome modules and features. Pupy can generate payloads in multiple formats such as:
- PE executables, reflective DLLs, pure python files, powershell, apk, etc.
With Pupy Scriptlets, embedded python scripts which can perform various tasks offline, you can for e.g. start a background script, add persistence, start a keylogger, detect a sandbox, etc.
Supported OS:
- Windows, Linux, OSX, Android.
Features:
- Cross-platform: tested on Windows XP, 7, 8, 10, Kali Linux, Ubuntu, OSX, Android).
- On Windows: you can compile Pupy payload as a reflective DLL and the whole python interpreter will load from memory.
- It can also be packed into a single
.py
file and run without any dependencies (except standard python libraries). - Pupy can reflectively migrate into other processes.
- Pupy can remotely import pure python packages (
.py
,.pyc
) and compiled python C extensions (.pyd
,.so
) from memory, without touching the disk. - It’s easily extensible, modules are quite simple to write, sorted by OS and category.
- A lot of awesome modules are already there.
- Pupy uses rpyc and a module can directly access python objects on the remote client. We can also access remote objects interactively from the pupy shell with remote attributes auto-completion.
- Modular, stackable and cool communication transports. You could exfiltrate data using HTTP over HTTP over AES over XOR, or with any other combination of the available transports.
- Pupy can communicate using obfsproxy pluggable transports.
- You can dispatch all non interactive modules to multiple hosts in one command.
- Scripts and commands during running on remote hosts are interruptible.
- Commands and arguments auto-completion.
- You can define custom config : command aliases, modules automatically run at connection, etc.
- You’re able to open interactive python shells with auto-completion on the all in memory remote python interpreter.
- Interactive shells (
cmd.exe
,/bin/bash
, etc.) can be opened remotely. Remote shells on Unix & Windows clients have a realtty
with all keyboard signals working fine just like assh
shell. - Pupy can execute PE exe remotely and from memory.
- Pupy can generate payloads in various formats :
apk
,lin_x86
,lin_x64
, so_x86,so_x64
,exe_x86
,exe_x64
,dll_x86
,dll_x64
,py
,pyinst,py_oneliner
,ps1
,ps1_oneliner
,rubber_ducky.
- It can be deployed in memory, from a single command line using
pupygen.py
‘s python or powershell one-liners. - “Scriptlets” can be embeded in generated payloads to perform some offline tasks without needing network connectivity (ex: start keylogger, add persistence, execute custom python script,
check_vm
, etc.).
Transports
rsa
: A layer with authentication & encryption using RSA and AES256, often stacked with other layersaes
: layer using a static AES256 keyssl
(the default one): TCP transport wrapped with SSLssl_rsa
: same as ssl but stacked with a rsa layerhttp
: layer making the traffic look like HTTP traffic. HTTP is stacked with a rsa layerobfs3
- A protocol to keep a third party from telling what protocol is in use based on message contents
- obfs3 is stacked with a rsa layer for a better security
scramblesuit
- A Polymorphic Network Protocol to Circumvent Censorship
- scramblesuit is stacked with a rsa layer for a better security
udp
: rsa layer but over UDP (could be buggy, it doesn’t handle packet loss yet)other
: other layers doesn’t really have any interest and are given for code examples :dummy
,base64
,XOR
, etc.
Launchers
- connect: just connect back.
- bind: bind payload instead of reverse.
- auto_proxy: retrieve a list of possible SOCKS/HTTP proxies and try each one of them. Proxy retrieval methods are: registry, WPAD requests, gnome settings, HTTP_PROXY env variable.
Modules
- migrate (windows only): inter process architecture injection also works
(x86->x64
andx64->x86
) - keylogger (windows only)
- persistence (windows only)
- screenshot (windows only)
- webcam snapshot (windows only)
- command execution
- download
- upload
- socks5 proxy
- local port forwarding
- interactive shell (
cmd.exe
,/bin/sh
, …) - interactive python shell
- shellcode exec
Requirements:
- Management software (server side):
pupysh
- Agent software (client side):
pupy/payload_templates/*pupy*.*
- Python libraries for various OS/CPU combinations:
pupy/payload_templates/*OS*-*CPU*.zip
Pupy Install
Debian 9:
If you want simple installation in a virtualenv with pre-built binaries, run the following:
$ apt-get install git libssl1.0-dev libffi-dev python-dev python-pip tcpdump python-virtualenv
Clone the Pupy from git repo. The script pupy/create-workspace.py
will create a Python virutalenv in the selected folder and symlinks to pupysh at ~/.local/bin
also:
$ git clone --recursive https://github.com/n1nj4sec/pupy $cd pupy && ./create-workspace.py pupyws
Now you can use pupy, as follows:
$ export PATH=$PATH:~/.local/bin
Install via Docker Compose:
You can install pupy via Docker Compose. Docker-supported platform:
- Windows 10, Mac, CentOS, Debian, Fedora, Ubuntu.
Clone the repository, then install all dependencies and configure:
$ ./install.sh
To start Pupy, run:
$ ./pupy_start_compose.sh
Pupy Shell Usage
To see available commands, just type your command followed by -h
or --help
:
sessions -h
jobs -h
run -h
It’s the same for modules, for example pyexec
:
>> run pyexec -h
usage: pyexec [-h] [--file <path>] [-c <code string>]
execute python code on a remote system
optional arguments:
-h, --help show this help message and exit
--file <path> execute code from .py file
-c <code string>, --code <code string>
execute python oneliner code. ex : 'import
platform;print platform.uname()'