From 7a58af815670270bd65bcadd445b43673473664f Mon Sep 17 00:00:00 2001 From: David Polakovic Date: Thu, 1 May 2025 11:22:30 +0200 Subject: [PATCH] made the dead drop code more readable... --- dead-drop.php | 7 +- php/captcha.php | 69 ++++++++++++ php/{dd.php => dd2.php} | 243 +++++++++++++++++++--------------------- test.php | 27 ++--- 4 files changed, 198 insertions(+), 148 deletions(-) create mode 100644 php/captcha.php rename php/{dd.php => dd2.php} (51%) diff --git a/dead-drop.php b/dead-drop.php index bd51e79..628dfe1 100755 --- a/dead-drop.php +++ b/dead-drop.php @@ -7,7 +7,8 @@ - + + @@ -45,7 +46,7 @@
A dead drop is a spy technique used for anonymous information exchange. When you stash your message in a dead drop, it will be hidden from anyone who doesn't know its location. It - also uses MD5 hashing and AES-256-CBC encryption to keep it hidden from the hosting provider + also uses SHA-256 hashing and AES-256-CBC encryption to keep it hidden from the hosting provider and webmaster as well. Enter the coordinates of a dead drop to check if it's hot (has stashed message) or if it's cold (empty). @@ -61,7 +62,7 @@

- Every dead drop goes cold after 18 hours. + Every dead drop goes cold after one sol.

diff --git a/php/captcha.php b/php/captcha.php new file mode 100644 index 0000000..213d1c6 --- /dev/null +++ b/php/captcha.php @@ -0,0 +1,69 @@ +"; + } + + echo "
"; + echo ""; + echo ""; + generatePicture(); + echo "
"; + echo ""; + echo "
"; + return null; +} + +function generatePicture() { + $width = 95; + $height = 30; + + $image = imagecreatetruecolor($width, $height); + + $isWhite = rand(0, 1) === 1; + $bgColor = $isWhite ? imagecolorallocate($image, 255, 255, 255) : imagecolorallocate($image, 0, 0, 0); + imagefilledrectangle($image, 0, 0, $width, $height, $bgColor); + + $charset = 'abcdefghijklmnpqrstuvwxyz123456789'; + $randomStr = ''; + for ($i = 0; $i < 4; $i++) { + $randomStr .= $charset[rand(0, strlen($charset) - 1)]; + } + + $_SESSION['captcha'] = $randomStr; + + $fontSize = 5; + $charWidth = imagefontwidth($fontSize); + $charHeight = imagefontheight($fontSize); + $textWidth = $charWidth * strlen($randomStr); + $x = ($width - $textWidth) / 2; + $y = ($height - $charHeight) / 2; + + $colors = [ + imagecolorallocate($image, 255, 0, 0), + imagecolorallocate($image, 0, 0, 255), + imagecolorallocate($image, 0, 255, 0), + imagecolorallocate($image, 255, 0, 255), + imagecolorallocate($image, 0, 255, 255) + ]; + + for ($i = 0; $i < strlen($randomStr); $i++) { + $char = $randomStr[$i]; + $charColor = $colors[array_rand($colors)]; + imagestring($image, $fontSize, $x + $i * $charWidth, $y, $char, $charColor); + } + + ob_start(); + imagepng($image); + $imageData = ob_get_clean(); + imagedestroy($image); + + $base64 = base64_encode($imageData); + echo 'Random Image'; +} diff --git a/php/dd.php b/php/dd2.php similarity index 51% rename from php/dd.php rename to php/dd2.php index eaade51..ab15d45 100644 --- a/php/dd.php +++ b/php/dd2.php @@ -1,74 +1,63 @@ 1){ - echo "There are $fileCount hot drops on this domain right now."; + if ($fileCount == 0) { + echo "There is no hot drop on this domain right now."; + } elseif ($fileCount == 1) { + echo "There is exactly one hot drop on this domain right now."; + } else { + echo "There are $fileCount hot drops on this domain right now."; } - } else { - echo "Directory '$directory' does not exist."; + echo "Directory '" . DEAD_DROP_DIR . "' does not exist."; } - } function cleanTheCity() { - $directory = "./Dead-drops"; $now = time(); - $expiry = 18 * 3600; - - if (is_dir($directory)) { - $files = scandir($directory); + if (is_dir(DEAD_DROP_DIR)) { + $files = scandir(DEAD_DROP_DIR); foreach ($files as $file) { - // Skip the specific file by name - if ($file == '75cfce5a009d44910a23bd55a3f8f0bd') { - continue; - } + if (in_array($file, IGNORED_DROPS)) continue; - $filePath = $directory . DIRECTORY_SEPARATOR . $file; + $filePath = DEAD_DROP_DIR . DIRECTORY_SEPARATOR . $file; if (is_file($filePath)) { $fileAge = $now - filemtime($filePath); - if ($fileAge > $expiry) { + if ($fileAge > DROP_EXPIRY_SECONDS) { unlink($filePath); } } } } else { - echo "

