Back

H2C Smuggling

๐Ÿ” Introduction

HTTP/2 Protocol and H2C Switching

HTTP2 ํ”„๋กœํ† ์ฝœ์€ ๊ตฌ๊ธ€์—์„œ ๊ฐœ๋ฐœ ๋ฐ ์‹œ๋ฒ” ์‚ฌ์šฉ์ค‘์ด๋˜ SPDY ํ”„๋กœํ† ์ฝœ์˜ ์‚ฌ์–‘์„ ๊ธฐ๋ฐ˜์œผ๋กœ HTTP-WG์—์„œ ์ง„ํ–‰ํ•œ ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  2015๋…„ HTTP/2 ํ‘œ์ค€์œผ๋กœ ์ฑ„ํƒ๋จ๊ณผ ๋™์‹œ์— SPDY๋Š” ์ง€์› ์ค‘๋‹จ์„ ํ•˜๊ฒŒ ๋˜์—ˆ์ง€์š”. ์•„๋ฌดํŠผ HTTP/2๋‚œ ์ฐจ์„ธ๋Œ€ ์›น ํ”„๋กœํ† ์ฝœ๋กœ ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™๊ณ , 1.x ๋ฒ„์ „๋Œ€๋ณด๋‹ค ์„ฑ๋Šฅ์ ์œผ๋กœ ํฐ ๊ฐœ์„ ๋“ค์ด ์žˆ์–ด์„œ ์„œ์„œํžˆ ๋งŽ์€ ์„œ๋ฒ„๋“ค์ด HTTP2 ์ง€์›์„ ํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค. HTTP2์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ google developers ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

H2C๋Š” HTTP/1.x ๋ฒ„์ „์—์„œ HTTP/2 ๋ฒ„์ „์œผ๋กœ ํ”„๋กœํ† ์ฝœ์„ ์Šค์œ„์นญํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ ๋ชจ๋‘ HTTP/2 ์ง€์›์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. (RFC-7540)

Request

GET / HTTP/1.1
Host: test.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c

