はじめに
とあるCTF(Capture The Flag)の問題を解いている際にSSP
に振り回されたため,次回以降の自分用メモぐらいのノリぐらいで書いて行こうと思います.間違い等ありましたら,ご指摘いただけると幸いです.
一応,出てくる話はLinuxでx86アーキテクチャを想定しています.
SSPとは?
IPAが発行した資料によると,SSP
(Stack Smashing Protector)はバッファオーバーフロー攻撃を検出するためのセキュリティ機構だそうです.
SSP
はgcc
ではデフォルトで有効であり,コンパイルの際に次のようにオプションをつけることで無効化することができます.
$ gcc -fno-stack-protector test.c
仕組み
SSP
が有効な実行ファイルでは,関数呼び出し時にカナリア(以下「canary」)
と呼ばれる値がローカル変数とリターンアドレスの間に挿入され,関数終了時にcanary
が変更されていないかチェックする機能が追加されます.そうすることで,ローカル変数が予め用意されたバッファの大きさを溢れても,canary
が上書きされるため関数の処理前後でcanary
の値を比較することでバッファオーバーフローを検知することができます.
SSPありとなしのスタックの状態を示します(退避されたebpの値などは省略しています).
- SSPなし
スタック |
---|
・・・ |
ローカル変数 |
リターンアドレス |
・・・ |
- SSPあり
スタック |
---|
・・・ |
ローカル変数 |
canary |
リターンアドレス |
・・・ |
## canaryの特徴 1. `canary`の最初の1バイトは必ずNULL文字(0x00)となる.
これは,NULL文字終端しない文字列操作などでcanaryの値が漏れることを防いでいます. 2. 実行ファイルが再起動するたびcanaryの値は変化する.
逆の言い方をすると再起動するまでは変化しないとも言えます.この特徴が弱さにつながることもあります.
手元で確認してみる
次のサンプルコードを-fno-stack-protector
オプションありとなしでコンパイルし,実行ファイルにどのような違いが出るのか調べてみます.
#include <stdio.h>
void func(void) {
char buf[16];
fgets(buf, 16, stdin);
puts(buf);
}
int main(void) {
func();
return 0;
}
ディスアセンブル結果は次のようになりました.
SSP有効時のfunc()
SSP無効時のfunc()
SSP有効時と無効時の画像を比較すると,有効時には___stack_chk_fail
の処理が存在することに気が付きます.これは,canary
の値が変化していた場合に呼び出されます.まず,0x080484C1~0x080484C7
の部分でスタックにcanary
がセットされます.今回はlarge gs:14h
からebp+var_C
にセットされます.そして,関数終了時の0x080484F3~0x080484F6
の部分でcanary
の値が変化していないかチェックします.ebp+var_C
からレジスタeaxに値を取り出しeaxとlarge gs:14h
とxorをとります.xor(排他的論理和)は同じ値でをとると0となるという特徴があります.同じ値,つまり変化しなかった場合は処理が0x08048504
にジャンプするという流れになっています.
SSPの弱点
SSP
はバッファオーバーフローを利用した攻撃を防ぐことができます.しかし,万が一canary
の値がわかるとSSPを回避される可能性もあるそうです.
-
canary
をリークさせる方法
Improper Null Terminationを利用したSSP回避 -
ブルートフォースで
canary
を特定する方法
byte-by-byte bruteforceによるSSP回避
まとめ
いままで,ちょこちょこ調べてたことをまとめました.
インターネット上にある様々な記事を参考にさせていただきました.ありがとうございます.
自分ではlarge gs:14h
の部分がわからないため,どなたか教えていただきたいです.
- 追記しました.
おそらくmaster canary
と関係していると考えています.
追記
コメントでColumbineさんからセグメントによるアドレス指定について教えていただきました.ありがとうございます.
この記事にあるようにcanaryの値を保存しているのだと思われます。(url1)
GSというのはGセグメントの事で、基底アドレス指定方式みたいにGSのアドレスに14hを足したアドレスを指しているようです。(url2)
参考
オープンソース・ソフトウェアの セキュリティ確保に関する調査報告書 - IPA
Improper Null Terminationを利用したSSP回避
byte-by-byte bruteforceによるSSP回避