Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CWEから学ぶ脆弱性

happynote3966
November 04, 2018

 CWEから学ぶ脆弱性

セキュリティ・ミニキャンプ in 北海道 2018で発表したスライド資料です

happynote3966

November 04, 2018
Tweet

More Decks by happynote3966

Other Decks in Technology

Transcript

  1. 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()が実行される
  2. 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
  3. 書式文字列と引数の関係(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)”へのポインタ ?????????????????????????? ?????????????????????????? ?????????????????????????? 参照 参照 スタック
  4. 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
  5. 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という扱いになる
  6. C言語における文字列 67 A B C D E F G H

    I J K L ... 0x80486b4 文字列本体 0x80486b4 alphabetの値 変数(または定数)は 文字列の「アドレス」を保存している ? ? ? ? ? ? ? ? ? ? ? ? ... 0x0(NULL) ???????? 0x0 小文字入力時の pointerの値 アドレスが0の場所には 何もない(アクセス禁止)
  7. メモリについて 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 データ
  8. スタックについて 79 スタック 引数2 引数1 リターンアドレス(制御データ) ローカル変数 push pop リターンアドレスや

    引数などは スタックにpushされる ローカル変数は スタック領域を増やすことで 確保している (pushやpopではない)
  9. スタック上でバッファオーバーフローが起きる時 86 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 入力用バッファ (データを入力する場所) データ入力後 重要なデータ

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

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

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

    (リターンアドレスや文字列など) 入力用バッファ (データを入力する場所) 入力されたデータ 上書きされてしまった部分 入 力 の 流 れ スタック スタック
  14. 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
  15. スタック上でバッファオーバーリードが起きる時 106 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ

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

    (リターンアドレスや文字列など) 重要なデータ (リターンアドレスや文字列など) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック
  17. GDBで見てみる 108 $ gdb -q CWE-126 (gdb) b *main+149 (gdb)

    run (入力) A (入力) 24 (gdb) x/20xw $ebp - 0x28
  18. スタック上でバッファアンダーリードが起きる時 116 下位アドレス (数字が小さい) 上位アドレス (数字が大きい) 出力用バッファ (出力データがある場所) データ出力後 重要なデータ

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

    (リターンアドレスや文字列など) 出力用バッファ (出力データがある場所) 出力されたデータ 余計に出力されて しまった部分 (重要なデータ含む) 出 力 の 流 れ スタック スタック
  20. GDBで見てみる 118 $ gdb -q CWE-127 (gdb) b *main+145 (gdb)

    run (入力) A (入力) -24 (gdb) x/20xw $ebp - 0x38
  21. What is the EVIL input? ‘A’ * 15 123 ※16文字以上の入力でも可 ただしその場合は一度で

    loginを実行できない 16文字の入力の場合、 ’\n’の文字がバッファに貯まるため、パスワード入力時に失敗する
  22. 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つの文字列
  23. 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
  24. 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
  25. CWE-224 Clearing of Heap Memory Before Release (‘Heap Inspection’) 概要:reallocを使った際に重要なデータをそのまま残してしまうこと

    サンプル:reallocするサイズを極端に小さくしなければ残ったパスワードが表示される 149 https://cwe.mitre.org/data/definitions/244.html ptr2の内容に入力する前に ゼロクリアすべきだった
  26. 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
  27. 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
  28. 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