Slide 1

Slide 1 text

CWEから学ぶ脆弱性 金沢工業大学 宮口誠 @happynote3966

Slide 2

Slide 2 text

この講義での目的 2 ソフトウェア(≒プログラム)には何かしらの脆弱性があります 「脆弱性は塞がなければならない!」→「どうやって?」 脆弱性を防ぐ、もしくは攻撃から守るためには その仕組みを知らなければなりません 本講義では脆弱性の種類や それに対する攻撃手法と原理を学ぶことにより セキュアな(安全な)ソフトウェアを作成するための学びとします

Slide 3

Slide 3 text

講義の流れ 3 座学 演習 座学 <<< 演習

Slide 4

Slide 4 text

Level0 : Dreaming 4

Slide 5

Slide 5 text

まずはこの講義の 概要をお伝えします! 5

Slide 6

Slide 6 text

CWE、脆弱性とは 6 脆弱性:ソフトウェア等において、コンピュータ不正アクセス、 コンピュータウイルス等の攻撃により その機能や性能を損なう原因となり得る 安全性上の問題箇所(1) CWE:製品の個々の脆弱性ではなく、 ソフトウェアの弱点(脆弱性や不具合)のパターンに 共通の呼び名を与えるプロジェクト(2) (1) https://www.ipa.go.jp/files/000011568.pdf より引用 (2) https://www.ipa.go.jp/files/000059838.pdf より引用

Slide 7

Slide 7 text

今回学ぶことについて 7 以下のリンクにある、Cでありがちな脆弱性の種類について学びます https://cwe.mitre.org/data/definitions/658.html

Slide 8

Slide 8 text

配布VMについて 8 リンク:https://drive.google.com/file/d/1giv6ZPZGLlMFzK93uUqHYd-f3PKhoduW/view?usp=sharing USER:user PASS:justdoit :root :justdoit 配布したVM内のディレクトリは以下のようになっています (~)/MiniCamp2018_Hokkaido + Level1 + Level2 + Level3 + Level4 + Level5 各Levelがそれぞれフォルダ名に対応しています

Slide 9

Slide 9 text

Level1 : Wake-up CWE-457 / CWE-478 / CWE-480 / CWE-483 / CWE-484 / CWE-783 9

Slide 10

Slide 10 text

C言語のストレッチをします 慣れている人もそうでない人も クイズにチャレンジ! このレベルではPCを触らないよ! スライドの方を見てくださいね! 10

Slide 11

Slide 11 text

(前提知識)プログラムの制御構造 11 処理 処理 処理 処理A 処理B 制御式 制御式 処理 順次構造 選択構造 (ifやswitch) 繰り返し構造 (forやwhile)

Slide 12

Slide 12 text

Where is the BUG ? (CWE-457.c) 12

Slide 13

Slide 13 text

Where is the BUG ? (CWE-457.c) 変数を初期化せずに使っている! 13

Slide 14

Slide 14 text

CWE-457 Use of Uninitialized Variable 概要:初期化していない変数を使うことで、予想外の動作をしてしまうというもの 変数は初期化してから使いましょう サンプル:zero_variableには0を代入すべきだったが、されていなかった zero_variableには何が入っているか分からないため ほぼ確実にlogin()を実行できない https://cwe.mitre.org/data/definitions/457.html 14

Slide 15

Slide 15 text

Where is the BUG?? (CWE-478.c) 15

Slide 16

Slide 16 text

Where is the BUG?? (CWE-478.c) default文がない! (login_failedを呼び出していない!) 16

Slide 17

Slide 17 text

CWE-478 Missing Default Case in Switch Statement 概要:default文が書いてないために本来の動作とは異なってしまう サンプル:login_failed()をdefault文の中で実行すべきだったが その記述がどこにも見当たらない passcodeにどんな値が代入されても login()が実行されてしまう 17 https://cwe.mitre.org/data/definitions/478.html

Slide 18

Slide 18 text

Where is the BUG??? (CWE-480.c) 18

Slide 19

Slide 19 text

Where is the BUG??? (CWE-480.c) 代入演算子を使っている! 19

Slide 20

Slide 20 text