Error: Folder ./Locations not found.

"; + echo "

Error: Folder " . DEAD_DROP_DIR . " not found.

"; } } - - function deadDropUI() { session_start(); - $csrf_lifetime = 600; $session_id_key = 'csrf_token_session_id'; if (!isset($_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) || session_id() !== $_SESSION[$session_id_key] || - time() - $_SESSION['csrf_token_time'] > $csrf_lifetime) { + time() - $_SESSION['csrf_token_time'] > CSRF_TOKEN_LIFETIME) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); $_SESSION['csrf_token_time'] = time(); $_SESSION[$session_id_key] = session_id(); @@ -76,69 +65,78 @@ function deadDropUI() { $token = $_SESSION['csrf_token']; $result = deadDropLogic(); - $dropCount = count(glob('./Dead-drops/*')); + $dropFiles = glob(DEAD_DROP_DIR . '/*'); + $dropCount = count($dropFiles); + + if ($result['mode'] === 'readonly' && $result['status'] === 'cold') { + if ($dropCount > DROP_LIMIT) { + echo "There is too much heat on this domain right now to stash a new message. Come back later."; + return; + } + $slowDown = checkDropRate(); + if ($slowDown) { + if (captcha($token, $result['w3w']) !== 'YAY') return; + } + echo "

" . htmlentities($result['w3w']) ."

This drop is cold. You can stash your message here.

