a first step towards automated detection of buffer overrun vulnerabilities

36
A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities 情情情情情情情情情 情情情 M1 情情 情 ([email protected] )

Upload: talbot

Post on 24-Jan-2016

39 views

Category:

Documents


0 download

DESCRIPTION

A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities. 情報理工学系研究科 米澤研 M1 田渕 直 ( [email protected] ). 概要. C 言語で書かれたプログラムに存在する、潜在的な Buffer Overrun バグをソースコードの static な解析によって検出する方法を提案する。. C プログラムの問題点. C 言語はいくつかの点で安全ではない 配列境界をチェックしない - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

A First Step Towards Automated Detection of Buffer Overrun

Vulnerabilities情報理工学系研究科 米澤研

M1 田渕 直 ([email protected])

Page 2: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

概要• C 言語で書かれたプログラムに存在す

る、潜在的な Buffer Overrun バグをソースコードの static な解析によって検出する方法を提案する。

Page 3: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

C プログラムの問題点• C 言語はいくつかの点で安全ではない

– 配列境界をチェックしない– 配列境界に無頓着なライブラリ関数の存

在e.g. gets(), strcpy(), etc…

– ライブラリ関数の仕様の不統一e.g. strncpy(d, s, sizeof d) ○ strncat(d, s, sizeof d) ×

Page 4: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

解決策の提案• 安全でない言語使用やライブラリの結果、

– 正しいプログラムを書くのは難しい。– 危険なプログラムはすぐに書ける。

• しかし、現実には Legacy な C 言語に頼らざるを得ない場面も多い。

⇒ 人手によらず、危険な個所を自動検出できるツールがあれば嬉しい。

Page 5: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

システムの特徴 (1/4)

• 静的解析 : C ソースプログラムの静的な解析に基づいて危険な個所を検出する。

• Scalability > Precision: 検出結果の過不足には目をつぶって、現実のアプリケーションに適用できる程度の性能を目指す。

• 対象 : 解析の対象は文字列 ( と文字列用ライブラリ関数 ) に限定。

Page 6: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

システムの特徴 (2/4)

• 静的解析– Runtime testing では全ての条件とパスをテス

トできるとは限らない。– 特に、セキュリティ上最も重要なコードは、

通常実行されることのないパスに潜んでいる。

e.g. if (strlen(src) > sizeof (dst)) break;strcpy(dst, src);

What if strlen(src) == sizeof (dst) ?

Page 7: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

システムの特徴 (3/4)

• C 文字列を抽象データ型として扱う– ポインタは一般に静的解析と相性が悪い。– ほとんどの buffer overrun は文字列バッフ

ァについて起こる。

⇒ 文字列とライブラリ関数の動作を直接モデル化することによって、ポインタの解析を回避する。ポインタを直接操作するようなコードは、誤りを検出できない。

Page 8: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

システムの特徴 (4/4)

• 「バッファ」のモデル化– 文字列バッファを「確保サイズ」・「文字

列長」の整数範囲のペアとしてモデル化

⇒ 文字列の内容を意識しない処理が可能。⇒ 問題を integer range constraint として定式化

できる。

Page 9: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

システムの制限• Scalability > Precision の構図に基づき、

以下の制限を設けた実装とした。1. 制御フローを無視。2. ポインタの解析はしない。3. 構造体は一括して扱う ( 次項 ) 。

Page 10: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

構造体の扱いについて• C の慣習として、構造体はポインタと

組み合わせて使われることが多い。• 構造体を無視しては実世界のアプリケ

ーションを検証することはできない。⇒ 同じ型の構造体のインスタンスは制約

システム中で全て一括して扱うという方針で、妥協的に解決した。

Page 11: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

アーキテクチャ

C parserInteger constraint

generationConstraint solver

Source

Syntaxtree

Const-raints

Warnings

Page 12: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の表現 (1/4)

• Integer range:integer range は Z∞ = Z {±∞} ∪ の部分集合で、 [m, n] = {m, …, n}