CWE-480 Use of Incorrect Operator 概要:間違った演算子を使ってしまい、セキュリティ上の問題を引き起こすこと サンプル:「=(代入演算子)」と「==(比較演算子のイコール)」を間違って使っていた 本当なら「==」を使わないといけない passcodeが0以外であれば login()が実行される 20 https://cwe.mitre.org/data/definitions/480.html

Slide 21

Slide 21 text

Where is the BUG???? (CWE-483.c) 21

Slide 22

Slide 22 text

Where is the BUG???? (CWE-483.c) if文の後のインデントがおかしい! 22

Slide 23

Slide 23 text

CWE-483 Incorrect Block Delimination 概要:波カッコ「{ }」などを使ってブロックを分かりやすく分けてないせいで if文などのブロックの処理が複数行われてしまうこと サンプル:波カッコを使わずにif文を書くと、その下の一行だけがブロックになるが それよりも下の行がインデントをミスしている 23 https://cwe.mitre.org/data/definitions/483.html 黄色の部分はif文 緑色の部分は 黄色のif分の結果に 関係なく実行される

Slide 24

Slide 24 text

Where is the BUG????? (CWE-484.c) 24

Slide 25

Slide 25 text

Where is the BUG????? (CWE-484.c) break文がない! 25

Slide 26

Slide 26 text

CWE-484 Omitted Break Statement in Switch 概要:switch文の中に、break文をつけないと その下の処理も実行されてしまうということ サンプル:login_failed()の実行後に その下のcase文の中のlogin()も実行される 26 https://cwe.mitre.org/data/definitions/484.html case 1から実行すると login_failed()とlogin()が実行され case 0から実行すると login()が実行される

Slide 27

Slide 27 text

Where is the BUG?????? (CWE-783.c) 27

Slide 28

Slide 28 text

Where is the BUG?????? (CWE-783.c) 演算子の優先順位が間違っている! 28

Slide 29

Slide 29 text

CWE-783 Operator Precedence Logic Error 概要:演算子の優先順位を間違ってしまい、予想外の処理をしてしまうこと サンプル:「=」よりも「==」のほうが優先順位が高いため is_loginにauth()の返り値が代入されるよりも前に0との比較が行われてしまった 29 https://cwe.mitre.org/data/definitions/783.html 直感的には左から右へ実行しそうだが 実際には「auth() == 0」が先に実行し その結果をis_loginに代入する

Slide 30

Slide 30 text

Level2 : Stretch CWE-128 / CWE-134 / CWE-191 / CWE-194 / CWE-242 / CWE-476 30

Slide 31

Slide 31 text

ちょっとずつ難しくなります コンピュータの仕組みと照らしながら 勉強しましょう! ここからは実際に 手を動かしながら調べてみましょう! 31

Slide 32

Slide 32 text

(前提知識)CPUとレジスタについて 32 EAX EBX ECX EDX CPU レジスタ ビット列 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Slide 33

Slide 33 text

Where is the BUG? (CWE-128.c) 33

Slide 34

Slide 34 text

Where is the BUG? (CWE-128.c) 34

Slide 35

Slide 35 text

What is the EVIL input? ? ? 35

Slide 36

Slide 36 text

What is the EVIL input? 2147483647 1 36

Slide 37

Slide 37 text

CWE-128 Wrap-around Error 概要:表せる範囲の最大値を超えて表そうとすると プラスの値がマイナスの値になってしまうこと(符号なしの場合は0に戻る) サンプル:sumが表せる最大範囲の2147483647を超えた足し算をしてしまった 37 https://cwe.mitre.org/data/definitions/128.html sum += input_numberが 実行される前に 最大値を超えないか確認すべきだった

Slide 38

Slide 38 text

EX. 4bitで表した整数の足し算 38 0 0 0 0 0 0 0 0 1 1 0 0 1 0 2 0 0 1 1 3 0 1 0 1 5 0 1 1 0 6 0 1 1 1 7 1 0 0 0 -8 0 1 0 0 4 足し算の結果がマイナスになっている! +1 +1 +1 +1 +1 +1 +1 +1

Slide 39

Slide 39 text

Where is the BUG?? (CWE-134.c) 39

Slide 40

Slide 40 text

Where is the BUG?? (CWE-134.c) 40

Slide 41

Slide 41 text

What is the EVIL input?? ? ? 41

Slide 42

Slide 42 text

What is the EVIL input?? %d(%x) -889275714 42

