1
0
mirror of https://github.com/boku7/Loki synced 2026-06-06 15:24:27 +00:00
Files
boku7-Loki/client/links.html
T

293 lines
10 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>Agent Links</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #1a1a1a;
color: #ffffff;
margin: 0;
padding: 20px;
height: 100vh;
box-sizing: border-box;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.header {
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #333;
}
.header h1 {
margin: 0;
font-size: 24px;
color: #00ff00;
}
.links-container {
background-color: #222;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.link-item {
background-color: #2a2a2a;
border: 1px solid #333;
border-radius: 4px;
padding: 12px;
margin-bottom: 10px;
transition: all 0.3s ease;
}
.link-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.link-title {
font-weight: bold;
text-align: left;
}
.link-item.windows .link-title {
color: #0078D4;
}
.link-item.linux .link-title {
color: #FCC624;
}
.link-item.macos .link-title {
color: #fff;
}
.link-item.azure .link-title {
color: #d500f9;
}
.link-status {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
}
.status-active {
background-color: #1a472a;
color: #00ff00;
}
.status-inactive {
background-color: #472a1a;
color: #ff0000;
}
.link-details {
display: grid;
grid-template-columns: 1fr 1.5fr 1fr 1.5fr;
gap: 8px 16px;
font-size: 14px;
margin-top: 8px;
}
.detail-label {
color: #aaa;
font-size: 13px;
text-align: right;
padding-right: 8px;
}
.detail-value {
color: #fff;
font-size: 14px;
text-align: left;
}
.link-actions {
margin-top: 10px;
display: flex;
gap: 10px;
}
.action-button {
background-color: #333;
border: 1px solid #444;
color: #fff;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}
.action-button:hover {
background-color: #444;
border-color: #00ff00;
}
.no-links {
text-align: center;
padding: 20px;
color: #666;
font-style: italic;
}
.platform-icon {
width: 24px;
height: 24px;
object-fit: contain;
vertical-align: middle;
margin-right: 8px;
}
/* Platform-specific themes */
.link-item.windows {
border-left: 4px solid #0078D4;
background-color: rgba(0, 120, 212, 0.13);
}
.link-item.windows:hover {
background-color: rgba(0, 120, 212, 0.20);
border-color: #0078D4;
}
.link-item.linux {
border-left: 4px solid #FCC624;
background-color: rgba(252, 198, 36, 0.13);
}
.link-item.linux:hover {
background-color: rgba(252, 198, 36, 0.20);
border-color: #FCC624;
}
.link-item.macos {
border-left: 4px solid #fff;
background-color: rgba(255,255,255,0.13);
}
.link-item.macos:hover {
background-color: rgba(255,255,255,0.15);
border-color: #fff;
}
.link-item.azure {
border-left: 4px solid #d500f9;
background-color: rgba(213, 0, 249, 0.13);
}
.link-item.azure:hover {
background-color: rgba(213, 0, 249, 0.15);
border-color: #d500f9;
}
.arrow-container {
display: flex;
justify-content: center;
align-items: center;
margin: -5px 0 10px 0;
}
.arrow {
color: #fff;
font-size: 24px;
line-height: 1;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="links-container" id="linksContainer">
<div class="no-links">Loading links...</div>
</div>
</div>
<script>
const { ipcRenderer } = require('electron');
ipcRenderer.on('agent-links', (event, agentsData) => {
const container = document.getElementById('linksContainer');
if (!agentsData || agentsData.length === 0) {
container.innerHTML = '<div class="no-links">No links available</div>';
return;
}
let html = '';
agentsData.forEach((agent, index) => {
// Platform icon logic
let platformIcon = '';
let platformKey = agent.platform || '';
if (platformKey.toLowerCase().includes('mac')) platformKey = 'macOS';
if (platformKey.toLowerCase().includes('darwin')) platformKey = 'macOS';
if (platformKey.toLowerCase().includes('windows')) platformKey = 'Windows';
if (platformKey.toLowerCase().includes('linux')) platformKey = 'Linux';
if (platformKey.toLowerCase().includes('azure')) platformKey = 'Azure Storage Account';
if (PLATFORM_ICONS[platformKey]) {
platformIcon = `<img src="${PLATFORM_ICONS[platformKey]}" class="platform-icon" alt="${agent.platform} icon">`;
}
// Platform class for color theme
let platformClass = '';
if (platformKey === 'Windows') platformClass = 'windows';
else if (platformKey === 'Linux') platformClass = 'linux';
else if (platformKey === 'macOS') platformClass = 'macos';
else if (platformKey === 'Azure Storage Account') platformClass = 'azure';
// Azure card: only show hostname and platform
if (platformKey === 'Azure Storage Account') {
html += `
<div class="link-item ${platformClass}">
<div class="link-header">
${platformIcon}
<span class="link-title">${agent.hostname || 'Azure Storage'}</span>
</div>
<div class="link-details">
<span class="detail-label">Platform</span>
<span class="detail-value">Azure Storage Account</span>
</div>
</div>
`;
} else {
html += `
<div class="link-item ${platformClass}">
<div class="link-header">
${platformIcon}
<span class="link-title">${agent.hostname || agent.agentid || 'Unnamed Agent'}</span>
</div>
<div class="link-details">
<span class="detail-label">Agent ID</span><span class="detail-value">${agent.agentid || ''}</span>
<span class="detail-label">Container</span><span class="detail-value">${agent.containerid || ''}</span>
<span class="detail-label">Username</span><span class="detail-value">${agent.username || ''}</span>
<span class="detail-label">Process</span><span class="detail-value">${agent.fileName || ''}</span>
<span class="detail-label">PID</span><span class="detail-value">${agent.PID || ''}</span>
<span class="detail-label">IP</span><span class="detail-value">${agent.IP || ''}</span>
<span class="detail-label">Architecture</span><span class="detail-value">${agent.arch || ''}</span>
<span class="detail-label">Mode</span><span class="detail-value">${agent.mode || ''}</span>
<span class="detail-label">Platform</span><span class="detail-value">${agent.platform || ''}</span>
</div>
</div>
`;
}
if (index < agentsData.length - 1) {
html += `
<div class="arrow-container">
<div class="arrow">↓</div>
</div>
`;
}
});
container.innerHTML = html;
});
function handleAction(action, linkId) {
ipcRenderer.send('link-action', { action, linkId });
}
// Base64 encoded SVG icons
const PLATFORM_ICONS = {
Windows: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4OCA4OCI+PHBhdGggZD0iTTAgMTJoMzd2MzdIMFYxMnptNDEgMGg0N3YzN0g0MVYxMnptLTQxIDQxaDM3djM3SDBWNTN6bTQxIDBoNDd2MzdINDFWNTN6Ii8+PC9zdmc+',
Linux: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBkPSJNMjU2IDEyOGMtMTcuNyAwLTMyIDE0LjMtMzIgMzJ2MzJoNjR2LTMyYzAtMTcuNy0xNC4zLTMyLTMyLTMyem0tOTYgNjRjLTE3LjcgMC0zMiAxNC4zLTMyIDMydjk2YzAgMTcuNyAxNC4zIDMyIDMyIDMyaDY0di0zMmgtMzJ2LTY0aDMydi0zMmgtNjR6bTE5MiAwdjMyaDMydjY0aC0zMnYzMmg2NGMxNy43IDAgMzItMTQuMyAzMi0zMnYtOTZjMC0xNy43LTE0LjMtMzItMzItMzJoLTY0eiIvPjwvc3ZnPg==',
macOS: 'assets/images/apple.png',
'Azure Storage Account': 'assets/images/azure.png'
};
</script>
</body>
</html>