FEAT:🚩 Daily-AlpacaHack 「Site 2」Easy
HTTP/2 (h2c) 通信の基礎
20260615-dail_alpaca-web-easy-site_2
Summary
本問は,HTTP/2 (h2c) 通信の基礎を確認する問題です.
- Category: Web
- Description: HTTP/2 に対応した Web サイトを作ったんだけど、アクセスできなくて困ってます
- Tools & TechStack:
- Nodejs
- node::http2
- Release: 2026/06/15
階層構造
1
2
3
4
5
6
.
├── compose.yaml
├── Dockerfile
└── server.js
1 directory, 3 files
ソースコードの調査
とりあえず,HTTP/2 でサーバに接続することができれば,Flag が入手できるようです.
server.js
1
2
3
4
5
6
7
8
9
import http2 from "node:http2";
const server = http2.createServer();
server.on("stream", (stream) => {
stream.end("🦙 Welcome to my website 🦙\nFlag: Alpaca{REDACTED}");
});
server.listen(3000, () => { console.log("http://localhost:3000"); });
HTTP/2 の調査
HTTP/2に関して知識がなかったため,まず関連情報を調べました.基本的に,HTTP/2を使用するためにはTLS (HTTPS通信) を前提としています. しかし,問題文で与えられているソースコードでは,http通信を行う http2.createServer() が使用されています.本来,HTTP/2 over TLS を有効化するには,証明書と秘密鍵を読み込み,http2.createSecureServer() を使用する必要があります. そのため,httpsを使用していない環境下で h2c (HTTP/2 Cleartext)1 通信を行う方法を調べました.
h2c の接続方式
1. Prior Knowledge (事前知識) 方式
これは,HTTP/2 通信を直接行う方式です. クライアント側が接続開始時に,24バイトのマジック文字列を送信し,HTTP/2 通信を開始します.
curl での接続コマンド
1
$ curl --http2-prior-knowledge <target>
2. Upgrade (negotiation) 方式
こちらは,既存の HTTP/1.1 での通信から,HTTP/2 通信へアップグレードする方式です. クライアント側は,HTTP/1.1 のリクエストにUpgrade: h2c と HTTP2-Settings という Header を付けて送信し,サーバー側が 101 Switching Protocols で応答すれば,h2c に切り替わります.
curl での接続コマンド
1
$ curl --http2 <target>
[!warning] RFC 9113 において,Upgrade 方式による h2c の開始は正式に 廃止 (非推奨) されています. Nodejsにおいても,この手法は実装されていません.
Exploitation
--http2-prior-knowledge オプションを使用して GET リクエストを送ることで,正常に h2c 接続が完了し,Flag が表示されました.
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
$ curl -v --http2-prior-knowledge http://localhost:3000
* Host localhost:3000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:3000...
* Established connection to localhost (::1 port 3000) from ::1 port 48824
* using HTTP/2
* [HTTP/2] [1] OPENED stream for http://localhost:3000/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: http]
* [HTTP/2] [1] [:authority: localhost:3000]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.20.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: localhost:3000
> User-Agent: curl/8.20.0
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< date: Mon, 15 Jun 2026 02:14:32 GMT
<
🦙 Welcome to my website 🦙
* Connection #0 to host localhost:3000 left intact
Flag: Alpaca{REDACTED}%
Post-Mortem & Dead ends
HTTP/2 に関して無知すぎた…