Slide 43

Slide 43 text

CWE-134 Use of Externally-Controlled Format String 概要:外部から入力される文字列をそのまま書式文字列として渡すこと サンプル:入力される文字列がprintf関数の第一引数になっているため 書式指定子を入力するとそれに応じた結果が出力されてしまう 43 https://cwe.mitre.org/data/definitions/134.html 外部からの入力を そのまま出力させたいのなら printf(“%s”,buf)にすべきだった

Slide 44

Slide 44 text

書式文字列と引数の関係(x86の場合) 44 printf(“%d %s %x”,integer,str,hex) printf(buf) ※bufには”%d %s %x”が入るとする “%d(1) %s(2) %x(3)”へのポインタ (1) integer(何かの整数) (2) str(何かの文字列へのポインタ ) (3) hex(何かの整数) スタック(後述) “%d(1) %s(2) %x(3)”へのポインタ ?????????????????????????? ?????????????????????????? ?????????????????????????? 参照 参照 スタック

Slide 45

Slide 45 text

Where is the BUG??? (CWE-191.c) 45

Slide 46

Slide 46 text

Where is the BUG??? (CWE-191.c) 46

Slide 47

Slide 47 text

What is the EVIL input??? ? ? 47

Slide 48

Slide 48 text

What is the EVIL input??? 2147483647 2 48

Slide 49

Slide 49 text

CWE-191 Integer Underflow (Wrap or Wraparound) 概要:表せる範囲の最小値より小さい値を表そうとすると マイナスの値がプラスの値になってしまうこと(符号なしの場合は最大値になる) サンプル:sub_sumが表せる最小範囲の-2147483647を下回る引き算をしてしまった 49 https://cwe.mitre.org/data/definitions/191.html sub_sum -= input_numberが 実行される前に 最小値を下回らないか 確認すべきだった

Slide 50

Slide 50 text

EX. 4bitで表した整数の引き算 50 1 1 1 1 -1 1 1 1 0 -2 1 1 0 1 -3 1 1 0 0 -4 1 0 1 0 -6 1 0 0 1 -7 1 0 0 0 -8 0 1 1 1 7 1 0 1 1 -5 引き算の結果がプラスになっている! -1 -1 -1 -1 -1 -1 -1 -1

Slide 51

Slide 51 text

Where is the BUG???? (CWE-194.c) 51

Slide 52

Slide 52 text

Where is the BUG???? (CWE-194.c) 52

Slide 53

Slide 53 text

What is the EVIL input???? ? 53

Slide 54

Slide 54 text

What is the EVIL input???? 65535 54

Slide 55

Slide 55 text

CWE-194 Unexpected Sign Extension 概要:大きいデータ型から小さいデータ型へデータを移動する時に 意図せず符号(プラスやマイナス)が付加してしまうこと サンプル 55 https://cwe.mitre.org/data/definitions/194.html number = tmp_numberをする際に 2つのデータタイプを しっかりと確認すべきだった

Slide 56

Slide 56 text

2byteから1byteへの整数値のキャスト 56 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 無視される 255 -1 2byteで(11111111)の時は255という扱いになるが 1byteで(11111111)の時は-1という扱いになる

Slide 57

Slide 57 text

Where is the BUG????? (CWE-242.c) 57

Slide 58

Slide 58 text

Where is the BUG????? (CWE-242.c) 58

Slide 59

Slide 59 text

What is the EVIL input????? ? 59

Slide 60

Slide 60 text

What is the EVIL input????? ‘A’ * 31~ 60

Slide 61

Slide 61 text

CWE-242 Use of Inherently Dangerous Function 概要:安全に動作する保証のない関数を使うこと サンプル:gets関数はユーザ側が任意の長さの入力をすることが可能 61 https://cwe.mitre.org/data/definitions/242.html getsを使うことがそもそも危険 (後で解説するBOFにつながる) ※他にも危険な関数は存在する

Slide 62

Slide 62 text

Where is the BUG?????? (CWE-476.c) 62

Slide 63

Slide 63 text

Where is the BUG?????? (CWE-476.c) 63

Slide 64

Slide 64 text

What is the EVIL input?????? ? 64

Slide 65

Slide 65 text

What is the EVIL input?????? [a-z] 65

Slide 66

Slide 66 text

CWE-476 NULL Pointer Dereference 概要:NULLポインタを参照すると大抵の場合クラッシュしてしまうというもの サンプル:pointerに代入されるstrchrの返り値がNULLであるかをチェックしていない 66 https://cwe.mitre.org/data/definitions/476.html *pointer = ‘!’を実行する前に pointerの値がNULLかどうかを チェックしなければならなかった

Slide 67

Slide 67 text

C言語における文字列 67 A B C D E F G H I J K L ... 0x80486b4 文字列本体 0x80486b4 alphabetの値 変数(または定数)は 文字列の「アドレス」を保存している ? ? ? ? ? ? ? ? ? ? ? ? ... 0x0(NULL) ???????? 0x0 小文字入力時の pointerの値 アドレスが0の場所には 何もない(アクセス禁止)

Slide 68

Slide 68 text

Level3 : Running CWE-121 / CWE-124 / CWE-126 / CWE-127 / CWE-170 68

Slide 69

Slide 69 text

いよいよ本格的になります あの有名な脆弱性もでてくるよ! わからないことがあれば 近くの人と話したり チューターに質問してみよう! 69

Slide 70

Slide 70 text

ASCII文字について 70 文字は全て文字コードに従って「数値」の表現を変えたものです 詳しくは http://www3.nit.ac.jp/~tamura/ex2/ascii.html を参照 0x31 = ‘1’ 0x40 = ‘@’ 0x41 = ‘A’

Slide 71

Slide 71 text

メモリについて 71 0x01番地 0x02番地 0x03番地 0x04番地 CPU メモリ ビット列 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 データ

Slide 72

Slide 72 text

メモリについて 72 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所) 0x00000000 0xFFFFFFFF

Slide 73

Slide 73 text

メモリについて 73 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所) スタック領域は 上に向かって(アドレスの小さい方に) 領域が増えていく 0x00000000 0xFFFFFFFF

Slide 74

Slide 74 text

スタックについて 74 スタック push pop

Slide 75

Slide 75 text

スタックについて 75 スタック 引数2 push pop

Slide 76

Slide 76 text

スタックについて 76 スタック 引数2 引数1 push pop

Slide 77

Slide 77 text

スタックについて 77 スタック 引数2 引数1 リターンアドレス(制御データ) push pop

Slide 78

Slide 78 text

スタックについて 78 スタック 引数2 引数1 リターンアドレス(制御データ) ローカル変数 push pop

Slide 79

Slide 79 text

スタックについて 79 スタック 引数2 引数1 リターンアドレス(制御データ) ローカル変数 push pop リターンアドレスや 引数などは スタックにpushされる ローカル変数は スタック領域を増やすことで 確保している (pushやpopではない)

Slide 80

Slide 80 text

Where is the BUG? (CWE-121.c) 80

Slide 81

Slide 81 text

Where is the BUG? (CWE-121.c) 81

Slide 82

Slide 82 text

What is the EVIL input? ? 82

Slide 83

Slide 83 text

What is the EVIL input? ‘A’ * 16 ~ 83

Slide 84

Slide 84 text

CWE-121 Stack-based Buffer Overflow 概要:スタック上のバッファから大量のデータが流れ込み その下にある変数や重要なデータなどが上書きされてしまうもの サンプル:nameへの大量の入力でバッファオーバーフローを起こすことができる 84 https://cwe.mitre.org/data/definitions/121.html bufというバッファに溜め込める 大きさを超えたデータが nameから流れ込んでしまった

Slide 85

Slide 85 text

スタック上でバッファオーバーフローが起きる時 85 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) 重要なデータ (リターンアドレスや文字列など) スタック

Slide 86

Slide 86 text