"; + echo << + + +
+ + +HTML; + return; + } - if (($result['mode'] === 'initial' && $dropCount < 501) || + if ($result['mode'] === 'initial' || ($result['mode'] === 'readonly' && $result['status'] === 'invalid')) { echo <<input[type="text"],input[type="submit"] { font-size: 16.5px; } -
- - - - -
- HTML; - } elseif ($result['mode'] === 'initial' && $dropCount >= 501) { - echo "This domain is too hot. Come back later when there won't be so much heat"; - } + +
+ + + + +
+HTML; + } - if ($result['mode'] === 'readonly') { - if ($result['status'] === 'hot') { - echo "
" . htmlspecialchars($result['decrypted'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "
"; - echo << - - - - - HTML; - } elseif ($result['status'] === 'cold') { - echo "

" . htmlentities($result['w3w']) ."

This drop is cold. You can stash your message here.

"; - echo << - - -

- - - HTML; - } elseif ($result['status'] === 'invalid') { - echo "
{$result['message']}"; - } - } elseif ($result['mode'] === 'stashed') { - echo "

Message stashed at " . htmlentities($result['w3w']) ."

Your dead drop is hot."; + if ($result['mode'] === 'readonly') { + if ($result['status'] === 'hot') { + echo "
" . htmlspecialchars($result['decrypted'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "
"; + echo << + + + + +HTML; + } elseif ($result['status'] === 'invalid') { + echo "
{$result['message']}"; } + } elseif ($result['mode'] === 'stashed') { + echo "

Message stashed at " . htmlentities($result['w3w']) ."

Your dead drop is hot."; + } } function deadDropLogic() { session_start(); - $csrf_lifetime = 600; $session_id_key = 'csrf_token_session_id'; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'], $_SESSION['csrf_token_time'], $_SESSION[$session_id_key]) || $_POST['csrf_token'] !== $_SESSION['csrf_token'] || session_id() !== $_SESSION[$session_id_key] || - time() - $_SESSION['csrf_token_time'] > $csrf_lifetime) { + time() - $_SESSION['csrf_token_time'] > CSRF_TOKEN_LIFETIME) { die('CSRF token invalid or expired. Reload the website, that usually helps...'); } if (isset($_POST['burnW3W'])) { $input = trim($_POST['burnW3W']); - $hashed = md5($input); + $hashed = hash('sha256', $input); if (!isValidHash($hashed)) die('Invalid hash'); - $file = './Dead-drops/' . $hashed; + $file = DEAD_DROP_DIR . '/' . $hashed; if (file_exists($file)) unlink($file); header("Location: https://www.dpolakovic.space/dead-drop"); exit; @@ -146,7 +144,7 @@ function deadDropLogic() { if (isset($_POST['stashContent'], $_POST['originalW3W'])) { $input = trim($_POST['originalW3W']); - $hashed_w3w = md5($input); + $hashed_w3w = hash('sha256', $input); if (!isValidHash($hashed_w3w)) die('Invalid hash'); $plaintext = $_POST['stashContent']; @@ -154,7 +152,7 @@ function deadDropLogic() { return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Message too long.']; } - $filepath = "./Dead-drops/{$hashed_w3w}"; + $filepath = DEAD_DROP_DIR . "/{$hashed_w3w}"; if (file_exists($filepath)) { return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'hot']; } @@ -176,9 +174,9 @@ function deadDropLogic() { if (!validateStringW3W($input)) { return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Place you are looking for doesn\'t exist.']; } - $hashed = md5($input); + $hashed = hash('sha256', $input); if (!isValidHash($hashed)) die('Invalid hash'); - $dropPath = './Dead-drops/' . $hashed; + $dropPath = DEAD_DROP_DIR . '/' . $hashed; if (file_exists($dropPath)) { $raw = file_get_contents($dropPath); $data = base64_decode($raw); @@ -207,69 +205,56 @@ function deadDropLogic() { } function isValidHash($hash) { - return preg_match('/^[a-f0-9]{32}$/', $hash) === 1; + return preg_match('/^[a-f0-9]{64}$/', $hash) === 1; } - - - - - - - - - - function validateString($str) { - if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - return false; - } - - if (substr($str, 0, 3) !== "///") { - return false; - } - - $parts = substr($str, 3); - if (substr_count($parts, ".") !== 2) { - return false; - } - - if (!preg_match('/^[a-z]+\.[a-z]+\.[a-z]+$/', $parts)) { - return false; - } - - return true; + if ($_SERVER['REQUEST_METHOD'] !== 'POST') return false; + if (substr($str, 0, 3) !== "///") return false; + $parts = substr($str, 3); + if (substr_count($parts, ".") !== 2) return false; + if (!preg_match('/^[a-z]+\.[a-z]+\.[a-z]+$/', $parts)) return false; + return true; } function validateStringW3W($str) { - if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - return false; - } - - $API_KEY = '747757BO'; + if ($_SERVER['REQUEST_METHOD'] !== 'POST') return false; $cleaned = substr($str, 3); - $url = 'https://api.what3words.com/v3/autosuggest?input=' . urlencode($cleaned) . '&key=' . urlencode($API_KEY); - + $url = 'https://api.what3words.com/v3/autosuggest?input=' . urlencode($cleaned) . '&key=' . urlencode(API_KEY); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); - if (curl_errno($ch)) { echo "Curl error: " . curl_error($ch); return false; } - curl_close($ch); $result = json_decode($response, true); - if (isset($result['suggestions']) && count($result['suggestions']) > 0) { foreach ($result['suggestions'] as $suggestion) { - if (strcasecmp($suggestion['words'], $cleaned) === 0) { - return true; - } + if (strcasecmp($suggestion['words'], $cleaned) === 0) return true; } } + return false; +} + +function checkDropRate() { + $files = glob(DEAD_DROP_DIR . '/*'); + usort($files, function($a, $b) { + return filemtime($b) - filemtime($a); + }); + + $now = time(); + $recentFiles = array_filter($files, fn($f) => $now - filemtime($f) <= 60); + + if (count($recentFiles) > 50) return true; + + if (count($files) >= 2) { + $t1 = filemtime($files[0]); + $t2 = filemtime($files[1]); + if (abs($t1 - $t2) < 2) return true; + } return false; -} \ No newline at end of file +} diff --git a/test.php b/test.php index 6fbf846..0c1e861 100755 --- a/test.php +++ b/test.php @@ -8,6 +8,7 @@ + @@ -28,9 +29,9 @@ @@ -78,7 +79,8 @@ if (isWebsiteOnline2($websiteUrl)) {

- cool dancing alien + + cool dancing alien

@@ -87,15 +89,12 @@ if (isWebsiteOnline2($websiteUrl)) {

-

-

- -
+

+ DOWNLOAD NOW

- - - DOWNLOAD NOW + +

@@ -103,11 +102,7 @@ if (isWebsiteOnline2($websiteUrl)) { Copyright David Polakovic - Content of this web is licensed under CC BY-NC-ND 3.0. -
- This site is javascript and cookie free. The source code is available - here - under - GPLv3 license. +
rubdeansheadwaitundernewton -- 2.30.2