Created
September 27, 2023 00:28
-
-
Save mnixry/cdee7353f383eb973657e72d03b11954 to your computer and use it in GitHub Desktop.
Base3050 Challenge (TSCTF-J 2023)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class BaseN | |
{ | |
protected $charset; | |
protected $reverseCharset; | |
public function __construct(array $charset) | |
{ | |
$this->charset = $charset; | |
$this->reverseCharset = array_flip($this->charset); | |
assert(count($this->charset) == count($this->reverseCharset)); | |
} | |
public function encode(string $input): array | |
{ | |
$output = []; | |
$base = count($this->charset); | |
$input_n = array_reduce( | |
unpack('C*', $input), | |
function ($carry, $item) { | |
return bcadd(bcmul($carry, 256), $item); | |
}, | |
0 | |
); | |
error_log(print_r($input_n, true)); | |
while ($input_n > 0) { | |
$output[] = $this->charset[bcmod($input_n, $base)]; | |
$input_n = bcdiv($input_n, $base, 0); | |
} | |
return $output; | |
} | |
} | |
const EMOJI_DIR = './openmoji-svg-color/'; | |
$flag = getenv('FLAG', true) ?: 'flag{base3050_1s_4w3s0m3}'; | |
$emojis = []; | |
foreach (glob(EMOJI_DIR . '*.svg') as $file) { | |
$file_basename = pathinfo($file, PATHINFO_FILENAME); | |
$emojis[$file_basename] = file_get_contents($file); | |
} | |
$emojiKeys = array_keys($emojis); | |
srand(crc32($flag)); | |
shuffle($emojiKeys); | |
$emojiCharset = array_slice($emojiKeys, 0, 3050); | |
$base3050 = new BaseN($emojiCharset); | |
/** | |
* <div class="emoji" alt="$char"> | |
* <?= $emojis[$char] ?> | |
* </div> | |
*/ | |
?> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Base3050</title> | |
<style> | |
.emoji svg { | |
margin-top: 10px; | |
height: 30px; | |
} | |
.emoji-container { | |
display: flex; | |
flex-direction: row; | |
flex-wrap: wrap; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="flag"> | |
<h1>Your flag is:</h1> | |
<p> Total <?= count($emojiCharset) ?> emojis</p> | |
<div class="emoji-container"> | |
<?php foreach ($base3050->encode($flag) as $char) : ?> | |
<div class="emoji" alt="<?= $char ?>"> | |
<?= $emojis[$char] ?> | |
</div> | |
<?php endforeach; ?> | |
</div> | |
</div> | |
</div> | |
<hr /> | |
<!--input chars and output encoded emoji SVGs--> | |
<form method="post"> | |
<input type="submit" value="Encode"> | |
<input type="textarea" name="input" placeholder="Try something here..." value="<?= $_POST['input'] ?? '' ?>" autocomplete="false"> | |
</form> | |
<div class="emoji-container"> | |
<?php if (isset($_POST['input'])) : ?> | |
<?php foreach ($base3050->encode($_POST['input']) as $char) : ?> | |
<div class="emoji" alt="<?= $char ?>"> | |
<?= $emojis[$char] ?> | |
</div> | |
<?php endforeach; ?> | |
<?php endif; ?> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment