import asyncio
import sys
import os
import subprocess
import ctypes
# ⚠️ CHANGE THIS PASSWORD! Anyone with this password can access your PC's terminal.
PASSWORD = "12345"
PORT = 8021
def elevate_privileges():
try:
if not ctypes.windll.shell32.IsUserAnAdmin():
print("[!] Administrator privileges required. Prompting for UAC...")
script = os.path.abspath(sys.argv[0])
ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, f'"{script}"', None, 1
)
sys.exit(0)
except Exception as e:
print(f"[-] Failed to elevate privileges: {e}")
sys.exit(1)
elevate_privileges()
def check_deps():
try:
import fastapi
import uvicorn
except ImportError:
print("[*] Installing required web dependencies...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "fastapi", "uvicorn", "websockets"])
check_deps()
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse, Response
import uvicorn
app = FastAPI()
def find_hackashell():
base = os.path.dirname(os.path.abspath(__file__))
candidates = [
os.path.join(base, "HackaShell.py"),
os.path.join(base, "HackaShell", "HackaShell.py"),
]
for path in candidates:
if os.path.exists(path):
return path
return None
HACKASHELL_PATH = find_hackashell()
html = """
<!DOCTYPE html>
<html>
<head>
<title>HackaShell Connect</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />
<style>
body { margin: 0; background: #1e1e1e; overflow: hidden; color: #d4d4d4; font-family: sans-serif; }
#terminal { width: 100vw; height: 100vh; display: none; }
#login { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; }
input { padding: 10px; font-size: 16px; margin-bottom: 10px; border-radius: 5px; border: none; }
button { padding: 10px 20px; font-size: 16px; border-radius: 5px; border: none; background: #4CAF50; color: white; cursor: pointer; }
button:hover { background: #45a049; }
.error { color: #ff5555; margin-top: 10px; display: none; }
</style>
</head>
<body>
<div id="login">
<h2>HackaShell Remote Access</h2>
<input type="password" id="pwd" placeholder="Enter Password">
<button onclick="connect()">Connect</button>
<p class="error" id="err">Incorrect password or connection failed.</p>
</div>
<div id="terminal"></div>
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
<script>
let ws;
function connect() {
const pwd = document.getElementById('pwd').value;
const err = document.getElementById('err');
// 🔒 FIX: Automatically use wss:// for HTTPS (Cloudflare) and ws:// for HTTP (Localhost)
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
ws = new WebSocket(`${protocol}//${window.location.host}/ws?token=${encodeURIComponent(pwd)}`);
let lineBuffer = "";
ws.onopen = () => {
document.getElementById('login').style.display = 'none';
document.getElementById('terminal').style.display = 'block';
const term = new Terminal({ cursorBlink: true, fontSize: 14, fontFamily: 'Consolas, monospace', theme: { background: '#1e1e1e', foreground: '#d4d4d4' } });
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById('terminal'));
fitAddon.fit();
window.addEventListener('resize', () => fitAddon.fit());
term.onData(data => {
if (data === '\\r') { ws.send(lineBuffer + '\\n'); lineBuffer = ""; }
else if (data === '\\x7f' || data === '\\b') { if (lineBuffer.length > 0) { lineBuffer = lineBuffer.slice(0, -1); term.write('\\b \\b'); } }
else if (data >= String.fromCharCode(0x20) && data <= String.fromCharCode(0x7E)) { lineBuffer += data; term.write(data); }
});
ws.onmessage = event => term.write(event.data);
ws.onclose = () => { term.write('\\r\\n[Connection closed. Refresh to reconnect.]\\r\\n'); };
};
ws.onerror = () => { err.style.display = 'block'; };
}
</script>
</body>
</html>
"""
@app.get("/")
async def get():
return HTMLResponse(html)
@app.get("/favicon.ico")
async def favicon():
return Response(status_code=204)
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
# 🔒 PASSWORD CHECK
token = websocket.query_params.get("token")
if token != PASSWORD:
await websocket.close(code=1008) # Policy violation
return
await websocket.accept()
if HACKASHELL_PATH is None:
await websocket.send_text("[!] HackaShell.py not found!\r\n")
await websocket.close()
return
proc = await asyncio.create_subprocess_exec(
sys.executable, "-u", HACKASHELL_PATH,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
cwd=os.path.dirname(HACKASHELL_PATH)
)
async def read_output():
try:
while True:
data = await proc.stdout.read(1024)
if not data: break
text = data.decode('utf-8', errors='replace').replace('\r\n', '\n').replace('\n', '\r\n')
await websocket.send_text(text)
except Exception: pass
finally:
try: await websocket.close()
except: pass
async def read_input():
try:
while True:
data = await websocket.receive_text()
if proc.stdin:
proc.stdin.write(data.encode('utf-8'))
await proc.stdin.drain()
except WebSocketDisconnect: pass
except Exception: pass
finally:
if proc.returncode is None: proc.terminate()
await asyncio.gather(read_output(), read_input())
if proc.returncode is None: proc.terminate()
if __name__ == "__main__":
if HACKASHELL_PATH:
print(f"[*] Found HackaShell at: {HACKASHELL_PATH}")
print(f"[*] Starting HackaShell Connect on http://localhost:{PORT}")
print("[*] Keep this window open while using the web interface.")
uvicorn.run(app, host="127.0.0.1", port=PORT)