Document

Windowsシステムの
Exploitにおける環境依存性
Environment Dependencies in Windows Exploitation
Yuji Ukai , Senior Software Engineer
Derek Soeder, Software Engineer
Ryan Permeh, Senior Software Engineer
http://www.eeye.com
はじめに
脆弱性情報が公開されると・・・
Exploit公開
Exploit改良
Worm
Worm化される脆弱性には、多くの場合、共通する
様々な危険要素がある。
極力初期の段階からこれら危険要素を見極めるため、
的確な脅威分析が重要。
はじめに - 脅威分析
的確な脅威分析のためには・・・
脆弱性の詳細かつ正確な技術的分析
(攻撃の種別、攻撃ベクタ、安定性、再現容易性、権限など)
影響範囲
公開されている情報量
主なexploit developerやworm writerの現在の動向、技術力
攻撃のトレンド
等総合し判断する必要がある。
全てのステージで的確な分析が必要
はじめに – 環境依存性
Exploit、worm等には環境依存がある可能性がある
- 特にBuffer Overflowなどマシンコード実行型
日本語環境に有効なら、日本にとって更なる脅威となる
特にwormの場合、環境依存回避がどのような形で行
われているかで、世界的な影響をある程度予測可能
「環境依存」にフォーカス
現状の環境依存回避の実態は?
環境依存回避は本来どこまで可能なのか?
対応策は?
Environment Dependencies
環境依存性
1
環境依存性 – 概要
[環境依存]
ある特定のexploitやworm等の有効性が、対象の「環境」によって
左右される現象
環境(例)
•対象OSのメジャー、マイナーバージョン
•対象アプリケーションのバージョン
•言語バージョン
環境依存性 – 事例 (1)
MS03-026 – Blaster Worm
(出典:JP Vulnerability Notes)
2003-07-27 BugTraq ML
“DCOM RPC exploit (dcom.c)” が投稿される
2003-07-31 Full-Disclosure ML
“RPC DCOM universal offsets” が投稿され
る
日本語環境に影響
2003-08-11
Blaster Worm発生。日本語環境にも影響
環境依存性 – 事例 (2)
MS04-011 – Sasser Worm
2004-4-25 : Full-Disclosure ML (k-otik)
DsRoleUpgradeDownlevelServer ()APIコード書き換え
・日本語版Windows2000
・日本語版WindowsXP
: 有効
: 無効
2004-4-29 : Full-Disclosure ML (SecurityLab)
LSADS DCE/RPCパケットをsocket()で送信
・日本語版Windows2000
・日本語版WindowsXP
: 無効
: 有効
Sasser
環境依存性 – 発生原因
Stack Based
Buffer Overflow Exploit
user32.dll=0x77E10000
user32.dll=0x77DE0000
JMP ESP
Return Address
ESP
JMP ESP
・ DLLベースアドレス相違
・ DLLコード相違
環境依存
0x77E09EB8
環境依存性 – 回避法とその対策
ExploitやWormで良く利用される環境依存回避法
•共通リターンアドレス
•Version検出+アドレステーブル
•Brute forcing+アドレステーブル
環境依存回避の回避
•環境依存回避に繋がるヒントを与えない
•環境依存回避を本質的に無効化
潜在的なリスクを除去する
Common Return Address
共通リターンアドレスによる
環境依存回避とその対策
2
共通リターンアドレス ー 定義
多くの種類の環境で共通して利用可能なリターンアドレス
最も脅威となるリターンアドレスは、
•全ての言語バージョンで利用できる
•全てのメジャーバージョンで利用できる
•全てのサービスパックレベル、パッチレベルで利用できる
共通リターンアドレス ー 組み込み事例
2004-4-29 (SecurityLab)
FullDisclosure: MS04011 Lsasrv.dll RPC buffer overflow
remote exploit (PoC) with Universal targets
このExploitは、実際は“Universal”ではなかった
共通リターンアドレス ー 潜在的な脅威
少なくとも、
・ 全言語バージョン
・ 全サービスパックレベル、全パッチレベル
で利用できるリターンアドレスは・・・
存在するのか、しないのか?
・ 存在していれば、wormに利用される前に潰す必要あり
・ 存在しないなら、 “完全Universal”は存在しないことが証明される
共通リターンアドレス ー 対象
共通リターンアドレスとなる対象
ESPが示すアドレスにジャンプする場合・・・
従来の手法
しかし本来は・・・
• JMP ESP
• PUSH ESP / RET
• MOV ECX,ESP / JMP ECX
• MOV EAX / JMP ESP
・・・・ 組み合わせは限りなく存在する
単純なバイト列の検索では全てを検出できない
★ バイト列を「命令として解釈」しながら検索する必要がある
★ RET実行時の“Context”を考慮する必要がある
EEREAP
- eEye Emulating Return Address Purveyor
Context-Awareなマシンコード・エミュレーション
を用いたReturn Address Finder
EEREAPer
© Derek Soeder@eEye
EEREAP ー 目的
共通リターンアドレスの有無を明らかにしたい
― 共通リターンアドレスの存在を検証する実装は無かった
■ 存在していれば、wormに利用される前に潰す必要あり
* 潜在的な脅威
* 対策を実装するために非常に強力なツールとなる
■ 存在しないなら、 “完全Universal”は存在しないことが証明される
* 「存在するかもしれない」という「可能性の脅威」が一人歩き
* 存在しないなら、「可能性として語られていた脅威」は消滅
EEREAP ー 概要
・IA32エミュレータ
・仮想記憶マネージャ
対象プロセス
・レジスタ情報
・メモリスナップショット
・最大検索命令数
EEREAP
0x71234412
0x712A5123
0x714E0234
0x73A1BA02
:
:
・ コードセクション内で全ての候補をリストアップする
・ ESPへのジャンプだけでなく、特定バッファへのジャンプは全て対応
(Heap Based Buffer Overflow、Format String Bug等にも利用可能)
EEREAP ー レジスタ情報
各レジスタのビットレベル値 {0,1,X}
(例)
# STACK : 64KBの書き込み可能なメモリエリア
STACK @ 00XXXXXXh : 65536, RW
# ESP : ‘STACK’ + オフセットE000H
ESP = STACK + E000h
# BUFFER : ‘STACK’ + オフセットE09CH → TARGET (Read Only)
BUFFER @ STACK + E09Ch : 128, TARGET, RO
# ‘STACK’ + オフセットE004Hには‘BUFFER’へのポインタが存在
[STACK+E004h] = BUFFER + 8
EAX = 0
ECX = 3FFXXXXXh
EBP = STACK + E134h
ESI = STACK + E01Ch
TIB @ 7FFXX000h : 4096, RW
FS = TIB
EFLAGS = 0010000X0X1Xb
EEREAP ー メモリスナップショット
C:\>psnap.exe --priority --suspend -a:r -c:w 260 lsass.ees
* Record:
* Write:
micdhstp ----c----- ---
[#] 00010000..00010FFF
[#] 00020000..00020FFF
[ ] 00030000..00065FFF
[G] 00066000..00066FFF
[#] 00067000..0006FFFF
[#] 00070000..00120FFF
[ ] 00121000..0016FFFF
...
[#] 00CAA000..00CAFFFF
[#] 01000000..01000FFF
[#] 01001000..01001FFF
[#] 01002000..01002FFF
[#] 01003000..01009FFF
[ ] 01090000..010C8FFF
[G] 010C9000..010C9FFF
...
Saved process 260 snapshot
.................................. Recorded
.................................. Recorded
................................... Ignored
................................... Ignored
.................................. Recorded
Heap .............................. Recorded
Heap ............................... Ignored
Stack
Image
Code
Data
Data
Stack
Stack
............................. Recorded
- lsass.exe ................ Recorded
- lsass.exe:.text ........... Written
- lsass.exe:.data .......... Recorded
- lsass.exe:.rsrc .......... Recorded
.............................. Ignored
.............................. Ignored
to "lsass.ees" (12795328 bytes).
EEREAP ー 動作
• コードセクションのトップから検索開始
• 一つのアドレスからのエミュレーションごとにリフレッシュ
• 最大検索命令数に到達すると停止(永久ループ対策)
• EFLAGS/ECX未定義時の条件分岐/ループ
- 両方の子threadがターゲットに到達したら親を成功とみなす
- 両方の子は親のContextをそのまま継承
- 残り検索命令数は子同士で等分する
• 例外(アクセス違反、特権命令実行、無効命令実行、0除算など)が発
生すると停止
EEREAP ー 適用手順
• ターゲットをデバッガにattachしておく
• 脆弱性を利用してクラッシュさせる
- 可能な限り実行hijack時に状態に近い状態でクラッシュさせる
(EIP=0x41414141など)
• メモリスナップショットを作成する
• クラッシュ時の状況を分析してContext情報を作成する
MS04-011
LSASS脆弱性
Windows2000
Advanced Server
SP4
STACK = 0XXXA000H:6000H,RW
BUFFER@STACK+5A14H:10H,RO,TARGET
EAX=00000000H
EBX=00000000H
ECX=STACK+5D38H
EDX=785B2C60H
ESI=00000004H
EDI=STACK+5A58H
ESP=STACK+5A14H
EBP=XXXXXXXXH
EFLAGS=0296H
EEREAP ー 適用
プロセス
LSASS.EXE
MS04-011 : LSASSの脆弱性
EEYE : Windows Local Security Authority Service Remote Buffer Overflow
プラットフォーム
• Windows 2000 Advanced Server (English) SP0 ~ SP4
• Windows 2000 Advanced Server (日本語) SP0 ~ SP4
EEREAP ー パフォーマンス
EEREAP vs “Simple Search” - JMP ESP/CALL ESP/PUSH ESP&RET
検出したリターンアドレス数の比較
EEREAP ー 適用結果
ターゲットバッファまでの命令数の分布例 (SP4 英語版)
# Instructions
Addresses
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 or more
Total
最大命令数 = 91
59
63
90
90
106
100
57
54
30
20
22
13
11
5
104
824
共通リターンアドレス ー その存在
Windows 2000 Advanced Server LSASS
英語版
SP0 ~ SP4 共通
アドレス数=19
日本語版
SP0 ~ SP4 共通
アドレス数=24
Printable = 3
日本語版、英語版
SP4 共通
アドレス数 = 207
Printable = 18
Alpha-Numerical = 2
共通リターンアドレス ー 対処
(1) dllベースアドレスの変更
(2) JMP ESP命令を含むサブルーチンの移動
詳細は後ほど・・・
Common Return Address
Version検出による
環境依存回避とその対策
3
Version検出 – 概要
• 対象システムの環境を自動で判別できれば、それに合わせた
攻撃を自動的に行う事ができる
• 各環境ごとにリターンアドレス・テーブルを作っておけば
Universal Exploitを実現する事が可能
• Exploitに利用可能な「バージョン情報」判定
(ex. “Windows 2000 SP4 日本語版”)
• Version検出の無効化とその有効性、問題点
Version検出 - Active検出
攻撃者(Exploit等)が能動的に対象のバージョンを判定する
脆弱性スキャナでよく利用されるOSのバージョン検出手法は・・・
・TCP OS Finger Printing (NMap)
・ICMP OS Finger Printing
・SNMP
・SMB (SessionSetupAndX Reply)
・Workstation Service (NetWkstaGetInfo API)
・DCE/RPC IfID リスト
・その他サービス(HTTP、TELNETなど)のバナーを利用
Version検出 - Active検出の無効化
SMB (SessionSetupAndX)
収集可能情報
OSメジャーバージョン
対応策
・ フィルタリング
Workstationサービス (NetWkstaGetInfo)
収集可能情報
OSメジャーバージョン、言語バージョン
対応策
・ 匿名アクセスの禁止
・ フィルタリング
・ Workstationサービス停止
DCE/RPC IfID リスト
収集可能情報
OSメジャーバージョン、SPレベル
対応策
・ フィルタリング
Version検出 - Passive検出
・Webブラウザやネットワーククライアント等を対象とした受動的攻撃
・攻撃用マシンをネットワーク上にホストするタイプの脆弱性
被攻撃者
Version情報
攻撃者
攻撃コード
• Internet Explorer
アプリケーションバージョン、OSメジャーバージョン、言語バージョン
• Apple Quick Time Player、iTunes
アプリケーションバージョン、OSメジャーバージョン、SPレベル
Version検出 - Passive検出の無効化
webブラウザ
+
SPレベルを通知する
アプリケーション
=
詳細な
バージョン情報
リターンアドレステーブルを参照して攻撃コードを生成する事で、
強力な環境依存回避が可能
・セキュリティポリシーに反映
・Proxy Serverで情報を削除
・アクティブスクリプト、Active Xコントロールの実行を通常は無効に
Common Return Address
Brute Forceによる
環境依存回避とその対策
4
Brute Force環境依存回避 - Active
• リターンアドレステーブルを用意し、ランダム、あるいは順にセット
• 一度クラッシュしても再起動するものなら適用可能
• 手荒であるがVersion検出が不要。Version検出対策を回避可能
[比較事例]
Blaster
80%の確率でWindowsXP、20%の確率で
Windows2000のリターンアドレスを選択。
Sasser
SMBバナーによるメジャーバージョン検出
があった。
Brute Force環境依存回避 - Passive
• リターンアドレステーブルに存在する全てのパターンを用意
• 対象のクライアントを複数起動させ、全てを一度に処理させる
被攻撃者
×
×
SP1
SP2
○
×
SP3
SP4
攻撃者
Brute Force環境依存回避 - 対策(?)
•
•
攻撃が荒っぽいため気付きやすい
しかし、特にPassiveでは根本的な対策をとるのは難しい
そもそも
Brute Force攻撃が可能な場合、Version検出回避は一時凌ぎなのでは?
根本的な対策は?
自分の環境がテーブルに無いなら、少なくとも自分はやられない
Common Return Address
特殊化による
環境依存性回避対策
5
環境の特殊化 – 概要
• バージョン相違による環境依存は、それ自体がある種の防御機構と
なっていた。
• しかし、共通リターンアドレス、バージョン検出、Brute force等、環境
依存回避を可能にする要因がある。
• また、言語バージョンの違いによる偶発的な環境依存は、逆に特定
の国を狙ったサイバーテロなどに利用される危険性がある。
各対象ごとに「環境」を変化させ、特殊化する
環境の特殊化 ー アプローチ
* UNIX用アプリケーション(delegate)
スタックトップを起動ごとに変動。Shellコードへのジャンプを無効に。
* しかしWindowsでは・・・
対象スレッドのスタックトップは変動。よって、JMP ESP手法が主流に。
特殊化のアプローチは・・・
(1) JMP ESPアドレスの利用を困難にさせる
(2) JMP ESP命令を実行させない
環境の特殊化 ー DLLベースアドレス
DLLのベースアドレスを変更する事で、 JMP ESPアドレスの利用
を困難にさせる事ができる
開発側
• DLLベースアドレスを、起動するた
びに変化させる
• インストールごとに乱数を加味した
衝突のないマップを作成し、
ベースアドレスを変化させる
名前、種別
A-C
D-F
G-I
J-L
M-O
P-R
S-U
V-X
Y-Z
System DLL
アドレス
0x60000000
0x61000000
0x62000000
0x63000000
0x64000000
0x65000000
0x66000000
0x67000000
0x68000000
0x70000000-0x78000000
Microsoft推奨ベースアドレス
環境の特殊化 ー DLLベースアドレス
ユーザー側
• DLLベースアドレスを任意の値に変更する
• Windows システムDLLは・・・
1) EEREAPを使用して移動すべきDLLを特定
2) REBASE.EXEを使用して移動
環境の特殊化 ー DLLベースアドレス
[例:Lsasrv.dllのベースアドレスを変更]
1.
2.
3.
4.
5.
6.
7.
8.
REBASE.EXEを用意する (Visual Studio等に同梱)
Safe Mode + Consoleでシステムを起動する
copy lsasrv.dll temp.dll
REBASE –b 0x14000000 temp.dll (任意のアドレス)
LSASS.EXEを強制終了
copy temp.dll dllcache\lsasrv.dll
copy temp.dll lsasrv.dll
再起動
EEREAPを使って、可能性のある全てのDLLを移動
環境の特殊化 ー API Hook
EEREAPを使って、JMP ESP命令を含むサブルーチンを列挙。
サブルーチンを移動し、JMP ESP命令を実行させない。
関数入口
関数出口
JMP hook
Func A
90 90 90 90
90 90 90 90
90 90 90 90
・・・
Func A
JMP ESP
NOP
JMP ESP
別アドレス
exception
JMP ESPはNOPに置き換わり、最終的にexception発生
まとめ
• 環境依存の有無は脅威度に大きく影響
• 環境依存回避は多くの脆弱性で可能
• 潜在的なリスクをなくすためにも、環境の特殊化は有効
今後の課題
• EEREAPをより使いやすく改良、システム管理者、アプリ開発者、
セキュリティ技術者向けに無償配布したい。
• EEREAPをworm製作者などに悪用されないための仕組み作り。
Question ?
Contact : [email protected]
Thank you for your attention !
EEREAP Project Researchers :
・Yuji Ukai, Senior Software Engineer, eEye Digital Security
・Derek Soeder, Software Engineer, eEye Digital Security
・Ryan Permeh, Senior Software Engineer, eEye Digital Security
EEREAP Contact : [email protected]
Black Hat Japan 2004
Oct. 14-15, 2004, Tokyo
Yuji Ukai - eEye Digital Security