• Range closure: S Z⊆ ∞ に対し、 range-closure(S) = [inf S, sup S]

Page 13: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の表現 (2/4)

• Operations on range closure:S, T Z⊆ ∞ に対し、

S + T = range-closure({ s+t | s S, t ∈ ∈

T})S – T, S * T も同様に定義される。

• {n} を n と略記する。e.g. 2T = {2} * T = { 2t | t T}∈

Page 14: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の表現 (3/4)

• Integer range expression:e ::= v | n | n * v | e + e | e – e

| max(e, …, e) | min(e, …, e)where n Z, v ∈ は変数。

• Integer range constraint:制約は e v ⊆ の形に表される。

Page 15: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の表現 (4/4)

• Assignment:assignment α は、各変数 v に対しα(v) Z⊆ ∞ ( 実際には range) を割当てる。

• 定義 : α が制約システムを満たす⇔ constraint 中の各変数 v を α(v) で置き換えた時に、全ての constraint が成立。

• 定義 : α β ⇔ α(v) β(v) for v⊆ ⊆ ∀

Page 16: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の生成 (1/3)

• C ソースの構文木から、一連の constraint を生成する。– 整数変数 v に対し、変数 v を対応させる。– 文字列変数 s に対し、確保長 alloc(s) と

文字列長 len(s) を対応させる (* len(s) は‘ \0’ を含む ) 。

– 代入 v = e に対し、 e v ⊆ を生成。– 各文字列操作に対し、対応する制約を生成。

Page 17: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の生成 (2/3)

Code Interpretation

char s[n]; n alloc(s)⊆

strlen(s) len(s) - 1

strcpy(d, s); len(s) len(d)⊆

s = “foo”; 4 len(s), 4 alloc(s)⊆ ⊆

p = malloc(n) n alloc(p)⊆

strcat(s, suf); len(s)+len(suf)-1 len(s)⊆

文字列操作に対応する制約の例。

Page 18: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の生成 (3/3)

• 関数 f(int p) の呼出し b = f(a);

は p = a 、 b = f_return と解釈。• ポインタ操作

q = p+j;は alloc(p) – j alloc(q)⊆ 、len(p) – j len(q) ⊆ と解釈 (aliasing等を無視 ) 。

Page 19: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

制約の解決• 制約の解決は、全ての変数が取り得る値

の範囲をカバーする最小の bounding box を求めることに相当。

• 求まった bounding box から各 len(s) と alloc(s) の関係を見ることで overrun を検出。

Page 20: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

アルゴリズム (1/2)

• とりあえず f(vi) = avi + b v⊆ j の形の制約のみで考える。– 各 vi に頂点 vi を割り当て– 制約 f(vi) v⊆ j に対し、枝 vi →f vj を割り当

て。– 各 vi に対し α(vi) = φ

– 制約 n v⊆ i に対し、α(vi) = range-closure(α(vi) {n})∪

Page 21: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

アルゴリズム (2/2)

• 前項の初期化の後、グラフの枝に沿って情報を伝播させる。– f(α(vi)) ⊈ α(vj) であれば

α(vj) = range-closure(α(vj) f(α(v∪ i)))

• グラフが閉路を含んでいれば、その部分に関しては、別途直接計算で解を求める。

Page 22: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

擬似コード (1/2)

Constraint-Solver:Set α(vi) = φ for all i, done = falseFor each constraint of the form n w⊆

Set α(w) = range-closure(α(w) {n})∪While done = false call One-Iteration

One-Iteration:Set C(vi) = white for all i, done = trueFor each vi

if (C(vi) == white)Set prev(vi) = null, call Visit(vi)

Page 23: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

擬似コード (2/2)

Visit(v):Set C(v) = grayFor each constraint of the form f(v) w⊆

if (f(α(v)) ⊈ α(w)) Set α(w) = range-closure(f(α(v)) ∪ α(w)) Set done = false if (C(w) == gray)