スタック上でバッファオーバーフローが起きる時 86 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ (リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 入力されたデータ 入 力 の 流 れ スタック スタック

Slide 87

Slide 87 text

スタック上でバッファオーバーフローが起きる時 87 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ (リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 入力されたデータ 上書きされてしまった部分 入 力 の 流 れ スタック スタック

Slide 88

Slide 88 text

GDBで見てみる 88 $ gdb -q CWE-121 (gdb) b *main+99 (gdb) b *main+104 (gdb) run (入力) AAAAAAAAAAAAAAAA (gdb) x/20xw $esp (gdb) c (gdb) x/20xw $esp

Slide 89

Slide 89 text

メモリの状態 89 buf ecx 上書きされた部分

Slide 90

Slide 90 text

Where is the BUG??(CWE-124.c) 90

Slide 91

Slide 91 text

Where is the BUG??(CWE-124.c) 91

Slide 92

Slide 92 text

What is the EVIL input? 92 ? ?

Slide 93

Slide 93 text

What is the EVIL input? 93 -10 P@ssword

Slide 94

Slide 94 text

CWE-124 Buffer Underwrite (‘Buffer Underflow’) 概要:書き込みの際にバッファより上の領域に対してデータが流れ込み 書き込むバッファより上の領域に合ったデータが上書きされるもの サンプル:num_of_indent変数マイナスの値を入力することで バッファより上の領域にデータを書き込める 94 https://cwe.mitre.org/data/definitions/124.html scanf関数で マイナスの値が入力されるのを チェックしなければならなかった

Slide 95

Slide 95 text

スタック上でバッファアンダーフローが起きる時 95 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) 重要なデータ (リターンアドレスや文字列など) スタック

Slide 96

Slide 96 text

スタック上でバッファアンダーフローが起きる時 96 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ (リターンアドレスや文字列など) 入力用バッファ (データを入力する場所) 入力されたデータ 入 力 の 流 れ スタック スタック

Slide 97

Slide 97 text

スタック上でバッファアンダーフローが起きる時 97 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ (リターンアドレスや文字列など) 入力用バッファ (データを入力する場所) 入力されたデータ 上書きされてしまった部分 入 力 の 流 れ スタック スタック

Slide 98

Slide 98 text

GDBで見てみる 98 $ gdb -q CWE-124 (gdb) b *main+145 (gdb) b *main+150 (gdb) run (入力) -10 (gdb) x/20xw $ebp - 0x26 (gdb) c (入力) P@ssword (gdb) x/20xw $ebp - 0x26 (gdb) x/s $ebp - 0x26

Slide 99

Slide 99 text

メモリの状態 99 buf “P@ssword”になっている password bufのアドレス(0xffffd00c) - passwordのアドレス(0xffffd002) = 0xa(10)

Slide 100

Slide 100 text

Where is the BUG??? (CWE-126.c) 100

Slide 101

Slide 101 text

Where is the BUG??? (CWE-126.c) 101

Slide 102

Slide 102 text

What is the EVIL input? ? 102

Slide 103

Slide 103 text

What is the EVIL input? 24 ~ 103

Slide 104

Slide 104 text

CWE-126 Buffer Over-read 概要:スタック上のバッファからの読み込みのときに 読み込んでいるバッファを超えてさらに読み込んでしまうもの サンプル:scanf関数で大きな値を入力するとその分だけ読み込んでしまう 104 https://cwe.mitre.org/data/definitions/126.html scanf関数で 大きすぎる値が入力されるのを 防がなければならなかった

Slide 105

Slide 105 text

スタック上でバッファオーバーリードが起きる時 105 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) 重要なデータ (リターンアドレスや文字列など) スタック スタック

Slide 106

Slide 106 text