Response - HTTP/2 ์ง€์›

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c
[ HTTP/2 connection ...

Response - HTTP/2 ๋ฏธ์ง€์›

์„œ๋ฒ„๊ฐ€ ๋ฌด์‹œ

RFC-7540์„ ์ฝ์–ด๋ณด๋ฉด HTTP/2 ํ†ต์‹ ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์›น ์†Œ์ผ“ ํ†ต์‹ ๊ณผ ๋งŽ์ด ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ(์›น๋ธŒ๋ผ์šฐ์ €)๋Š” ์›น ์„œ๋ฒ„์™€์˜ HTTP/2 ํ†ต์‹ ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์—์„œ HTTP/2 ์ง€์› ์—ฌ๋ถ€๋ฅผ ๋ฌผ์–ด๋ณด๊ณ , ๊ทธ์— ๋”ฐ๋ผ์„œ HTTP/2๋ฅผ ํ†ต์‹ ์„ ์‚ฌ์šฉํ• ์ง€, HTTP/1.x ํ†ต์‹ ์„ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

HTTP/2 ํ†ต์‹ ์€ 7 Layer(Application) ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ํ”„๋กœํ† ์ฝœ์ด๊ณ , TCP Connection์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ธฐ์กด HTTP ํ†ต์‹ ๊ณผ๋Š” ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์›น ์†Œ์ผ“๊ณผ ๊ฐ™์ด ์ง€์›์—ฌ๋ถ€ ์ฒดํฌ ํ›„ ํ”„๋กœํ† ์ฝœ ๋ณ€ํ™˜์ธ 101 Switching protocol์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (uri๋Š” http์™€ ๋™์ผํ•˜๊ฒŒ http->80, https->443์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.)

An HTTP/2 connection is an application-layer protocol running on top
of a TCP connection ([TCP]).  The client is the TCP connection
initiator.

HTTP/2 uses the same "http" and "https" URI schemes used by HTTP/1.1.
HTTP/2 shares the same default port numbers: 80 for "http" URIs and
443 for "https" URIs.  As a result, implementations processing
requests for target resource URIs like "http://example.org/foo" or
"https://example.com/bar" are required to first discover whether the
upstream server (the immediate peer to which the client wishes to
establish a connection) supports HTTP/2.

The means by which support for HTTP/2 is determined is different for
"http" and "https" URIs.  Discovery for "http" URIs is described in
Section 3.2.  Discovery for "https" URIs is described in Section 3.3.

http/1.x -> http/2๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์œ„ํ•ด์„  http request์˜ Upgrade ํ—ค๋”์— indicator์™€ HTTP2-Settings ํ—ค๋”๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. indicator ์ข…๋ฅ˜๋Š” HTTP๋Š” h2c HTTPS๋Š” h2 ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ Upgrade: h2c ๋Š” HTTP/2๋ฅผ ํ‰๋ฌธ์œผ๋กœ ํ†ต์‹ ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

GET / HTTP/1.1
Host: test.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

์ดํ›„ HTTP/2๋ฅผ ์ง€์›ํ•˜๊ฒŒ ๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—๊ฒ 101 Switching protocol์„ ์ „๋‹ฌํ•˜๊ณ  TLS Connection(HTTP/2)์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์™€ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ํ”„๋กœํ† ์ฝœ์— ๋Œ€ํ•œ ํ•ฉ์˜๋Š” TLS-ALPN(Application-Layer-Protocol Negotiation)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ APLN extension์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ๋ฒ„์ „์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ณ , ์„œ๋ฒ„๋Š” ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. https๋ฅผ ์‚ฌ์šฉํ•˜๋Š” HTTP/2์˜ ๊ฐ’์€ h2์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก  HTTP/2๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ผ€์ด์Šค์˜ ๊ฒฝ์šฐ TLS-ALPN์„ ํ†ตํ•ด ๋ฐ”๋กœ ํ”„๋กœํ† ์ฝœ ํ˜‘์ƒ ํ›„ TLS ์ปค๋„ฅ์…˜์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

H2C Smuggling

๋งŽ์€ ์›น ์„œ๋น„์Šค๋“ค์€ Reverse Proxy๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์—์„œ 101 Switching ์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์˜ค๋ฉด, ํ”„๋ก์‹œ ์„œ๋ฒ„๋Š” ๋ณ„๋„์˜ ์ฒ˜๋ฆฌ์—†์ด ์ค‘์žฌ์ž ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ bishopfox๋Š” HTTP/2 ํ”„๋กœํ† ์ฝœ์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ์ง„ํ–‰ํ–ˆ๊ณ , ๊ฒฐ๊ตญ ์žฌ๋ฏธ์žˆ๋Š” ๊ฒฐํ•จ์„ ๋ฐœ๊ฒฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

RFC-7540์˜ 3.2.1 ๋ถ€๋ถ„์— ๋ช…์‹œ๋œ ๋‚ด์šฉ๊ณผ TLS ๋‚ด HTTP/2 ์„ค์ •์—์„  h2c Upgrade๋Š” cleartext connection์—์„œ๋งŒ ํ—ˆ์šฉ๋˜๊ณ  ์ด ๋•Œ HTTP2-Settings ํ—ค๋”๋Š” ์ „๋‹ฌํ•˜์ง€ ๋ง์•„์•ผํ•œ๋‹ค๊ณ  ๋ช…์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

HTTP2-Settings    = token68

A server MUST NOT upgrade the connection to HTTP/2 if this header
field is not present or if more than one is present.  A server MUST
NOT send this header field.

https://tools.ietf.org/html/rfc7540#section-3.2.1

HTTP2 ์ŠคํŽ™์—๋Š” ์ด๋ ‡๊ฒŒ ๋ช…์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

3.3 Starting HTTP/2 for "https" URIs
A client that makes a request to an "https" URI uses TLS [TLS12] with the application-layer protocol negotiation (ALPN) extension [TLS-ALPN].

HTTP/2 over TLS uses the "h2" protocol identifier. The "h2c" protocol identifier MUST NOT be sent by a client or selected by a server; the "h2c" protocol identifier describes a protocol that does not use TLS.

Once TLS negotiation is complete, both the client and the server MUST send a connection preface (Section 3.5).

https://http2.github.io/http2-spec/#discover-https

TLS๋ฅผ ํ†ตํ•œ HTTP/2๋ฅผ ์‚ฌ์šฉํ•  ๋• h2c๊ฐ€ ์•„๋‹Œ h2 ํ”„๋กœํ† ์ฝœ ์‹๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ๋งจ ์œ„์—์„œ ์ด์•ผ๊ธฐ๋“œ๋ ธ๋“ฏ์ด h2c๋Š” http, h2๋Š” https๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ indicator์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .๋งŒ์•ฝ proxy๊ฐ€ ๊ปด์žˆ๋Š” ๊ตฌ์กฐ์—์„œ cleartext๊ฐ€ ์•„๋‹Œ TLS ์ƒ์—์„œ proxy๊ฐ€ h2c ๋ฅผ ๋ฐฑ์—”๋“œ์— ์ „๋‹ฌํ•˜์—ฌ upgrade๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

Proxy๊ฐ€ ์žˆ๋Š” hops ํ™˜๊ฒฝ์—์„œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ Cleartext์ธ์ง€ TLS์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด h2c,h2 ๋“ฑ์˜ indicator ๋ฟ์ด๋ผ ์›น์ด ์•„๋‹Œ TLS Connection์„ HTTP๋กœ ํŒ๋‹จํ•˜์—ฌ TLS Connection ์œ„์— TCP Tunnel ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ๋•Œ ํด๋ผ์ด์–ธํŠธ๋Š” HTTP๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด ์ปค๋„ฅ์…˜์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (Over TLS)

์ฆ‰ ์ด๋ฏธ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ปค๋„ฅ์…˜์ด๊ณ  HTTP ํ†ต์‹ ์ด ์•„๋‹ˆ๊ธฐ ๋–„๋ฌธ์— Proxy์˜ ACL ์ •์ฑ…์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์ง€๋งŒ, TCP Tunnel์—์„œ ๋ฐœ์ƒํ•œ ์š”์ฒญ์ด HTTP๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฐจ๋‹จ๋œ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํฌ์ธํŠธ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.

Flows

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„(ํ”„๋ก์‹œ)๋กœ HTTP/1.1 Upgrade ์š”์ฒญ ์ „์†ก (์ž˜๋ชป๋œ ํ—ค๋”๋ฅผ ์ „์†ก)
  • ํ”„๋ก์‹œ๊ฐ€ ํ•ด๋‹น ์š”์ฒญ์„ ๋ฐฑ์—”๋“œ์— ์ „๋‹ฌํ•˜๊ณ  101 Swiching protocol๋กœ response๋ฅผ ๋‚ด๋ ค์คŒ
  • ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์—์„œ 101์„ ๋ฐ›์œผ๋ฉด TCP Tunnel์„ ์ƒ์„ฑํ•จ
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ”„๋ก์‹œ๋กœ๋ถ€ํ„ฐ 101์„ ๋ฐ›์œผ๋ฉด ๊ธฐ์กด ์ปค๋„ฅ์…˜์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ , HTTP/2 ์ดˆ๊ธฐํ™”๋ฅผ ์ง„ํ–‰
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ HTTP/2 multiplexing์„ ์‚ฌ์šฉํ•˜์—ฌ priavteํ•œ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด ์ถ”๊ฐ€ ์š”์ฒญ์„ ์ „์†กํ•จ
  • ํ”„๋ก์‹œ๋Š” TCP ํ†ต์‹ ์„ ๊ฐ์‹œํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—(์ •์ฑ…์ƒ HTTP) ์ œํ•œ๋œ ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ , ์„œ๋ฒ„๋Š” ์‘๋‹ต์„ TLS Tunnel๋กœ ์ „๋‹ฌํ•จ

๐Ÿ—ก Offensive techniques

Detect

ํ•ด๋‹น ์ทจ์•ฝ์ ์„ ๋ฐœ๊ฒฌํ•œ ByshopFox๊ฐ€ ๋„๊ตฌ์™€ ํ™˜๊ฒฝ์„ ๋งŒ๋“ค์–ด๋‘์–ด์„œ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/BishopFox/h2csmuggler

  1. Set-up
$ git clone https://github.com/BishopFox/h2csmuggler
$ cd h2csmuggler
$ pip3 install h2
  1. Scanning
$ python3 h2csmuggler.py --scan-list urls.txt --threads 5
  1. Get internal endpoint
$ python3 h2csmuggler.py -x https://edgeserver -X POST -d '{"user":128457 "role": "admin"}' -H "Content-Type: application/json" -H "X-SYSTEM-USER: true" http://backend/api/internal/user/permissions
  1. Bruteforce endpoint
$ python3 h2csmuggler.py -x https://edgeserver -i dirs.txt http://localhost/
  1. Get AWS Metadata API
$ python3 h2csmuggler.py -x https://edgeserver -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token`

๐Ÿ›ก Defensive techniques

HTTP Request Smuggling / WebSocket Connection Smuggling๊ณผ ๊ฐ™์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋Œ€์‘๋ฐฉ์•ˆ์ด ์žˆ๊ฒ ์ง€๋งŒ, ์›๋ฆฌ์ ์ธ ์ธก๋ฉด์—์„œ ๋ณด๋ฉด RFC ๋ฌธ์„œ์—์„œ ์ด์•ผ๊ธฐ๋œ๋Œ€๋กœ tls connection์—์„œ h2c upgrade๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ•น Tools

๐Ÿ“š Articles

๐Ÿ“Œ References

Licensed under CC BY-NC-SA 4.0
Last updated on Aug 28, 2021 00:48 +0900