Call Handle-Cycle(v, w, prev) if (C(w) == white) Set prev(w) = v, call Visit(w)

Set C(v) = black

Page 24: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

Overrun の検出• 制約の解決後、各 alloc(s), len(s) の関係から overrun を検出。

• alloc(s) = [a, b], len(s) = [c, d] として…1. b c overrun ≦ ⇒ は起こらない。2. a > d ⇒ 常に overrun が起こる。3. Otherwise overrun ⇒ が起こる可能性有り。

Page 25: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

性能評価• いくつかの実際に使用されているパッ

ケージに対してツールを適用し、性能評価を試みた。

• 人手でソースを解読して false alerm 率を測定。

Page 26: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

評価 1. Linux net tools

• Linux net tools に関して、今まで報告されていない問題を検出できた。– DNS ・ NIS の応答を信頼している個所が

あり、悪意のある応答に対して脆弱。• 既知の問題をどの程度検出できたかに

ついては言及がなかった。

Page 27: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

評価 2. Sendmail 8.9.3 (1/2)

• 既知の問題の多さ、プログラム規模等の面で sendmail は良い題材である。

• セキュリティホールは検出されなかったが、 queue の扱いに関して小さな off-by-one バグを検出した。

• False alerm 率の高さのため、人手による検証に多くの時間がかかった。

Page 28: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

評価 2. Sendmail 8.9.3 (2/2)

• False alerm の例1. if (sizeof dst < strlen(src)+1) break;

strcpy(dst, src);

2. char* ptr;if (A) ptr = “abc”;else ptr = “defgh”;

→ 制御フローを無視することによるもの。

→ bounding box 解析の原理上の制限。

Page 29: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

評価 3. Sendmail 8.7.5

• 公表されていない数多くのバグを検出した。

• chfn に関する既知の問題は検出できなかったらしい。

Page 30: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

パフォーマンス• Sendmail の検証にかかった時間は

Pentium III で 15 分程度。• 検証結果を人手で確認する手間の方が大きいので、 CPU時間はそれほど問題にならないのではないか。

Page 31: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

問題点• 現在のシステムの主な問題点は ,

– False alerm の多さ– 検出ミスの可能性– 出力の情報量不足

Page 32: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

False alerm の多さ (1/2)

• Precision を犠牲にした設計のため、実際には問題のないコードが引っかかることが多く、結局人手での検証に負担がかかる。

e.g.Sendmail の検証では Probable とされた 44箇所のうち、 40箇所が false alerm だった。

Page 33: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

False alerm の多さ (2/2)

• 解析手法の強化でどの程度精度が向上するかを見積もった。– 制御フロー– ポインタ解析– 文脈の情報– Linear invariants

手法 結果フロー 19/40

フロー +ポインタ

25/40

フロー + 文脈 + inv.

28/40

全部 38/40

⇒ もう少し精度を重視しても良かったかもしれない。

Page 34: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

検出ミスの可能性• 検出ミスの数を完全に見積もることは

難しい。• Sendmail 8.7.5 の検証では…

chfn に関するバグは検出できなかった ( ポインタを直接操作していたため ) 。その他の、未公表のまま修正されていた問題は全て検出した。

Page 35: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

出力の情報量不足• ツールの報告は「どのバッファが溢れるか」

のみ。「どこで溢れるか」は示されない ( 制約に基づくシステムの原理的な限界 ) 。

⇒ 「バッファ溢れに関係する変数名を同時に報告する」というヒューリスティクスを採用して、多少の改善を試みた。

Page 36: A First Step Towards Automated Detection of Buffer Overrun Vulnerabilities

結論• Buffer overrun の静的解析技法として、 2 つの

アイデアを提案した。– 文字列のモデル化– 制約に基づく解析

• このアプローチは十分に有効で実用的。• 精度を犠牲にして、大きなプログラムに適用

できるだけの scalability を達成できた。• 人手では発見できない小さなバグも発見でき

た。• 精度に関しては改善の余地がある。