スタック上でバッファオーバーリードが起きる時 106 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ (リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 出力されたデータ 出 力 の 流 れ スタック スタック

Slide 107

Slide 107 text

スタック上でバッファオーバーリードが起きる時 107 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ (リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック

Slide 108

Slide 108 text

GDBで見てみる 108 $ gdb -q CWE-126 (gdb) b *main+149 (gdb) run (入力) A (入力) 24 (gdb) x/20xw $ebp - 0x28

Slide 109

Slide 109 text

メモリの状態 109 name “!53cr37!”になっている buf nameの大きさ(16)+”!53cr37!”の大きさ(8) =24

Slide 110

Slide 110 text

Where is the BUG???? (CWE-127.c) 110

Slide 111

Slide 111 text

Where is the BUG???? (CWE-127.c) 111

Slide 112

Slide 112 text

What is the EVIL input? ? 112

Slide 113

Slide 113 text

What is the EVIL input? -16 113

Slide 114

Slide 114 text

CWE-127 Buffer Under-read 概要:スタック上のバッファからの読み込みのときに 読み込んでいるバッファよりも上から読み込んでしまうもの サンプル:scanf関数でマイナスの値を入力することで バッファの上にあるデータを読み込める 114 https://cwe.mitre.org/data/definitions/127.html scanf関数で マイナスの値が入力されるのを チェックしなければならなかった

Slide 115

Slide 115 text

スタック上でバッファアンダーリードが起きる時 115 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) 重要なデータ (リターンアドレスや文字列など) スタック

Slide 116

Slide 116 text

スタック上でバッファアンダーリードが起きる時 116 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ (リターンアドレスや文字列など) 出力用バッファ (出力データがある場所) 出力されたデータ 出 力 の 流 れ スタック スタック

Slide 117

Slide 117 text

スタック上でバッファアンダーリードが起きる時 117 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ (リターンアドレスや文字列など) 出力用バッファ (出力データがある場所) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック

Slide 118

Slide 118 text

GDBで見てみる 118 $ gdb -q CWE-127 (gdb) b *main+145 (gdb) run (入力) A (入力) -24 (gdb) x/20xw $ebp - 0x38

Slide 119

Slide 119 text

メモリの状態 119 secret_buf “P@ssword”になっている user_buf secret_bufのアドレス(0xffffcff0) - user_bufのアドレス(0xffffd000) = 0x10(16)

Slide 120

Slide 120 text

Where is the BUG ????? (CWE-170.c) 120

Slide 121

Slide 121 text

Where is the BUG ????? (CWE-170.c) 121

Slide 122

Slide 122 text

What is the EVIL input? ? 122

Slide 123

Slide 123 text

What is the EVIL input? ‘A’ * 15 123 ※16文字以上の入力でも可 ただしその場合は一度で loginを実行できない 16文字の入力の場合、 ’\n’の文字がバッファに貯まるため、パスワード入力時に失敗する

Slide 124

Slide 124 text

CWE-170 Improper Null Termination 概要:しっかりとしたNULL文字終端をしていないということ サンプル:read関数に大量の文字列を送ることでNULL文字をなくすことができる 124 https://cwe.mitre.org/data/definitions/170.html read関数の後で 適切なNULL文字の挿入を すべきだった

Slide 125

Slide 125 text

read関数でNULL文字(‘\0’)が入らないワケ 125 A A A A \n \0 S E C R E T buffer secret read(0,buffer,6) AAAA(改行) A A A A A \n S E C R E T buffer secret read(0,buffer,6) AAAAA(改行) 1つの文字列 1つの文字列 1つの文字列

Slide 126

Slide 126 text

GDBで見てみる 126 $ gdb -q CWE-170 (gdb) b *main+102 (gdb) b *main+107 (gdb) run (gdb) x/20xw $ebp - 0x21 (gdb) c (入力) AAAAAAAAAAAAAAA (gdb) x/20xw $ebp - 0x21

Slide 127

Slide 127 text

メモリの状態 127 “!53cre7!”になっている buf buf 改行文字が挿入されている

Slide 128

Slide 128 text

Level4 : Dash CWE-122 / CWE-244 / CWE-415 / CWE-416 128

Slide 129

Slide 129 text

かなり難しくなります メモリについての知識が 必要になります! 一度に全部覚える 必要はありません! 少しずつ理解していきましょう! 129

Slide 130

Slide 130 text

メモリについて 130 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所) 0x00000000 0xFFFFFFFF

Slide 131

Slide 131 text

メモリについて 131 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所) ヒープ領域は 下に向かって(アドレスの大きい方に) 領域が増えていく 0x00000000 0xFFFFFFFF

Slide 132

Slide 132 text

ヒープについて 132 ヒープ

Slide 133

Slide 133 text

ヒープについて 133 ヒープ 管理領域(ヒープ管理のための場所) データ領域 (実際にユーザが使えるメモリの場所) malloc ptr

Slide 134

Slide 134 text

ヒープについて 134 ヒープ 管理領域(ヒープ管理のための場所) データ領域 (実際にユーザが使えるメモリの場所) free ptr 管理領域(重なる部分もある)

Slide 135

Slide 135 text

Where is the BUG ? (CWE-122.c) 135

Slide 136

Slide 136 text

Where is the BUG ? (CWE-122.c) 136

Slide 137

Slide 137 text

What is the EVIL input? 137 ?

Slide 138

Slide 138 text

