From: David Polakovic Date: Thu, 1 May 2025 09:22:30 +0000 (+0200) Subject: made the dead drop code more readable... X-Git-Url: https://git.dpolakovic.space/?a=commitdiff_plain;h=7a58af815670270bd65bcadd445b43673473664f;p=my-website made the dead drop code more readable... --- 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/dd.php deleted file mode 100644 index eaade51..0000000 --- a/php/dd.php +++ /dev/null @@ -1,275 +0,0 @@ - 1){ - echo "There are $fileCount hot drops on this domain right now."; - } - - } else { - echo "Directory '$directory' does not exist."; - } - -} - -function cleanTheCity() { - $directory = "./Dead-drops"; - $now = time(); - $expiry = 18 * 3600; - - if (is_dir($directory)) { - $files = scandir($directory); - foreach ($files as $file) { - // Skip the specific file by name - if ($file == '75cfce5a009d44910a23bd55a3f8f0bd') { - continue; - } - - $filePath = $directory . DIRECTORY_SEPARATOR . $file; - if (is_file($filePath)) { - $fileAge = $now - filemtime($filePath); - if ($fileAge > $expiry) { - unlink($filePath); - } - } - } - } else { - echo "

Error: Folder ./Locations 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) { - $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); - $_SESSION['csrf_token_time'] = time(); - $_SESSION[$session_id_key] = session_id(); - } - - $token = $_SESSION['csrf_token']; - $result = deadDropLogic(); - $dropCount = count(glob('./Dead-drops/*')); - - if (($result['mode'] === 'initial' && $dropCount < 501) || - ($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"; - } - - 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."; - } -} - -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) { - die('CSRF token invalid or expired. Reload the website, that usually helps...'); - } - - if (isset($_POST['burnW3W'])) { - $input = trim($_POST['burnW3W']); - $hashed = md5($input); - if (!isValidHash($hashed)) die('Invalid hash'); - $file = './Dead-drops/' . $hashed; - if (file_exists($file)) unlink($file); - header("Location: https://www.dpolakovic.space/dead-drop"); - exit; - } - - if (isset($_POST['stashContent'], $_POST['originalW3W'])) { - $input = trim($_POST['originalW3W']); - $hashed_w3w = md5($input); - if (!isValidHash($hashed_w3w)) die('Invalid hash'); - $plaintext = $_POST['stashContent']; - - if (strlen($plaintext) > 4096) { - return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Message too long.']; - } - - $filepath = "./Dead-drops/{$hashed_w3w}"; - if (file_exists($filepath)) { - return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'hot']; - } - - $cipher = "AES-256-CBC"; - $key = hash('sha256', $input); - $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher)); - $encrypted = openssl_encrypt($plaintext, $cipher, $key, 0, $iv); - $output = base64_encode($iv . $encrypted); - file_put_contents($filepath, $output); - return ['mode' => 'stashed', 'w3w' => $input]; - } - - if (isset($_POST['inputString'])) { - $input = trim($_POST['inputString']); - if (!validateString($input)) { - return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Invalid coordinates format.']; - } - if (!validateStringW3W($input)) { - return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Place you are looking for doesn\'t exist.']; - } - $hashed = md5($input); - if (!isValidHash($hashed)) die('Invalid hash'); - $dropPath = './Dead-drops/' . $hashed; - if (file_exists($dropPath)) { - $raw = file_get_contents($dropPath); - $data = base64_decode($raw); - $iv_len = openssl_cipher_iv_length("AES-256-CBC"); - $iv = substr($data, 0, $iv_len); - $ciphertext = substr($data, $iv_len); - $key = hash('sha256', $input); - $decrypted = openssl_decrypt($ciphertext, "AES-256-CBC", $key, 0, $iv); - return [ - 'mode' => 'readonly', - 'w3w' => $input, - 'status' => 'hot', - 'decrypted' => $decrypted - ]; - } else { - return [ - 'mode' => 'readonly', - 'w3w' => $input, - 'status' => 'cold' - ]; - } - } - } - - return ['mode' => 'initial']; -} - -function isValidHash($hash) { - return preg_match('/^[a-f0-9]{32}$/', $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; -} - -function validateStringW3W($str) { - if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - return false; - } - - $API_KEY = '747757BO'; - $cleaned = substr($str, 3); - $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; - } - } - } - - return false; -} \ No newline at end of file diff --git a/php/dd2.php b/php/dd2.php new file mode 100644 index 0000000..ab15d45 --- /dev/null +++ b/php/dd2.php @@ -0,0 +1,260 @@ + DROP_EXPIRY_SECONDS) { + unlink($filePath); + } + } + } + } else { + echo "

Error: Folder " . DEAD_DROP_DIR . " not found.

"; + } +} + +function deadDropUI() { + session_start(); + $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_TOKEN_LIFETIME) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + $_SESSION['csrf_token_time'] = time(); + $_SESSION[$session_id_key] = session_id(); + } + + $token = $_SESSION['csrf_token']; + $result = deadDropLogic(); + $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' || + ($result['mode'] === 'readonly' && $result['status'] === 'invalid')) { + echo <<input[type="text"],input[type="submit"] { font-size: 16.5px; } +
+ + + + +
+HTML; + } + + 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(); + $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_TOKEN_LIFETIME) { + die('CSRF token invalid or expired. Reload the website, that usually helps...'); + } + + if (isset($_POST['burnW3W'])) { + $input = trim($_POST['burnW3W']); + $hashed = hash('sha256', $input); + if (!isValidHash($hashed)) die('Invalid hash'); + $file = DEAD_DROP_DIR . '/' . $hashed; + if (file_exists($file)) unlink($file); + header("Location: https://www.dpolakovic.space/dead-drop"); + exit; + } + + if (isset($_POST['stashContent'], $_POST['originalW3W'])) { + $input = trim($_POST['originalW3W']); + $hashed_w3w = hash('sha256', $input); + if (!isValidHash($hashed_w3w)) die('Invalid hash'); + $plaintext = $_POST['stashContent']; + + if (strlen($plaintext) > 4096) { + return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Message too long.']; + } + + $filepath = DEAD_DROP_DIR . "/{$hashed_w3w}"; + if (file_exists($filepath)) { + return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'hot']; + } + + $cipher = "AES-256-CBC"; + $key = hash('sha256', $input); + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher)); + $encrypted = openssl_encrypt($plaintext, $cipher, $key, 0, $iv); + $output = base64_encode($iv . $encrypted); + file_put_contents($filepath, $output); + return ['mode' => 'stashed', 'w3w' => $input]; + } + + if (isset($_POST['inputString'])) { + $input = trim($_POST['inputString']); + if (!validateString($input)) { + return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Invalid coordinates format.']; + } + if (!validateStringW3W($input)) { + return ['mode' => 'readonly', 'w3w' => $input, 'status' => 'invalid', 'message' => 'ERROR: Place you are looking for doesn\'t exist.']; + } + $hashed = hash('sha256', $input); + if (!isValidHash($hashed)) die('Invalid hash'); + $dropPath = DEAD_DROP_DIR . '/' . $hashed; + if (file_exists($dropPath)) { + $raw = file_get_contents($dropPath); + $data = base64_decode($raw); + $iv_len = openssl_cipher_iv_length("AES-256-CBC"); + $iv = substr($data, 0, $iv_len); + $ciphertext = substr($data, $iv_len); + $key = hash('sha256', $input); + $decrypted = openssl_decrypt($ciphertext, "AES-256-CBC", $key, 0, $iv); + return [ + 'mode' => 'readonly', + 'w3w' => $input, + 'status' => 'hot', + 'decrypted' => $decrypted + ]; + } else { + return [ + 'mode' => 'readonly', + 'w3w' => $input, + 'status' => 'cold' + ]; + } + } + } + + return ['mode' => 'initial']; +} + +function isValidHash($hash) { + 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; +} + +function validateStringW3W($str) { + 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); + $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; + } + } + 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; +} 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