What is it?
PacuProxy is a feature built into the Pacu framework that allows you as a user to interact with compromised remote hosts to run shell commands on them or route your AWS API traffic through them (AKA use their IP address as your own).
Why use it?
Often times during a penetration testing engagement (especially AWS post-exploitation style), I find that I am able to gain unauthorized access to at least one remote server. While trying to stay as under-the-radar as possible, it's not a great idea to start firing off command after command after gaining access on these servers, but there is almost always some sort of access that I want to abuse. Some examples of this would be:
- an EC2 instance with an instance profile attached
- an EC2 instance with access to other servers/databases within its own VPC
- an EC2 instance in a VPC that has access to an API Gateway rest API
With all these fruitful attack paths come protections as well, such as AWS services like GuardDuty or CloudTrail, or defenses like firewalls, intrusion detection systems (IDS), and other monitoring tools.
PacuProxy was built to simplify the process that an attacker needs to go through to bypass these kinds of protections. This list below shows some specific use cases that PacuProxy was built around, but they definitely are not the only possibilities.
- Bypassing GuardDuty rules such as:
GuardDuty alerts on all kind of suspicious IP activity based on the associated IP address. By proxying AWS traffic through a compromised EC2 instance, GuardDuty/CloudTrail/everything else will see the IP address of the EC2 instance rather than your attacker IP address, so it will not flag any activity.
- Bypassing IAM policies that use aws:SourceIp/aws:SourceVpc restrictions to whitelist access to certain IP addresses/ranges or VPCs.
By proxying all our AWS API traffic through the compromised host, we can use a target hosts IP address to bypass IAM policy IP/VPC whitelisting.
Accessing private API Gateway REST APIs
Bypassing IP based firewall restrictions (e.g. EC2 security group rules)
Bypassing IP/host based intrusion detection system alerts and rules
How do I use it?
- Listener: The PacuProxy feature that listens for new connections from compromised hosts.
- Agent: A compromised host that has established a connection with the PacuProxy listener.
Shell: A reference to
- Stager: A command that can be run on a compromised host to instruct them to make a connection back to the PacuProxy listener.
PacuProxy command info: proxy [help] Control PacuProxy/display help start <ip> [port] Start the PacuProxy listener - port 80 by default. The listener will attempt to start on the IP supplied, but some hosts don't allow this. In this case, PacuProxy will listen on 0.0.0.0 and use the supplied IP to stage agents and it should work the same stop Stop the PacuProxy listener kill <agent_id> Kill an agent (stop it from running on the host) list/ls List info on remote agent(s) use none|<agent_id> Use a remote agent, identified by unique integers (use "proxy list" to see them). Choose "none" to no longer use any proxy (route from the local host instead) shell <agent_id> <command> Run a shell command on the remote agent fetch_ec2_keys <agent_id> Try to read the meta-data of the target agent to request a set of temporary credentials for the attached instance profile (if there is one), then save them to the Pacu database and set them as the active key pair stager sh|ps Generate a PacuProxy stager. The "sh" format is for *sh shells in Unix (like bash), and the "ps" format is for PowerShell on Windows
proxy helpwill show the relevant PacuProxy help information (shown just above).
proxy start <ip> [port]will start the PacuProxy listener if one is not already running. The servers public IP address is required and the port will default to port 80.
- NOTE: The IP address cannot be 0.0.0.0, as a public IP address is required for agents to be able to find your PacuProxy listener. Some servers will fail to listen on their public IP addresses (even if it is correct) and so PacuProxy will fallback to listening on 0.0.0.0 if that is the case, but it will still be able to pass the correct public IP to target agents.
proxy stopwill stop the PacuProxy listener.
- NOTE: Agents will continue to try and connect to the server unless killed via another method. This can be both good or bad, such as if Pacu gets closed and it is no longer listening, you can start it up again and your compromised agents will reconnect to the listener.
proxy kill <agent_id>will kill the connection of the target proxy agent and close the relevant process on the agents machine.
proxy lswill list all active agents that are connected to the current listener. For each agent, it will print out their agent ID, their IP address, the process ID of the stager on the agent, and the operating system/hostname.
proxy use <agent_id>will tell the target agent to make a reverse SSH connection to the PacuProxy server to open a port on the PacuProxy server that can be used as a proxy to route traffic through. By default, the agent will connect to the server over SSH on port 22 and allow the server to use 127.0.0.1:8001 as a SOCKS5 proxy to route connections through. With a target agent set, all Pacu modules (except no_auth modules, like s3_enum) will route all AWS API calls through this proxy to cover up your attacker IP address with the agents.
- NOTE: This functionality is currently limited to PacuProxy servers running Unix (Linux/Mac) through agents that are also running Unix (Linux/Mac). Due to the way that the reverse proxy is created, Windows hosts are currently not able to use this functionality. The same goes for Windows agents, but this is in progress.
NOTE: PacuProxy can successfully run on a Windows host and accept connections agents, as well as run commands on agents with the
shellcommand described below. The same goes for Windows agents: they can be staged successfully and you can run commands on them with the
shellcommand, but you cannot proxy module traffic through them yet.
proxy use nonewill tell PacuProxy to no longer route AWS API traffic through any remote agent. The listener will stay online and all agents will stay connected, but traffic will be routed normally through the PacuProxy server.
proxy shell <agent_id> <command>will run a shell command on a remote agent. Unix agents most often run these commands through
bash(it can vary though) and Windows hosts will run these commands through
proxy shell 0 ls -awill run
ls -aon the agent with ID 0. Example2:
proxy shell 2 powershell lswill run PowerShell's command
lson the agent with ID 2.
proxy stager shwill generate a Unix/Linux-style (bash) PacuProxy Python one-liner to run on a compromised host. This command will run in the background of the agent and make a connection back to the PacuProxy listener, allowing you to run shell commands on it or proxy your traffic through it.
proxy stager pswill generate a Windows style (PowerShell) PacuProxy one-liner to run on a compromised host. This command will run in the background of the agent and make a connection back to the PacuProxy listener, allowing you to run shell commands on it.
proxy fetch_ec2_keys <agent_id>attempts to fetch temporary credentials via an EC2 instance's meta-data API, parse them, and set them as the active Pacu session key pair.
- An open port for PacuProxy to listen on (it defaults to port 80, but you need to ensure that the port specified is opened on your firewall and public facing).
- Pacu must be executed as root/with sudo privileges for PacuProxy to work correctly.
- Compromised hosts currently must have Python (version 2 or 3) installed to successfully stage them. This is something that needs to be expanded on to allow for different kinds of stagers (PowerShell-only/etc), but is not specifically planned yet.
- The rest is covered by the basic Pacu requirements (Python3 on the PacuProxy server/requirements.txt Python libraries/etc).
- PacuProxy is still in development and bugs are expected. If you encounter an error with any part of it, please open a GitHub Issue with the relevant debugging information so we can begin working on a fix.
- Windows hosts can run PacuProxy, but they are not able to proxy traffic through any agents (planned for the future).
- Windows agents cannot be used to proxy traffic through, but shell commands can be run on them (in-progress).
- There are many hardcoded defaults in the whole PacuProxy structure, such as the port used for proxy forwarding (8001), the location of the temporary key file on Unix agents for connecting back to the listener, and others. There are currently plans to allow easy customization of these values. One of these values includes the User-Agent making the request. Currently it will use the User-Agent of the PacuProxy server when making requests, but it needs to be changed to fetch the User-Agent of the target agent and use that (not a huge deal, the only thing to be aware of here is running PacuProxy on Kali Linux due to the GuardDuty rule PenTest:IAMUser/KaliLinux and potentially other custom rules.
- The Python3 library
botocoreuses an outdated version of the
requestslibrary, which does not yet support SOCKS proxies. Due to this fact, Pacu is now bundled with
botocorewhich has been patched to include the latest version of the
requestslibrary, allowing for SOCKS proxy usage in the boto3 client. This is the only change made to the library. What this does is allow you to use the
socks5://protocol when setting up
botocore.config.Configfor a boto3 client.
botocoreis still included in the
requirements.txtfile and installed via pip to assist with the
update_regionscommand. This way, we can update
botocoreto the latest version to retrieve the latest list of services and regions that AWS supports, while not interfering with the necessary patch for PacuProxy.
- PacuProxy's reverse SSH connection uses the
useraddcommand to create a temporary user on your PacuProxy host. This requires sudo privileges on Linux and currently does not work on OSX.