What is the EVIL input? ‘A’*24+’Overwrite!’ 138

Slide 139

Slide 139 text

CWE-122 Heap-based Buffer Overflow 概要:ヒープ上で割り当てたメモリ領域の大きさを超えたデータが書き込まれること サンプル:gets関数によって割り当てたヒープ上のメモリ領域の大きさを超えて 別のメモリ領域に書き込んでいる 139 https://cwe.mitre.org/data/definitions/122.html 割り当てたメモリ領域に対して 入力サイズを合わせるべきだった

Slide 140

Slide 140 text

malloc malloc ヒープ上のオーバーフローで上書きできるワケ 140 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1 ptr2

Slide 141

Slide 141 text

ヒープ上のオーバーフローで上書きできるワケ 141 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1 ptr2 入力されたデータ 入 力 の 流 れ

Slide 142

Slide 142 text

ヒープ上のオーバーフローで上書きできるワケ 142 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1 ptr2 入力されたデータ 上書きされた領域 入 力 の 流 れ

Slide 143

Slide 143 text

GDBで見てみる 143 $ gdb -q CWE-122 (gdb) b *main+27 (gdb) b *main+89 (gdb) b *main+94 (gdb) run (gdb) print $eax (gdb) c (gdb) x/20xw $1 (gdb) c (入力) AAAAAAAAAAAAAAAAAAAAAAAAOverwrite! (gdb) x/20xw $1

Slide 144

Slide 144 text

メモリの状態 144 ptr1の示すメモリ領域 上書きされた部分 ptr2の示すメモリ領域

Slide 145

Slide 145 text

Where is the BUG ?? (CWE-244.c) 145

Slide 146

Slide 146 text

Where is the BUG ?? (CWE-244.c) 146

Slide 147

Slide 147 text

What is the EVIL input? ? 147

Slide 148

Slide 148 text

What is the EVIL input? 37 ~ 4096 148

Slide 149

Slide 149 text

CWE-224 Clearing of Heap Memory Before Release (‘Heap Inspection’) 概要:reallocを使った際に重要なデータをそのまま残してしまうこと サンプル:reallocするサイズを極端に小さくしなければ残ったパスワードが表示される 149 https://cwe.mitre.org/data/definitions/244.html ptr2の内容に入力する前に ゼロクリアすべきだった

Slide 150

Slide 150 text

malloc reallocで割り当てたメモリの中身 150 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1

Slide 151

Slide 151 text

reallocで割り当てたメモリの中身 151 ヒープ ptr1 書き込んだデータ

Slide 152

Slide 152 text

realloc reallocで割り当てたメモリの中身 152 reallocで再度割り当てた領域 ヒープ ptr1 書き込んだデータ ptr2

Slide 153

Slide 153 text

reallocで割り当てたメモリの中身 153 reallocで再度割り当てた領域 ヒープ ptr1 書き込んだデータ 書き込んだデータは そのまま残ってしまう (サイズを小さくした場合は 差分だけが消える) ptr2

Slide 154

Slide 154 text

GDBで見てみる 154 $ gdb -q CWE-244 (gdb) b *main+78 (gdb) b *main+199 (gdb) run (gdb) print $eax (gdb) c (入力) 37 (gdb) print $eax (gdb) x/s $2

Slide 155

Slide 155 text

メモリの状態 155 mallocの返り値も reallocの返り値も 一緒になっている $2の指し示す場所には 元から格納されていた 文字列がある

Slide 156

Slide 156 text

Where is the BUG ??? (CWE-415.c) 156

Slide 157

Slide 157 text

Where is the BUG ??? (CWE-415.c) 157

Slide 158

Slide 158 text

What is the EVIL input? ? 158

Slide 159

Slide 159 text

What is the EVIL input? ‘A’ * 9 ~ 159

Slide 160

Slide 160 text

CWE-415 Double Free 概要:一度freeしたメモリ領域を再度freeすること サンプル:文字列の長さを10にすると2回freeされてしまう 160 https://cwe.mitre.org/data/definitions/415.html 最後にまとめてfreeすべきだった (条件分岐内で分けて freeを書かなくてよかった)

Slide 161

Slide 161 text

GDBで見てみる 161 $ gdb -q CWE-415 (gdb) b *main+157 (gdb) b *main+206 (gdb) run (入力) AAAAAAAAAA (gdb) x/xw $esp (gdb) c (gdb) x/xw $esp

