Restyle fake UI and inputs, hide scrollbars
This commit is contained in:
@@ -200,6 +200,10 @@ public class FakeAdminResponder {
|
||||
const textEl = document.getElementById('typed-text');
|
||||
|
||||
const pick = (list) => list[Math.floor(Math.random() * list.length)];
|
||||
const specialLink = {
|
||||
text: 'Your special guide to get flag!',
|
||||
href: 'https://youtu.be/rrw-Pv3rc0E?si=-ZQmhZVxh4HF6luD'
|
||||
};
|
||||
|
||||
function renderImage() {
|
||||
const chosen = (images && images.length) ? pick(images) : '';
|
||||
@@ -242,25 +246,45 @@ public class FakeAdminResponder {
|
||||
|
||||
function typewriter() {
|
||||
const phrase = pick(phrases);
|
||||
const isSpecial = phrase === specialLink.text;
|
||||
textEl.textContent = '';
|
||||
let linkEl = null;
|
||||
if (isSpecial) {
|
||||
linkEl = document.createElement('a');
|
||||
linkEl.href = specialLink.href;
|
||||
linkEl.target = '_blank';
|
||||
linkEl.rel = 'noreferrer noopener';
|
||||
linkEl.style.color = '#aaf6ff';
|
||||
textEl.appendChild(linkEl);
|
||||
}
|
||||
let i = 0;
|
||||
const typeDelay = phrase.length ? 5000 / phrase.length : 120;
|
||||
|
||||
const typeInterval = setInterval(() => {
|
||||
textEl.textContent += phrase.charAt(i);
|
||||
const target = isSpecial ? linkEl : textEl;
|
||||
target.textContent += phrase.charAt(i);
|
||||
i++;
|
||||
if (i >= phrase.length) {
|
||||
clearInterval(typeInterval);
|
||||
setTimeout(() => erase(phrase), 3000);
|
||||
setTimeout(() => erase(phrase, isSpecial), 3000);
|
||||
}
|
||||
}, typeDelay);
|
||||
}
|
||||
|
||||
function erase(phrase) {
|
||||
function erase(phrase, isSpecial) {
|
||||
const eraseDelay = phrase.length ? 2000 / phrase.length : 80;
|
||||
const eraser = setInterval(() => {
|
||||
textEl.textContent = textEl.textContent.slice(0, -1);
|
||||
if (!textEl.textContent.length) {
|
||||
const target = isSpecial ? textEl.querySelector('a') : textEl;
|
||||
if (!target) {
|
||||
clearInterval(eraser);
|
||||
setTimeout(typewriter, 200);
|
||||
return;
|
||||
}
|
||||
target.textContent = target.textContent.slice(0, -1);
|
||||
if (!target.textContent.length) {
|
||||
if (isSpecial) {
|
||||
target.remove();
|
||||
}
|
||||
clearInterval(eraser);
|
||||
setTimeout(typewriter, 200);
|
||||
}
|
||||
@@ -284,158 +308,323 @@ public class FakeAdminResponder {
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>0xb00b5 team Packmate // fake packets</title>
|
||||
<title>0xb00b5 PM // packets</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css">
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=JetBrains+Mono:wght@500&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=JetBrains+Mono:wght@400;600&display=swap');
|
||||
:root {
|
||||
--bg: #04040f;
|
||||
--accent: #ff5fd2;
|
||||
--accent-2: #59f3ff;
|
||||
--glass: rgba(8, 12, 30, 0.85);
|
||||
--bg: #05030a;
|
||||
--bg-2: #0a0a18;
|
||||
--panel: rgba(9, 7, 18, 0.9);
|
||||
--panel-strong: rgba(14, 10, 24, 0.95);
|
||||
--accent: #c66bff;
|
||||
--accent-2: #7a1dff;
|
||||
--text: #e6e0ff;
|
||||
--muted: #9b90c8;
|
||||
--mono: 'JetBrains Mono', 'Ubuntu Mono', monospace;
|
||||
--pixel: 'Press Start 2P', 'JetBrains Mono', monospace;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
* { box-sizing: border-box; scrollbar-width: none; }
|
||||
*::-webkit-scrollbar { width: 0; height: 0; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(160deg, #04040f 0%, #06081a 50%, #0b1535 100%);
|
||||
color: #e9f7ff;
|
||||
font-family: 'Press Start 2P', 'JetBrains Mono', monospace;
|
||||
padding: 34px 18px 60px;
|
||||
}
|
||||
.matrix {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 14px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.banner {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(89, 243, 255, 0.35);
|
||||
box-shadow: 0 0 12px rgba(89, 243, 255, 0.25);
|
||||
background: rgba(6, 18, 40, 0.8);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card {
|
||||
background: var(--glass);
|
||||
border: 1px solid rgba(255, 95, 210, 0.35);
|
||||
border-radius: 16px;
|
||||
padding: 12px 14px;
|
||||
box-shadow: 0 0 18px rgba(255, 95, 210, 0.18);
|
||||
}
|
||||
.card h3 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 14px;
|
||||
color: #ffb3f1;
|
||||
}
|
||||
.card .meta {
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
color: rgba(233, 247, 255, 0.8);
|
||||
}
|
||||
.storm {
|
||||
background: rgba(6, 12, 28, 0.9);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(89, 243, 255, 0.35);
|
||||
box-shadow: inset 0 0 24px rgba(0,0,0,0.4), 0 0 14px rgba(89, 243, 255, 0.2);
|
||||
padding: 16px;
|
||||
height: 320px;
|
||||
background:
|
||||
radial-gradient(circle at 18% 24%, rgba(198, 107, 255, 0.18), transparent 25%),
|
||||
radial-gradient(circle at 82% 12%, rgba(122, 29, 255, 0.12), transparent 25%),
|
||||
linear-gradient(135deg, #020107 0%, #0a0820 50%, #03010b 100%);
|
||||
color: var(--text);
|
||||
font-family: var(--pixel);
|
||||
letter-spacing: 0.6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.bg-lines {
|
||||
position: fixed; inset: 0; pointer-events: none; z-index: 0;
|
||||
background-image: linear-gradient(rgba(122, 29, 255, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(198, 107, 255, 0.12) 1px, transparent 1px);
|
||||
background-size: 120px 120px;
|
||||
}
|
||||
.app-shell {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.navbar {
|
||||
background: var(--panel-strong);
|
||||
border-bottom: 1px solid rgba(122, 29, 255, 0.45);
|
||||
box-shadow: 0 10px 35px rgba(0, 0, 0, 0.55), 0 0 28px rgba(122, 29, 255, 0.35);
|
||||
padding: 12px 18px;
|
||||
}
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--accent);
|
||||
}
|
||||
.brand .dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, var(--accent), var(--accent-2));
|
||||
box-shadow: 0 0 10px rgba(122, 29, 255, 0.65);
|
||||
}
|
||||
.metrics {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
margin-left: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.chip {
|
||||
background: rgba(122, 29, 255, 0.12);
|
||||
border: 1px solid rgba(122, 29, 255, 0.28);
|
||||
color: var(--text);
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
column-gap: 8px;
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
box-shadow: 0 0 14px rgba(122, 29, 255, 0.24);
|
||||
}
|
||||
.chip .label { color: var(--muted); }
|
||||
.chip .value { color: var(--accent); }
|
||||
.patterns-dropdown {
|
||||
display: inline-flex;
|
||||
width: 128px;
|
||||
min-width: 128px;
|
||||
max-width: 128px;
|
||||
flex: 0 0 128px;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
margin-left: 14px;
|
||||
}
|
||||
.patterns-dropdown > button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: var(--pixel);
|
||||
font-size: 9.6px;
|
||||
letter-spacing: 0.05px;
|
||||
width: 128px;
|
||||
min-width: 128px;
|
||||
max-width: 128px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 0;
|
||||
min-height: calc(100vh - 72px);
|
||||
}
|
||||
.sidebar {
|
||||
background: var(--panel);
|
||||
border-right: 1px solid rgba(122, 29, 255, 0.25);
|
||||
box-shadow: inset -10px 0 24px rgba(0, 0, 0, 0.35);
|
||||
padding: 16px 12px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.sidebar-title {
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.service {
|
||||
margin: 8px 0;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(122, 29, 255, 0.25);
|
||||
background: linear-gradient(125deg, rgba(122, 29, 255, 0.12), rgba(7, 4, 15, 0.9));
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.3);
|
||||
padding: 12px;
|
||||
}
|
||||
.service .name {
|
||||
color: var(--text);
|
||||
font-size: 10px;
|
||||
}
|
||||
.service .meta {
|
||||
color: var(--muted);
|
||||
font-size: 9px;
|
||||
margin-top: 4px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.content {
|
||||
background: var(--panel);
|
||||
border-left: 1px solid rgba(122, 29, 255, 0.15);
|
||||
padding: 18px 22px 26px;
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.45), 0 0 38px rgba(122, 29, 255, 0.18);
|
||||
position: relative;
|
||||
}
|
||||
.packet-line {
|
||||
font-size: 11px;
|
||||
.content-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.title {
|
||||
font-size: 12px;
|
||||
color: var(--text);
|
||||
}
|
||||
.mode-pill {
|
||||
background: rgba(122, 29, 255, 0.12);
|
||||
border: 1px solid rgba(122, 29, 255, 0.35);
|
||||
color: var(--accent);
|
||||
padding: 6px 10px;
|
||||
border-radius: 10px;
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.5px;
|
||||
color: #c8f7ff;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px dashed rgba(255, 95, 210, 0.15);
|
||||
pointer-events: none;
|
||||
opacity: 0.85;
|
||||
animation: flicker 1.5s infinite;
|
||||
}
|
||||
.packet-line:nth-child(2n) { color: #aee3ff; }
|
||||
.packet-line:nth-child(3n) { color: #ffb3f1; }
|
||||
.packet-line.ghosted { opacity: 0.3; }
|
||||
@keyframes flicker {
|
||||
0% { text-shadow: 0 0 6px rgba(89, 243, 255, 0.35); }
|
||||
50% { text-shadow: 0 0 12px rgba(255, 95, 210, 0.3); }
|
||||
100% { text-shadow: 0 0 6px rgba(89, 243, 255, 0.35); }
|
||||
.packet-board {
|
||||
background: rgba(9, 7, 18, 0.9);
|
||||
border: 1px solid rgba(122, 29, 255, 0.35);
|
||||
border-radius: 14px;
|
||||
min-height: calc(100vh - 160px);
|
||||
padding: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 16px;
|
||||
.packet-feed {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
color: rgba(233, 247, 255, 0.6);
|
||||
max-height: calc(100vh - 200px);
|
||||
overflow-y: auto;
|
||||
padding-right: 6px;
|
||||
}
|
||||
.mute {
|
||||
opacity: 0.02;
|
||||
.packet-line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px dashed rgba(122, 29, 255, 0.2);
|
||||
color: var(--text);
|
||||
}
|
||||
.packet-line .pill {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 8px;
|
||||
background: rgba(122, 29, 255, 0.2);
|
||||
border: 1px solid rgba(122, 29, 255, 0.35);
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.4px;
|
||||
color: var(--accent);
|
||||
}
|
||||
.packet-line .meta {
|
||||
color: var(--muted);
|
||||
font-size: 10px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.packet-line .bytes { color: #9ff8ff; }
|
||||
.muted-bar {
|
||||
color: rgba(230, 224, 255, 0.4);
|
||||
font-size: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="banner">0xb00b5 team Packmate // decoy panel</div>
|
||||
<div class="matrix" id="service-grid"></div>
|
||||
<div class="storm" id="packet-feed"></div>
|
||||
<div class="footer">admin:admin only gets noise. Real API stays sealed.</div>
|
||||
<div class="mute">You're stupid:)</div>
|
||||
<div class="bg-lines"></div>
|
||||
<div class="app-shell">
|
||||
<nav class="navbar navbar-dark navbar-expand fixed-top">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="brand">
|
||||
<span class="dot"></span>
|
||||
0xb00b5 PM
|
||||
</span>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<span class="chip"><span class="label">SPM</span><span class="value" id="metric-spm">0</span></span>
|
||||
<span class="chip"><span class="label">PPS</span><span class="value" id="metric-pps">0</span></span>
|
||||
</div>
|
||||
<div class="patterns-dropdown">
|
||||
<button class="btn btn-dark btn-block" disabled>Patterns</button>
|
||||
</div>
|
||||
<span class="ml-auto text-monospace text-muted" style="font-size: 10px;">[Selected: none]</span>
|
||||
</nav>
|
||||
<div class="layout" style="margin-top: 64px;">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-title">Services</div>
|
||||
<div id="service-list"></div>
|
||||
</aside>
|
||||
<main class="content">
|
||||
<div class="content-header">
|
||||
<div class="title">Streams</div>
|
||||
<div class="mode-pill">mode: fake</div>
|
||||
</div>
|
||||
<div class="packet-board">
|
||||
<div class="packet-feed" id="packet-feed"></div>
|
||||
<div class="muted-bar">Decoy feed only. Real capture stays sealed.</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const serviceGrid = document.getElementById('service-grid');
|
||||
const packetFeed = document.getElementById('packet-feed');
|
||||
let packetId = Math.floor(Math.random() * 100000) + 1;
|
||||
const servicesEl = document.getElementById('service-list');
|
||||
const feedEl = document.getElementById('packet-feed');
|
||||
const spmEl = document.getElementById('metric-spm');
|
||||
const ppsEl = document.getElementById('metric-pps');
|
||||
let services = [];
|
||||
let packetId = Math.floor(Math.random() * 5000) + 10;
|
||||
|
||||
fetch('/api/fake/services')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
services = data;
|
||||
renderServices();
|
||||
startStorm();
|
||||
startFeed();
|
||||
})
|
||||
.catch(() => {
|
||||
services = [{ name: 'ghost', port: 0, packetKind: 'tcp' }];
|
||||
renderServices();
|
||||
startStorm();
|
||||
startFeed();
|
||||
});
|
||||
|
||||
function renderServices() {
|
||||
serviceGrid.innerHTML = '';
|
||||
services.forEach(svc => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'card';
|
||||
card.innerHTML = `
|
||||
<h3>${svc.name} #${svc.port}</h3>
|
||||
<div class="meta">packets: ${svc.packetKind || 'tcp'} stream</div>
|
||||
<div class="meta">interface: locked</div>
|
||||
servicesEl.innerHTML = '';
|
||||
services.forEach((svc, idx) => {
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'service';
|
||||
wrap.innerHTML = `
|
||||
<div class="name">${svc.name} #${svc.port}</div>
|
||||
<div class="meta">kind: ${(svc.packetKind || 'tcp').toUpperCase()}</div>
|
||||
<div class="meta">streams per min: ${Math.floor(Math.random() * 80) + 4}</div>
|
||||
`;
|
||||
serviceGrid.appendChild(card);
|
||||
servicesEl.appendChild(wrap);
|
||||
});
|
||||
}
|
||||
|
||||
function spawnPacket() {
|
||||
if (!services.length) {
|
||||
return;
|
||||
}
|
||||
if (!services.length) return;
|
||||
const svc = services[Math.floor(Math.random() * services.length)];
|
||||
const proto = (svc.packetKind || 'tcp').toUpperCase();
|
||||
const ts = new Date();
|
||||
const clock = ts.toTimeString().slice(0, 8);
|
||||
const bytes = Math.floor(Math.random() * 1800) + 40;
|
||||
|
||||
const line = document.createElement('div');
|
||||
line.className = 'packet-line';
|
||||
const protocol = (svc.packetKind || 'tcp').toUpperCase();
|
||||
line.textContent = `#${packetId} ${protocol} // :${svc.port} ${svc.name} // payload ${Math.floor(Math.random() * 1800)}b`;
|
||||
line.innerHTML = `
|
||||
<span class="pill">${proto}</span>
|
||||
<span class="meta">${clock}</span>
|
||||
<span class="meta">:${svc.port} ${svc.name}</span>
|
||||
<span class="bytes">${bytes} bytes</span>
|
||||
<span class="meta">id #${packetId}</span>
|
||||
`;
|
||||
packetId++;
|
||||
|
||||
packetFeed.prepend(line);
|
||||
while (packetFeed.children.length > 140) {
|
||||
packetFeed.removeChild(packetFeed.lastChild);
|
||||
feedEl.prepend(line);
|
||||
while (feedEl.children.length > 120) {
|
||||
feedEl.removeChild(feedEl.lastChild);
|
||||
}
|
||||
|
||||
setTimeout(() => line.classList.add('ghosted'), 1200);
|
||||
updateMetrics();
|
||||
}
|
||||
|
||||
function startStorm() {
|
||||
setInterval(spawnPacket, 50);
|
||||
function updateMetrics() {
|
||||
const total = feedEl.children.length;
|
||||
spmEl.textContent = Math.min(total, 999);
|
||||
ppsEl.textContent = Math.floor(total / 2);
|
||||
}
|
||||
|
||||
function startFeed() {
|
||||
setInterval(spawnPacket, 55);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
@@ -460,7 +649,7 @@ public class FakeAdminResponder {
|
||||
"b00b5 is not a fresh meat:(",
|
||||
"marcus, send your packmate credits pls",
|
||||
"Marcus, fuck off",
|
||||
"<a href='https://youtu.be/rrw-Pv3rc0E?si=-ZQmhZVxh4HF6luD'>Your special guide to get flag!</a>"
|
||||
"Your special guide to get flag!"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user