Your objective is to create a working alert(1) payload that executes inside the <script> tag shown below.
🔒 Restrictions:
– Max 275 characters
– Only special characters and Unicode rune characters are allowed
– No letters (a-zA-Z) or digits (0-9)
💡 Hints:
– Unicode characters (like runes) can be used as JavaScript variables, e.g., ᚠ = ''
– You cannot call function names like alert(1) directly due to letter restrictions
– Instead, build your own eval using string-based logic
– Certain built-in values, when used in unexpected expressions, may reveal useful strings.
For example, combining them with other types can sometimes coerce them into a readable form.
Once you have a string, remember: JavaScript lets you access individual characters using index notation — just like an array but only if the output itself is a string aka "test"[0] returns "t".
– A great trick from JSFuck: []["filter"]["constructor"]("alert(1)")() or here a better example how to "construct" your payloads []["fil"+"ter"]["const"+"ructor"]("ale"+"rt(1)")()
– This works entirely on strings, no named functions but the eval sink can run any function
👇 Scroll to the bottom and hit the button to see all allowed characters printed in your browser console
<?php
header("Content-Type: text/html; charset=utf-8");
$error = '';
$scriptPayload = '';
// Handle GET input
if (isset($_GET['input'])) {
$input = $_GET['input'];
echo "total length off payload input: ".mb_strlen($input, 'UTF-8');
// Length check (UTF-8)
if (mb_strlen($input, 'UTF-8') > 275) {
$error = '❌ Forbidden: Input exceeds 275 character limit.';
}
// Reject letters and digits
elseif (preg_match('/[a-zA-Z0-9]/', $input)) {
$error = '❌ Forbidden: Letters and digits are not allowed.';
}
// Reject anything outside of punctuation + runes
elseif (preg_match('/[^\p{S}\p{P}\x{16A0}-\x{16FF}]/u', $input)) {
$error = '❌ Forbidden: Only special characters and Unicode runes are allowed.';
} else {
$scriptPayload = $input;
}
}
?>
<div style="margin-top: 30px; background: #f0f0f0; padding: 15px; border-radius: 8px;">
<h1>CTF 19 – Runes Challenge</h1>
<h2>
(Inspired by the PMNH Challenge)<br><br>
Your objective is to create a working alert(1) payload that executes inside the <script> tag shown below.<br><br>
🔒 Restrictions:<br>
– Max 275 characters<br>
– Only special characters and Unicode rune characters are allowed<br>
– No letters (a-zA-Z) or digits (0-9)<br><br>
💡 Hints:<br>
– Unicode characters (like runes) can be used as JavaScript variables, e.g., <code>ᚠ = ''</code><br>
– You cannot call function names like <code>alert(1)</code> directly due to letter restrictions<br>
– Instead, build your own eval using string-based logic<br>
– Certain built-in values, when used in unexpected expressions, may reveal useful strings.
For example, combining them with other types can sometimes coerce them into a readable form.
Once you have a string, remember: JavaScript lets you access individual characters using index notation — just like an array but only if the output itself is a string aka <code>"test"[0]</code> returns "t".<br>
– A great trick from JSFuck:<br>
<code>[]["filter"]["constructor"]("alert(1)")()</code> or here a better example how to "construct" your payloads <code>[]["fil"+"ter"]["const"+"ructor"]("ale"+"rt(1)")()</code><br>
– This works entirely on strings, no named functions but the eval sink can run any function <br><br>
👇 Scroll to the bottom and hit the button to see all allowed characters printed in your browser console<br><br>
📚 Highly encouraged: study the full JSFuck reference or your gone have a bad time<br>
<a href="https://jsfuck.com/" target="_blank">
https://github.com/aemkei/jsfuck/blob/main/jsfuck.js
</a><br>
<a href="https://jsfuck.com/" target="_blank">
https://jsfuck.com/
</a></br>
</h2>
</div>
<!-- Console Helper -->
<button onclick="showAllowedChars()" style="margin-top:10px;">Show all Allowed Characters in your console (Console)</button>
<form method="get" action="" style="margin-top: 20px;">
<label for="input">Enter your rune/special-char payload (max 275 chars):</label><br>
<input type="text" name="input" id="input"
style="width: 100%; font-family: monospace;"
value="<?= htmlspecialchars($_GET['input'] ?? '') ?>"><br><br>
<button type="submit">Send Payload</button>
</form>
<!-- Error + Output Section -->
<div style="margin-top: 20px;">
<?php if ($error): ?>
<div style="color: red; font-weight: bold;">
<?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>
<?php if (!$error): ?>
<script>
// filler comment ignore payload is placed under this.
<?= $scriptPayload ?>
</script>
<?php endif; ?>
</div>
<?php
// Always show the PHP source
highlight_file(__FILE__);
echo '<hr>';
?>
<script>
function showAllowedChars() {
// generates all allowed chars in console make good use off this.
const specials = `!"#$%&'()*+,-./:;<=>?@[\\]^_\`{|}~`;
const runes = [];
for (let i = 0x16A0; i <= 0x16FF; i++) {
runes.push(String.fromCharCode(i));
}
console.log("Allowed Special Characters:");
console.log(specials.split('').join(','));
console.log("Allowed Unicode Runes (U+16A0–U+16FF):");
console.log(runes.join(','));
}
</script>