8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

セキュリティ機構 SSP について(自分用メモ)

Last updated at Posted at 2019-03-29

はじめに

とあるCTF(Capture The Flag)の問題を解いている際にSSPに振り回されたため,次回以降の自分用メモぐらいのノリぐらいで書いて行こうと思います.間違い等ありましたら,ご指摘いただけると幸いです.

一応,出てくる話はLinuxでx86アーキテクチャを想定しています.

SSPとは?

IPAが発行した資料によると,SSP(Stack Smashing Protector)はバッファオーバーフロー攻撃を検出するためのセキュリティ機構だそうです.

SSPgccではデフォルトで有効であり,コンパイルの際に次のようにオプションをつけることで無効化することができます.

$ 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有効

SSP無効時のfunc()

SSP無効

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を回避される可能性もあるそうです.

まとめ

いままで,ちょこちょこ調べてたことをまとめました.
インターネット上にある様々な記事を参考にさせていただきました.ありがとうございます.

自分ではlarge gs:14hの部分がわからないため,どなたか教えていただきたいです.

  • 追記しました.

おそらくmaster canaryと関係していると考えています.

追記

コメントでColumbineさんからセグメントによるアドレス指定について教えていただきました.ありがとうございます.

この記事にあるようにcanaryの値を保存しているのだと思われます。(url1)
GSというのはGセグメントの事で、基底アドレス指定方式みたいにGSのアドレスに14hを足したアドレスを指しているようです。(url2)

参考

オープンソース・ソフトウェアの セキュリティ確保に関する調査報告書 - IPA
Improper Null Terminationを利用したSSP回避
byte-by-byte bruteforceによるSSP回避

8
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?