Slide 162

Slide 162 text

メモリの状態 162 どちらも同じ値 (freeへの引数が どちらも一緒)

Slide 163

Slide 163 text

Where is the BUG ???? (CWE-416.c) 163

Slide 164

Slide 164 text

Where is the BUG ???? (CWE-416.c) 164

Slide 165

Slide 165 text

What is the EVIL input? ? 165 ?

Slide 166

Slide 166 text

What is the EVIL input? 3→4→AAA 166 4

Slide 167

Slide 167 text

CWE-416 Use After Free 概要:freeしたあとにNULL代入をせず再度使用すること サンプル:一度freeしたメモリ領域をそのまま使うことで 中に入っていたデータを抜き出すことができる 167 https://cwe.mitre.org/data/definitions/416.html freeした後のポインタは NULLを代入しておくべきだった

Slide 168

Slide 168 text

malloc freeの後にNULL代入せずに使用すると 168 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1

Slide 169

Slide 169 text

freeの後にNULL代入せずに使用すると 169 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1 入力したデータ

Slide 170

Slide 170 text

free freeの後にNULL代入せずに使用すると 170 freeした際の管理データ ヒープ ptr1 入力したデータ

Slide 171

Slide 171 text

freeの後にNULL代入せずに使用すると 171 freeした際の管理データ ヒープ ptr1 入力したデータ NULL代入されてないptr1を使うことで 管理データを書き換えたり 入力したデータを 読み取ったりすることができる

Slide 172

Slide 172 text

GDBで見てみる 172 $ gdb -q CWE-416 (gdb) b *main+146 (gdb) b *main+395 (gdb) b *main+400 (gdb) run (gdb) x/xw $esp (※0x0804b008) (gdb) c (入力) 3 (入力) 4 (gdb) x/20xw 0x0804b008 (gdb) c (入力) AAA (gdb) x/20xw 0x0804b008

Slide 173

Slide 173 text

メモリの状態 173 管理領域の部分が 0クリアされている freeされたptrが指し 示すメモリ領域 管理領域の部分に 書き込んでいる

Slide 174

Slide 174 text

Level5 : Flying CWE-??? / CWE-??? / CWE-??? / CWE-??? / CWE-??? 174

Slide 175

Slide 175 text

ここまでの集大成として プログラムの中から 脆弱性を探してみましょう! 今までに学んだ知識を総動員して 取り組んでみてください! 175

Slide 176

Slide 176 text

出題するプログラムについて ls,wc,strings,rev,whichのコマンドを真似したプログラムです (実際の動作とは異なっていますが、気にしないでください) 各プログラムから脆弱性を探してください こうなったら正解です ・プログラムが異常終了する ・本来の動作とは異なる動きをした(予想の動作と異なった) 想定解以外もあるかもしれません 176

Slide 177

Slide 177 text

Where is the BUG? (ls_vuln.c) 177

Slide 178

Slide 178 text

Where is the BUG?? (wc_vuln.c) 178

Slide 179

Slide 179 text

Where is the BUG??? (strings_vuln.c) 179

Slide 180

Slide 180 text

Where is the BUG???? (rev_vuln.c) 180

Slide 181

Slide 181 text

Where is the BUG????? (which_vuln.c) 181

Slide 182

Slide 182 text

Re:Level5 Flying with Conpass CWE-??? / CWE-??? / CWE-??? / CWE-??? / CWE-??? 182

Slide 183

Slide 183 text

This is the BUG! (ls_vuln.c) 183

Slide 184

Slide 184 text

PoC 184

Slide 185

Slide 185 text

This is the BUG!! (wc_vuln.c) 185

Slide 186

Slide 186 text

PoC 186

Slide 187

Slide 187 text

This is the BUG!!! (strings_vuln.c) 187

Slide 188

Slide 188 text

PoC 188

Slide 189

Slide 189 text

This is the BUG!!!! (rev_vuln.c) 189

Slide 190

Slide 190 text

PoC 190

Slide 191

Slide 191 text

This is the BUG!!!!! (which_vuln.c) 191

Slide 192

Slide 192 text

PoC 192

Slide 193

Slide 193 text

Thank you for your attention! (おつかれさまでした!) 193