「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>SC:システム開発]]

*目次 [#jbfad9b0]
#contents

*概要 [#ya4d6d14]
-C/C++のバッファ・オーバーフロー(BOF)系の対策

-言語使用として、全体的にBOF系に弱い。
--終端ナル(NULL)文字を忘れると、終端が認識されずBOFに繋がる。
--以下の様に、BOFを引き起こす可能性がある引数チェックされない関数が多い。

-以下の2つがある

--スタックベースのバッファ・オーバーフロー
---基本こちら
---呼び出し元に戻るアドレス部分を書き換え攻撃コードに誘導する。

--ヒープベースのバッファ・オーバーフロー~
スタックベースと比べ、攻撃が成功し難い。

*詳細 [#ve4ce9d9]

**データ実行防止機能(DEP) [#n726a699]
-データ領域からコードを実行することを防止する。
--Microsoft Windowsに搭載されているセキュリティ機能。
--ハードウェアDEP、ソフトウェアDEPがある。

-DEP対策として、return-to-libc攻撃がある。

**コンパイラに依る対策 [#vb4ab419]
開発環境やコンパイラによってはサポートされないことがある。

***SSP(Stack Smashing Protection) [#kd81c5b2]
-スタックフレーム内のebpレジスタとローカル変数の間に~
canary(カナリア・コード)を配置することで、スタック・オーバーフローの検知を行う。

-元となった実装の名前からStackGuardやProPoliceとも呼ばれることがある。

***ASLR(Address Space Layout Randomization) [#ca2c02b4]
-[[各種領域>#l983b52e]]をメモリ上にランダムに配置。
-コレにより、return-to-libc対策になる。

***PIE(Position Independent Executable) [#ud5d6ff9]
ASLRに加え、text領域のランダム化も行う(Full-ASLRとも言う)。

***AF(Automatic Fortification) [#b027012c]
脆弱性の原因となるような関数をコンパイル時に~
別の安全性の高い同じ機能を持つ関数へと置換する。

**BOFを起こす関数 [#u5e6e8fb]
以下の様に、BOFを引き起こす可能性がある引数チェックされない関数が多い。

***関数一覧 [#s9c7a7ad]
|#|関数|代替案/対策|用法|備考|h
|1|char *gets(char *s)&br;標準入力から一行を取り込む。|char *fgets(char *s, int n, FILE *stream);|fgets(dst , sizeof(dst) , stdin);|gets と異なり&br;・引数に最大読み込み文字数を指定する。&br;・改行文字も 1文字として数える。&br;・実際読むのはn-1で最後は終端ナル(NULL)文字になる。&br; ・終端記号は、末尾の改行を置換ではなく改行の後ろに付与&br; ・最大文字数を超えた場合でも終端ナル(NULL)文字を保証|
|2|char *strcpy(char *dst, const char *src);&br;src文字列をdst文字列バッファに'\0' までコピー|void *memset(void *buf, int ch, size_t n);&br;char *strncpy(char *dst, const char *src, size_t n);|memset(dst, 0 , sizeof(dst));&br;-> strncpy(dst, src, sizeof(dst) - 1);|・コピーされる文字の長さは、src長とnのいずれか小さい方。&br;・src長がnより短い場合、終端ナル(NULL)文字を保証|
|3|char *strcat(char *dst, const char *src);&br;src文字列をdst文字列バッファに'\0' まで連結|char *strncat(char *dst, const char *src, size_t n);|strncat(dst, src, sizeof(dst) - strlen(dst) - 1)|・文字列連結される文字の長さは、src長とnのいずれか小さい方。&br;・src長がnより短い場合、終端ナル(NULL)文字を保証|
|4|int sprintf(char *dst, const char *format, ...);&br;可変個引数をstring.Format()的に処理しdst文字列バッファに格納。|-|sprintf(dst, ”%.{B}s”, data)|{B} = 書式指定子の精度(最大文字数)&br;= dstの要素数 - 書式指定子以外の文字数 - 1(終端ナル(NULL)文字)|
|5|~|int snprintf(char *dst, size_t n, const char *format, ...);|snprintf(dst, sizeof(dst), ”%s”, data)|動作としては、fgets()に近く、実際読むのはn-1で最後は終端ナル(NULL)文字になる。|
|6|int scanf(const char *format, ...);&br;標準入力から空白、タブ、改行で分割された文字列を読みstring.Format()的に処理し格納可変個引数に格納。|-|scanf(”%.{B}s”, dst)|{B} = 書式指定子の精度(最大文字数)&br;= dstの要素数 - 書式指定子以外の文字数 - 1(終端ナル(NULL)文字)|
|7|int sscanf(char *src, const char *format, ...);&br;src文字列をstring.Format()的に処理し格納可変個引数に格納。|-|sscanf(src, ”%.{B}s”, dst)|{B} = 書式指定子の精度(最大文字数)&br;= dstの要素数 - 書式指定子以外の文字数 - 1(終端ナル(NULL)文字)|
|8|int fscanf(FILE *fp, const char *format, ...);&br;ストリームをstring.Format()的に処理し格納可変個引数に格納。|-|fscanf(fp, ”%.{B}s”, dst)|{B} = 書式指定子の精度(最大文字数)&br;= dstの要素数 - 書式指定子以外の文字数 - 1(終端ナル(NULL)文字)|
|9|getchar();, fgetc(fp);, getc(fp);&br;入力から一文字を取り込む。|-|-|使用する際にバッファ境界チェックを行う。|

***パターン [#m733e03a]
-何れもdstのサイズを調査して長さを指定する。
--基本的には、n = dstのサイズ - 1(終端ナル(NULL)文字用)
--指定先は、size_tか、書式指定子の精度(書式指定子の場合、更に書式指定子以外の文字列数を引く)になる。
--関数によっては(fgets、snprintf)、入力を自動的にn-1するものもあり、「- 1」が不要。

-va_listを使用する関数も基本的対応は同じ。
--vscanf → scanf
--vsscanf → sscanf
--vfscanf → fscanf
--vsprintf → sprintf

***パラメータ検証 [#z0f8b9e7]
-[[CRTセキュリティ強化>https://techinfoofmicrosofttech.osscons.jp/index.php?VC%2B%2B%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%83%E3%83%97#t697e5f8]]

-Libsafe
--BOFをチェックするコードを読み込ませた後に
--本来呼び出されるライブラリの内容を呼び出す。
--チェック関数挿入、コンパイル不要

**まとめ [#se2ae8df]

***OS [#h8f8d15a]
[[データ実行防止機能(DEP)>#n726a699]]

***[[コンパイラに依る対策>#vb4ab419]] [#z493d2c9]
-[[StackGuard、canary(カナリア・コード)>#kd81c5b2]]
-メモリ配置のランダム化([[ASLR>#ca2c02b4]]、[[PIE>#ud5d6ff9]])

***プログラミング [#c56c3ab0]
-[[BOFを起こす関数>#u5e6e8fb]]を適切に利用する。~
gets、strcpy、strcat等を使用しない、_sを使用。

-バッファ・コピー処理をLoopなどで書かない。

*参考 [#q547460e]
-バッファオーバーフローへの対策技術入門~
https://www.saitolab.org/infra_kaisetsu/

**各種領域 [#l983b52e]

***スタック領域 [#mda2bdb9]
***[[スタック領域>https://techinfoofmicrosofttech.osscons.jp/index.php?%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%81%AE%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF]] [#mda2bdb9]

***ヒープ領域 [#y91fe190]
***[[ヒープ領域>https://techinfoofmicrosofttech.osscons.jp/index.php?%E3%83%92%E3%83%BC%E3%83%97]] [#y91fe190]

***プログラム領域 [#ca902f8f]
-スタックは、下から上に積み上がる~
(下位アドレスが下に書いてある場合)

-上から順に、サブルーチンの
--ESP(先頭)
--バッファ
--ローカル変数
--canary
--EBP(底)
--リターン・アドレス

>となる。

***その他 [#m3127a87]
-text領域~
プログラムおよび定数
-data領域~
初期値をもつ静的変数
-bss領域~
初期値をもたない静的変数

**Wikipedia [#a5126966]
-バッファオーバーラン~
https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%83%95%E3%82%A1%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%83%B3

-データ実行防止~
https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E5%AE%9F%E8%A1%8C%E9%98%B2%E6%AD%A2
-Return-to-libc攻撃~
https://ja.wikipedia.org/wiki/Return-to-libc%E6%94%BB%E6%92%83

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS