DynPTA: Combining Static and Dynamic Analysis for Practical Selective Data Protection [SP’21]
github: https://github.com/taptipalit/dynpta
調査の目的
- 選択的データ保護のやり方
概要
- 問題
- データ漏洩,Transient Execution Attack(Spectre攻撃など)の脅威は強まっている.
- 既存の保護手法は
- コードを大きく変更する必要がある
- 大きなアプリに対してスケールしない
- 困難: scalability + データ漏洩への保護の両立
- 提案手法
- ポインタ解析と動的data-flow tracking(DFT)を組み合わせてsensitiveデータを推論
- sensitiveデータの暗号化によってデータ漏洩の被害を抑える
- 実験結果
- リアル検体に対して
- Heartbleedによるデータ漏洩を検知
- Spectre攻撃によるデータ漏洩を検知
- Runtime overhead: <= 19.2%
- リアル検体に対して
背景: Pointer Analysis
- 有名なポインタ解析
- Andersen: O(n^3)
- Steengard: O(n)
- 巨大なプログラムに対して,Andersenですら適用できない場合がある.
- Nginx: 11 hours
- Chromium browser: ran out of memory after running four days
- Andersen vs. Steengard
- Andersen: inclusion-based
- 要素を一個一個追加していく
- Steengard: unification-based
- 集合の和を取る
- Andersen: inclusion-based
手法
- 静的解析
- sensitiveデータの特定
- Annotation
- sensitiveデータへのアクセス命令の特定
- Steengardポインタ解析
- Value-Flow解析
-
malloc-wrapper関数の特定
- `return ptr`である関数に対して,mallocなどで新しく確保されるobjectが返されているのかを判定
- context-sensitive heap modelingと謳っているが,Summaryを使った部分的context-sensitivity
- `1: a = mem_alloc();`と`2: b = mem_alloc();`をSummaryから別々のobjectが確保されたと判別できる
- scalableだが,coarseな解析
- sensitiveデータの特定
- 動的解析
- sensitiveデータの暗号化・復号
- 静的解析でsensitiveデータへアクセスするかもしれない命令に対して
- 書き込み: 暗号化して書き込み
- 読み込み: 復号して読み込み
- 静的解析でsensitiveデータへアクセスするかもしれない命令に対して
- coarseな静的解析によって絞られた一部の(scoped)命令に対してのみ,確認・暗号処理を行う
- sensitiveデータの暗号化・復号
以下のコードにおいて,priv_key
を保護する流れを追う.
char* ptr;
char* priv_key = malloc_wrapper(8);
// calculate priv_key
ptr = priv_key;
...
char* pub_key = malloc_wrapper(8);
// calculate pub_key
ptr = pub_key;
...
静的解析
- プログラマがsensitiveデータにannotationをつける
priv_key
にannotate
- malloc-wrapper関数の候補を見つけ,Intra-proceduralポインタ解析により特定する
malloc_wrapper()
- Steengardポインタ解析により,sensitiveデータを指しうるポインタを求める
- malloc-wrapper関数においては,異なる呼び出しでは異なるobjectを確保すると解析する(context-sensitive heap modeling)
- 例では,{
ptr
,priv_key
,pub_key
}がsensitiveデータo1
を指す ```c char* ptr;
char* priv_key = malloc_wrapper(8); // o1 mark_sensitive(priv_key); // calculate priv_key ptr = priv_key; …
char* pub_key = malloc_wrapper(8); // o2 // calculate pub_key ptr = pub_key; …
4. Value-Flow解析により,sensitiveデータに関するValue-Flowをsoundに求める
5. Potential sensitive instruction(sensitiveデータにアクセスしうる命令)にメタデータを付け,実行時の目印とする
- 例では,全命令が該当
まとめ:
- sensitiveデータを特定
- Potential sensitive instructionsを特定
### 動的解析部分 Dynamic Flow Tracking(DFT)
6. Shadow memoryを用意し,annotationの付いたsensitiveデータに対してShadow memoryの該当箇所に印(taint)をつける

7. Potential sensitive instructionに対して,以下の処理を行う:
- Load: Shadow memoryにtaintが付いている場合,読み込むデータにtaintを付け,**復号**
- データの復号
- Store: taintが付いているデータを書き込む場合,Shadow memoryにtaintを付け,**暗号化**して書き込む
- データの暗号化
- Others: (top-variableに対して) taintの伝播処理を行う
- テイントの伝搬
例では,
- `o1`はテイントされ,暗号化される
- `o2`はテイントされず,保護されない
```c
char* ptr;
char* priv_key = malloc_wrapper(8); // o1
mark_sensitive(priv_key);
// calculate priv_key
ptr = priv_key;
...
char* pub_key = malloc_wrapper(8); // o2
// calculate pub_key
ptr = pub_key;
...
まとめ:
- Potential sensitive instructionが本当にsensitiveデータにアクセスするかをチェック
- sensitiveデータは暗号化してメモリに置く
実験結果
- パフォーマンス評価
Application | Protected Data | KLOC | Bitcode Size | DynPTA Compilation | Runtime Overhead |
---|---|---|---|---|---|
Nginx + OpenSSL | Private key | 389 | 8M | 50.6 min | + 17.92% |
Httpd | Password | 179 | 3.7M | 11.0 min | + 1.86% |
Lighttpd + ModAuth | Password | 83 | 1.9M | 2.8 min | + 1.87% |
MbedTLS server | Private Key | 54 | 726K | 1.3 min | + 4.08% |
OpenVPN | Private Key | 329 | 3.5M | 59.1 min | + 9.81% |
Memcached + Auth | Password | 71 | 1.1M | 1.0 min | + 0.32% |
ssh-agent | Private Key | 52 | 640K | 1.3 min | + 3.15% |
Minisign | Private Key | 45 | 1.2M | 37 sec | + 22.02% |
- 保護能力評価
- Heartbleed: data leakageを全て防げた
- Spectre: data leakageを全て防げた
自分の研究との関連
- 選択的データ保護
- 保護すべきデータは異なる
- データ漏洩: データがどこへ流れるか(テイント解析)
- integrity: データへ影響を与えるか(制御/データ依存解析)
- 動的テイント解析により,本当に保護すべきデータかどうかを判定するやり方は参考になる
- 保護すべきデータは異なる
- 暗号化によるデータ保護
- Transient execution attack(Spectre攻撃)に対する保護として有効