Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CWEから学ぶ脆弱性
Search
happynote3966
November 04, 2018
Technology
3
1k
CWEから学ぶ脆弱性
セキュリティ・ミニキャンプ in 北海道 2018で発表したスライド資料です
happynote3966
November 04, 2018
Tweet
Share
More Decks by happynote3966
See All by happynote3966
QEMUを用いた自動バイナリ防御機構の開発_公開版.pdf
happynote3966
6
3.6k
open()の実装を読んでみる
happynote3966
1
720
Other Decks in Technology
See All in Technology
生成AIと知識グラフの相互利用に基づく文書解析
koujikozaki
1
130
Jr. Championsになって、強く連携しながらAWSをもっと使いたい!~AWSに対する期待と行動~
amixedcolor
0
170
ABEMA のコンテンツ制作を最適化!生成 AI x クラウド映像編集システム / abema-ai-editor
cyberagentdevelopers
PRO
1
180
【LT】ソフトウェア産業は進化しているのか? -Javaの想い出とともに- #jjug_ccc
takabow
0
170
一休.comレストランにおけるRustの活用
kymmt90
3
570
プロダクトエンジニアが活躍する環境を作りたくて 事業責任者になった話 ~プロダクトエンジニアの行き着く先~
gimupop
1
440
Apple/Google/Amazonの決済システムの違いを踏まえた定期購読課金システムの構築 / abema-billing-system
cyberagentdevelopers
PRO
1
210
顧客が本当に必要だったもの - パフォーマンス改善編 / Make what is needed
soudai
24
6.6k
物価高なラスベガスでの過ごし方
zakky
0
320
[AWS JAPAN 生成AIハッカソン] Dialog の紹介
yoshimi0227
0
140
初心者に Vue.js を 教えるには
tsukuha
5
380
Product Engineer Night #6プロダクトエンジニアを育む仕組み・施策
hacomono
PRO
1
440
Featured
See All Featured
It's Worth the Effort
3n
183
27k
Why You Should Never Use an ORM
jnunemaker
PRO
53
9k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Building Applications with DynamoDB
mza
90
6.1k
The Cost Of JavaScript in 2023
addyosmani
45
6.6k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
13
1.9k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Unsuck your backbone
ammeep
668
57k
How GitHub (no longer) Works
holman
311
140k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Transcript
CWEから学ぶ脆弱性 金沢工業大学 宮口誠 @happynote3966
この講義での目的 2 ソフトウェア(≒プログラム)には何かしらの脆弱性があります 「脆弱性は塞がなければならない!」→「どうやって?」 脆弱性を防ぐ、もしくは攻撃から守るためには その仕組みを知らなければなりません 本講義では脆弱性の種類や それに対する攻撃手法と原理を学ぶことにより セキュアな(安全な)ソフトウェアを作成するための学びとします
講義の流れ 3 座学 演習 座学 <<< 演習
Level0 : Dreaming 4
まずはこの講義の 概要をお伝えします! 5
CWE、脆弱性とは 6 脆弱性:ソフトウェア等において、コンピュータ不正アクセス、 コンピュータウイルス等の攻撃により その機能や性能を損なう原因となり得る 安全性上の問題箇所(1) CWE:製品の個々の脆弱性ではなく、 ソフトウェアの弱点(脆弱性や不具合)のパターンに 共通の呼び名を与えるプロジェクト(2) (1)
https://www.ipa.go.jp/files/000011568.pdf より引用 (2) https://www.ipa.go.jp/files/000059838.pdf より引用
今回学ぶことについて 7 以下のリンクにある、Cでありがちな脆弱性の種類について学びます https://cwe.mitre.org/data/definitions/658.html
配布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がそれぞれフォルダ名に対応しています
Level1 : Wake-up CWE-457 / CWE-478 / CWE-480 / CWE-483
/ CWE-484 / CWE-783 9
C言語のストレッチをします 慣れている人もそうでない人も クイズにチャレンジ! このレベルではPCを触らないよ! スライドの方を見てくださいね! 10
(前提知識)プログラムの制御構造 11 処理 処理 処理 処理A 処理B 制御式 制御式 処理
順次構造 選択構造 (ifやswitch) 繰り返し構造 (forやwhile)
Where is the BUG ? (CWE-457.c) 12
Where is the BUG ? (CWE-457.c) 変数を初期化せずに使っている! 13
CWE-457 Use of Uninitialized Variable 概要:初期化していない変数を使うことで、予想外の動作をしてしまうというもの 変数は初期化してから使いましょう サンプル:zero_variableには0を代入すべきだったが、されていなかった zero_variableには何が入っているか分からないため ほぼ確実にlogin()を実行できない
https://cwe.mitre.org/data/definitions/457.html 14
Where is the BUG?? (CWE-478.c) 15
Where is the BUG?? (CWE-478.c) default文がない! (login_failedを呼び出していない!) 16
CWE-478 Missing Default Case in Switch Statement 概要:default文が書いてないために本来の動作とは異なってしまう サンプル:login_failed()をdefault文の中で実行すべきだったが その記述がどこにも見当たらない
passcodeにどんな値が代入されても login()が実行されてしまう 17 https://cwe.mitre.org/data/definitions/478.html
Where is the BUG??? (CWE-480.c) 18
Where is the BUG??? (CWE-480.c) 代入演算子を使っている! 19
CWE-480 Use of Incorrect Operator 概要:間違った演算子を使ってしまい、セキュリティ上の問題を引き起こすこと サンプル:「=(代入演算子)」と「==(比較演算子のイコール)」を間違って使っていた 本当なら「==」を使わないといけない passcodeが0以外であれば login()が実行される
20 https://cwe.mitre.org/data/definitions/480.html
Where is the BUG???? (CWE-483.c) 21
Where is the BUG???? (CWE-483.c) if文の後のインデントがおかしい! 22
CWE-483 Incorrect Block Delimination 概要:波カッコ「{ }」などを使ってブロックを分かりやすく分けてないせいで if文などのブロックの処理が複数行われてしまうこと サンプル:波カッコを使わずにif文を書くと、その下の一行だけがブロックになるが それよりも下の行がインデントをミスしている 23
https://cwe.mitre.org/data/definitions/483.html 黄色の部分はif文 緑色の部分は 黄色のif分の結果に 関係なく実行される
Where is the BUG????? (CWE-484.c) 24
Where is the BUG????? (CWE-484.c) break文がない! 25
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()が実行される
Where is the BUG?????? (CWE-783.c) 27
Where is the BUG?????? (CWE-783.c) 演算子の優先順位が間違っている! 28
CWE-783 Operator Precedence Logic Error 概要:演算子の優先順位を間違ってしまい、予想外の処理をしてしまうこと サンプル:「=」よりも「==」のほうが優先順位が高いため is_loginにauth()の返り値が代入されるよりも前に0との比較が行われてしまった 29 https://cwe.mitre.org/data/definitions/783.html
直感的には左から右へ実行しそうだが 実際には「auth() == 0」が先に実行し その結果をis_loginに代入する
Level2 : Stretch CWE-128 / CWE-134 / CWE-191 / CWE-194
/ CWE-242 / CWE-476 30
ちょっとずつ難しくなります コンピュータの仕組みと照らしながら 勉強しましょう! ここからは実際に 手を動かしながら調べてみましょう! 31
(前提知識)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
Where is the BUG? (CWE-128.c) 33
Where is the BUG? (CWE-128.c) 34
What is the EVIL input? ? ? 35
What is the EVIL input? 2147483647 1 36
CWE-128 Wrap-around Error 概要:表せる範囲の最大値を超えて表そうとすると プラスの値がマイナスの値になってしまうこと(符号なしの場合は0に戻る) サンプル:sumが表せる最大範囲の2147483647を超えた足し算をしてしまった 37 https://cwe.mitre.org/data/definitions/128.html sum +=
input_numberが 実行される前に 最大値を超えないか確認すべきだった
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
Where is the BUG?? (CWE-134.c) 39
Where is the BUG?? (CWE-134.c) 40
What is the EVIL input?? ? ? 41
What is the EVIL input?? %d(%x) -889275714 42
CWE-134 Use of Externally-Controlled Format String 概要:外部から入力される文字列をそのまま書式文字列として渡すこと サンプル:入力される文字列がprintf関数の第一引数になっているため 書式指定子を入力するとそれに応じた結果が出力されてしまう 43
https://cwe.mitre.org/data/definitions/134.html 外部からの入力を そのまま出力させたいのなら printf(“%s”,buf)にすべきだった
書式文字列と引数の関係(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)”へのポインタ ?????????????????????????? ?????????????????????????? ?????????????????????????? 参照 参照 スタック
Where is the BUG??? (CWE-191.c) 45
Where is the BUG??? (CWE-191.c) 46
What is the EVIL input??? ? ? 47
What is the EVIL input??? 2147483647 2 48
CWE-191 Integer Underflow (Wrap or Wraparound) 概要:表せる範囲の最小値より小さい値を表そうとすると マイナスの値がプラスの値になってしまうこと(符号なしの場合は最大値になる) サンプル:sub_sumが表せる最小範囲の-2147483647を下回る引き算をしてしまった 49
https://cwe.mitre.org/data/definitions/191.html sub_sum -= input_numberが 実行される前に 最小値を下回らないか 確認すべきだった
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
Where is the BUG???? (CWE-194.c) 51
Where is the BUG???? (CWE-194.c) 52
What is the EVIL input???? ? 53
What is the EVIL input???? 65535 54
CWE-194 Unexpected Sign Extension 概要:大きいデータ型から小さいデータ型へデータを移動する時に 意図せず符号(プラスやマイナス)が付加してしまうこと サンプル 55 https://cwe.mitre.org/data/definitions/194.html number
= tmp_numberをする際に 2つのデータタイプを しっかりと確認すべきだった
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という扱いになる
Where is the BUG????? (CWE-242.c) 57
Where is the BUG????? (CWE-242.c) 58
What is the EVIL input????? ? 59
What is the EVIL input????? ‘A’ * 31~ 60
CWE-242 Use of Inherently Dangerous Function 概要:安全に動作する保証のない関数を使うこと サンプル:gets関数はユーザ側が任意の長さの入力をすることが可能 61 https://cwe.mitre.org/data/definitions/242.html
getsを使うことがそもそも危険 (後で解説するBOFにつながる) ※他にも危険な関数は存在する
Where is the BUG?????? (CWE-476.c) 62
Where is the BUG?????? (CWE-476.c) 63
What is the EVIL input?????? ? 64
What is the EVIL input?????? [a-z] 65
CWE-476 NULL Pointer Dereference 概要:NULLポインタを参照すると大抵の場合クラッシュしてしまうというもの サンプル:pointerに代入されるstrchrの返り値がNULLであるかをチェックしていない 66 https://cwe.mitre.org/data/definitions/476.html *pointer =
‘!’を実行する前に pointerの値がNULLかどうかを チェックしなければならなかった
C言語における文字列 67 A B C D E F G H
I J K L ... 0x80486b4 文字列本体 0x80486b4 alphabetの値 変数(または定数)は 文字列の「アドレス」を保存している ? ? ? ? ? ? ? ? ? ? ? ? ... 0x0(NULL) ???????? 0x0 小文字入力時の pointerの値 アドレスが0の場所には 何もない(アクセス禁止)
Level3 : Running CWE-121 / CWE-124 / CWE-126 / CWE-127
/ CWE-170 68
いよいよ本格的になります あの有名な脆弱性もでてくるよ! わからないことがあれば 近くの人と話したり チューターに質問してみよう! 69
ASCII文字について 70 文字は全て文字コードに従って「数値」の表現を変えたものです 詳しくは http://www3.nit.ac.jp/~tamura/ex2/ascii.html を参照 0x31 = ‘1’ 0x40
= ‘@’ 0x41 = ‘A’
メモリについて 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 データ
メモリについて 72 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所)
0x00000000 0xFFFFFFFF
メモリについて 73 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所)
スタック領域は 上に向かって(アドレスの小さい方に) 領域が増えていく 0x00000000 0xFFFFFFFF
スタックについて 74 スタック push pop
スタックについて 75 スタック 引数2 push pop
スタックについて 76 スタック 引数2 引数1 push pop
スタックについて 77 スタック 引数2 引数1 リターンアドレス(制御データ) push pop
スタックについて 78 スタック 引数2 引数1 リターンアドレス(制御データ) ローカル変数 push pop
スタックについて 79 スタック 引数2 引数1 リターンアドレス(制御データ) ローカル変数 push pop リターンアドレスや
引数などは スタックにpushされる ローカル変数は スタック領域を増やすことで 確保している (pushやpopではない)
Where is the BUG? (CWE-121.c) 80
Where is the BUG? (CWE-121.c) 81
What is the EVIL input? ? 82
What is the EVIL input? ‘A’ * 16 ~ 83
CWE-121 Stack-based Buffer Overflow 概要:スタック上のバッファから大量のデータが流れ込み その下にある変数や重要なデータなどが上書きされてしまうもの サンプル:nameへの大量の入力でバッファオーバーフローを起こすことができる 84 https://cwe.mitre.org/data/definitions/121.html bufというバッファに溜め込める
大きさを超えたデータが nameから流れ込んでしまった
スタック上でバッファオーバーフローが起きる時 85 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) 重要なデータ (リターンアドレスや文字列など)
スタック
スタック上でバッファオーバーフローが起きる時 86 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ
(リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 入力されたデータ 入 力 の 流 れ スタック スタック
スタック上でバッファオーバーフローが起きる時 87 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ
(リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 入力されたデータ 上書きされてしまった部分 入 力 の 流 れ スタック スタック
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
メモリの状態 89 buf ecx 上書きされた部分
Where is the BUG??(CWE-124.c) 90
Where is the BUG??(CWE-124.c) 91
What is the EVIL input? 92 ? ?
What is the EVIL input? 93 -10 P@ssword
CWE-124 Buffer Underwrite (‘Buffer Underflow’) 概要:書き込みの際にバッファより上の領域に対してデータが流れ込み 書き込むバッファより上の領域に合ったデータが上書きされるもの サンプル:num_of_indent変数マイナスの値を入力することで バッファより上の領域にデータを書き込める 94
https://cwe.mitre.org/data/definitions/124.html scanf関数で マイナスの値が入力されるのを チェックしなければならなかった
スタック上でバッファアンダーフローが起きる時 95 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) 重要なデータ (リターンアドレスや文字列など)
スタック
スタック上でバッファアンダーフローが起きる時 96 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ
(リターンアドレスや文字列など) 入力用バッファ (データを入力する場所) 入力されたデータ 入 力 の 流 れ スタック スタック
スタック上でバッファアンダーフローが起きる時 97 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ
(リターンアドレスや文字列など) 入力用バッファ (データを入力する場所) 入力されたデータ 上書きされてしまった部分 入 力 の 流 れ スタック スタック
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
メモリの状態 99 buf “P@ssword”になっている password bufのアドレス(0xffffd00c) - passwordのアドレス(0xffffd002) = 0xa(10)
Where is the BUG??? (CWE-126.c) 100
Where is the BUG??? (CWE-126.c) 101
What is the EVIL input? ? 102
What is the EVIL input? 24 ~ 103
CWE-126 Buffer Over-read 概要:スタック上のバッファからの読み込みのときに 読み込んでいるバッファを超えてさらに読み込んでしまうもの サンプル:scanf関数で大きな値を入力するとその分だけ読み込んでしまう 104 https://cwe.mitre.org/data/definitions/126.html scanf関数で 大きすぎる値が入力されるのを
防がなければならなかった
スタック上でバッファオーバーリードが起きる時 105 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) 重要なデータ (リターンアドレスや文字列など)
スタック スタック
スタック上でバッファオーバーリードが起きる時 106 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ
(リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 出力されたデータ 出 力 の 流 れ スタック スタック
スタック上でバッファオーバーリードが起きる時 107 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ
(リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック
GDBで見てみる 108 $ gdb -q CWE-126 (gdb) b *main+149 (gdb)
run (入力) A (入力) 24 (gdb) x/20xw $ebp - 0x28
メモリの状態 109 name “!53cr37!”になっている buf nameの大きさ(16)+”!53cr37!”の大きさ(8) =24
Where is the BUG???? (CWE-127.c) 110
Where is the BUG???? (CWE-127.c) 111
What is the EVIL input? ? 112
What is the EVIL input? -16 113
CWE-127 Buffer Under-read 概要:スタック上のバッファからの読み込みのときに 読み込んでいるバッファよりも上から読み込んでしまうもの サンプル:scanf関数でマイナスの値を入力することで バッファの上にあるデータを読み込める 114 https://cwe.mitre.org/data/definitions/127.html scanf関数で
マイナスの値が入力されるのを チェックしなければならなかった
スタック上でバッファアンダーリードが起きる時 115 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) 重要なデータ (リターンアドレスや文字列など)
スタック
スタック上でバッファアンダーリードが起きる時 116 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ
(リターンアドレスや文字列など) 出力用バッファ (出力データがある場所) 出力されたデータ 出 力 の 流 れ スタック スタック
スタック上でバッファアンダーリードが起きる時 117 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ
(リターンアドレスや文字列など) 出力用バッファ (出力データがある場所) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック
GDBで見てみる 118 $ gdb -q CWE-127 (gdb) b *main+145 (gdb)
run (入力) A (入力) -24 (gdb) x/20xw $ebp - 0x38
メモリの状態 119 secret_buf “P@ssword”になっている user_buf secret_bufのアドレス(0xffffcff0) - user_bufのアドレス(0xffffd000) = 0x10(16)
Where is the BUG ????? (CWE-170.c) 120
Where is the BUG ????? (CWE-170.c) 121
What is the EVIL input? ? 122
What is the EVIL input? ‘A’ * 15 123 ※16文字以上の入力でも可 ただしその場合は一度で
loginを実行できない 16文字の入力の場合、 ’\n’の文字がバッファに貯まるため、パスワード入力時に失敗する
CWE-170 Improper Null Termination 概要:しっかりとしたNULL文字終端をしていないということ サンプル:read関数に大量の文字列を送ることでNULL文字をなくすことができる 124 https://cwe.mitre.org/data/definitions/170.html read関数の後で 適切なNULL文字の挿入を
すべきだった
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つの文字列
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
メモリの状態 127 “!53cre7!”になっている buf buf 改行文字が挿入されている
Level4 : Dash CWE-122 / CWE-244 / CWE-415 / CWE-416
128
かなり難しくなります メモリについての知識が 必要になります! 一度に全部覚える 必要はありません! 少しずつ理解していきましょう! 129
メモリについて 130 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所)
0x00000000 0xFFFFFFFF
メモリについて 131 コード領域 (実行するプログラムの場所) データ領域 (実行のためのデータの場所) ヒープ領域 (動的に確保するメモリの場所) スタック領域 (一時変数などに使用するメモリの場所)
ヒープ領域は 下に向かって(アドレスの大きい方に) 領域が増えていく 0x00000000 0xFFFFFFFF
ヒープについて 132 ヒープ
ヒープについて 133 ヒープ 管理領域(ヒープ管理のための場所) データ領域 (実際にユーザが使えるメモリの場所) malloc ptr
ヒープについて 134 ヒープ 管理領域(ヒープ管理のための場所) データ領域 (実際にユーザが使えるメモリの場所) free ptr 管理領域(重なる部分もある)
Where is the BUG ? (CWE-122.c) 135
Where is the BUG ? (CWE-122.c) 136
What is the EVIL input? 137 ?
What is the EVIL input? ‘A’*24+’Overwrite!’ 138
CWE-122 Heap-based Buffer Overflow 概要:ヒープ上で割り当てたメモリ領域の大きさを超えたデータが書き込まれること サンプル:gets関数によって割り当てたヒープ上のメモリ領域の大きさを超えて 別のメモリ領域に書き込んでいる 139 https://cwe.mitre.org/data/definitions/122.html 割り当てたメモリ領域に対して
入力サイズを合わせるべきだった
malloc malloc ヒープ上のオーバーフローで上書きできるワケ 140 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1
ptr2
ヒープ上のオーバーフローで上書きできるワケ 141 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1 ptr2 入力されたデータ
入 力 の 流 れ
ヒープ上のオーバーフローで上書きできるワケ 142 ptr2が指し示す メモリ領域 ptr1が指し示す メモリ領域 ヒープ ptr1 ptr2 入力されたデータ
上書きされた領域 入 力 の 流 れ
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
メモリの状態 144 ptr1の示すメモリ領域 上書きされた部分 ptr2の示すメモリ領域
Where is the BUG ?? (CWE-244.c) 145
Where is the BUG ?? (CWE-244.c) 146
What is the EVIL input? ? 147
What is the EVIL input? 37 ~ 4096 148
CWE-224 Clearing of Heap Memory Before Release (‘Heap Inspection’) 概要:reallocを使った際に重要なデータをそのまま残してしまうこと
サンプル:reallocするサイズを極端に小さくしなければ残ったパスワードが表示される 149 https://cwe.mitre.org/data/definitions/244.html ptr2の内容に入力する前に ゼロクリアすべきだった
malloc reallocで割り当てたメモリの中身 150 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1
reallocで割り当てたメモリの中身 151 ヒープ ptr1 書き込んだデータ
realloc reallocで割り当てたメモリの中身 152 reallocで再度割り当てた領域 ヒープ ptr1 書き込んだデータ ptr2
reallocで割り当てたメモリの中身 153 reallocで再度割り当てた領域 ヒープ ptr1 書き込んだデータ 書き込んだデータは そのまま残ってしまう (サイズを小さくした場合は 差分だけが消える)
ptr2
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
メモリの状態 155 mallocの返り値も reallocの返り値も 一緒になっている $2の指し示す場所には 元から格納されていた 文字列がある
Where is the BUG ??? (CWE-415.c) 156
Where is the BUG ??? (CWE-415.c) 157
What is the EVIL input? ? 158
What is the EVIL input? ‘A’ * 9 ~ 159
CWE-415 Double Free 概要:一度freeしたメモリ領域を再度freeすること サンプル:文字列の長さを10にすると2回freeされてしまう 160 https://cwe.mitre.org/data/definitions/415.html 最後にまとめてfreeすべきだった (条件分岐内で分けて freeを書かなくてよかった)
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
メモリの状態 162 どちらも同じ値 (freeへの引数が どちらも一緒)
Where is the BUG ???? (CWE-416.c) 163
Where is the BUG ???? (CWE-416.c) 164
What is the EVIL input? ? 165 ?
What is the EVIL input? 3→4→AAA 166 4
CWE-416 Use After Free 概要:freeしたあとにNULL代入をせず再度使用すること サンプル:一度freeしたメモリ領域をそのまま使うことで 中に入っていたデータを抜き出すことができる 167 https://cwe.mitre.org/data/definitions/416.html freeした後のポインタは
NULLを代入しておくべきだった
malloc freeの後にNULL代入せずに使用すると 168 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1
freeの後にNULL代入せずに使用すると 169 ptr1が指し示す mallocで割り当てた メモリ領域 ヒープ ptr1 入力したデータ
free freeの後にNULL代入せずに使用すると 170 freeした際の管理データ ヒープ ptr1 入力したデータ
freeの後にNULL代入せずに使用すると 171 freeした際の管理データ ヒープ ptr1 入力したデータ NULL代入されてないptr1を使うことで 管理データを書き換えたり 入力したデータを 読み取ったりすることができる
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
メモリの状態 173 管理領域の部分が 0クリアされている freeされたptrが指し 示すメモリ領域 管理領域の部分に 書き込んでいる
Level5 : Flying CWE-??? / CWE-??? / CWE-??? / CWE-???
/ CWE-??? 174
ここまでの集大成として プログラムの中から 脆弱性を探してみましょう! 今までに学んだ知識を総動員して 取り組んでみてください! 175
出題するプログラムについて ls,wc,strings,rev,whichのコマンドを真似したプログラムです (実際の動作とは異なっていますが、気にしないでください) 各プログラムから脆弱性を探してください こうなったら正解です ・プログラムが異常終了する ・本来の動作とは異なる動きをした(予想の動作と異なった) 想定解以外もあるかもしれません 176
Where is the BUG? (ls_vuln.c) 177
Where is the BUG?? (wc_vuln.c) 178
Where is the BUG??? (strings_vuln.c) 179
Where is the BUG???? (rev_vuln.c) 180
Where is the BUG????? (which_vuln.c) 181
Re:Level5 Flying with Conpass CWE-??? / CWE-??? / CWE-??? /
CWE-??? / CWE-??? 182
This is the BUG! (ls_vuln.c) 183
PoC 184
This is the BUG!! (wc_vuln.c) 185
PoC 186
This is the BUG!!! (strings_vuln.c) 187
PoC 188
This is the BUG!!!! (rev_vuln.c) 189
PoC 190
This is the BUG!!!!! (which_vuln.c) 191
PoC 192
Thank you for your attention! (おつかれさまでした!) 193