投稿

11月, 2020の投稿を表示しています

11月18日(水)1コマ目

イメージ
今日、やったこと バッファオーバーフローの確認テスト1 今日のテスト 一応、解答例を公開します。 図 解答例(設問1、設問2) 設問1 バッファオーバーフローはコピー先にサイズにかかわらずデータを書き込むことで発生します。プログラムでこのようなことをしているのは15行目のstrcpy()です。 ということで、 15行目 が正解。 設問2 printf("You are Administrator\n");の実行命令がコードエリアのどこにロードされているのか確認するには、デバッガ(GDB)のdisasコマンドでmain()関数を逆アセンブルして確認します。 図 設問2 disasコマンド出力結果 disasコマンドの出力結果から 0x0000 0000 0040 080b 番地からprintf("You are Administrator\n");の命令が始まることがわかります。 ただし、これは全員同じ値になる保証はなにもないため、明らかにおかしい値(例えば、0x7fff・・はスタックエリア)以外は正解にしています。 図 解答例(設問3) 設問3 これもデバッガで確認する問題です。 getuid()関数内にブレークポイントをセットして実行、停止時に各変数のアドレスを確認します。 図 設問3 変数cnt、uid、buffのアドレス確認 図 設問3 disasコマンド出力結果からリターンアドレスを確認 図 設問3 値からリターンアドレスが格納されるエリアを特定する 図 解答例(設問4,設問5) 設問4 このプログラムはコマンドライン引数(ユーザー名:ユーザーID)の:以降を15行目で配列buffに\0まで書き込みます。このとき、バッファオーバーフローが発生します。 スタック上の各変数およびリターンアドレスが書き込まれるエリアの並びを確認すると、配列buffの先頭から25バイト目以降にリターンアドレスがあります。ということは、buffの先頭から24バイトは適当な値、25バイト目以降に飛ばしたいアドレス(設問2で確認したアドレス)を書き込めばOKです。 ということで、正解は   a.out ユーザー名:[24バイト分のデータ][設問2で確認したアドレス] となります。 設問5 そもそもstrcpy()は危険すぎます。 何バイト書き込むか...

11月25日(水)1コマ目

イメージ
今日の予習 スレッドに関する内容を扱います。 スレッドのライフライクル スレッドは新規作成から終了まで下図のように状態が変わります。 新規作成 Threadクラスのインスタンス生成された時であり、まだこの時点ではシステム資源(CPU)は割り当てされていません。 実行可能状態 start()メソッドが実行されると新規作成状態から実行可能状態になります。この状態でもまだ処理は行われません。 スレッドには優先順位があり、実行可能状態のスレッドは実行可能キューで順番待ちをしています。順番が回ってくると実行中となります。 実行中 スレッドにシステム資源が割り当てられ、スレッドの処理が実行されている状態です。 「実行中」の遷移先は次の3つに分かれます。 ○より優先順位の高いスレッドが発生したとき 「実行可能状態」へ ○wait()、sleep()メソッドが実行された、入出力等で処理の遅延が発生した、排他制御でロックされたとき 「待ち状態」へ ○処理が完了したとき 「終了」へ 終了 run()メソッド内の処理が終わり、スレッドが消滅した状態や、run()メソッド実行中に例外が発生して途中で終了した状態です。 今日、やったこと バッファオーバーフロー確認テストの解説 今日のホワイトボード 確認テストの解説 先週のページ に解説を載せておきました。こちらもご参考ください。 メモリ プログラム実行のさい、メモリは下表の3つのエリアを使います。 コードエリア 実行する命令が置かれる。 メモリ番地の低位アドレスからエリアが確保される ヒープエリア 大きめのデータ用のエリア。C言語でmalloc()で確保する...

11月11日(水)1コマ目

イメージ
今日、やったこと バッファオバーフロー 今日のホワイトボード 今日も脆弱性のあるプログラムにバッファオーバーフローを仕掛けるお題です。 もう、見飽きた感がある「メモリ上のコードエリア」と「メモリ上のスタックエリア」で説明をしました。 図 メモリのコードエリアとスタックエリア 次回、紙のテストをします。

11月4日(水)1コマ目

イメージ
今日、やったこと バッファオーバーフロー 今日のホワイトボード 前回のおさらい 〇バッファオーバーとは メモリ上の別変数のエリアを誤って上書きしてしまうこと。 strcpy()やmemcpy()などコピー先のサイズに関係なくコピーをしてしまう関数は要注意! 〇プログラムの実行コードは コンパイルすると実行コードが出来上がる。 プログラムを実行すると、実行コードがメモリのコードエリアと呼ばれる領域にロードされ、下位アドレスから1つづつ順に実行していく。 図 コードエリア(左側) 〇スタックエリアには 関数呼び出し時にスタックエリアに引数やローカル変数のエリアが確保される。 メモリ上の高位アドレスから低位アドレスに向かってエリアが確保されるため、よく「積み上げられる」と言ったりする。 関数呼び出し時にスタックエリアに確保されるのは、引数やローカル変数だけではなく、関数実行後に戻るべきアドレス(リターンアドレス)も書き込まれる。 図 スタックエリア(右側) 〇リターンアドレスを調べる デバッガのdisasコマンドで実行コードを逆アセンブル。 このとき、/mオプションをつけるとCのソースとセットで出力されるために、アセンブラとCの対比ができる。 チェックすべきは関数呼び出し部分。アセンブラでは「callq」命令で関数の実行コードを呼び出している。 関数実行後は「callq」の次の命令「test」を実行する。ここに帰ってくるため、スタック上のリターンアドレスは「test」が格納されているアドレス番地が書き込まれる。 図 リターンアドレスを調べる 〇スタック上のリターンアドレスの位置を確認 関数内のstrcpy()実行直後にブレークポイントを設定して実行する。 デバッガのxコマンドでローカル変数を先頭にスタックエリアをチェックすると、図のようなイメージ。 リターンアドレスはわかっているため、値をもとにどこにあるか確認できる。 ここをバッファオバーフローの脆弱性を使って書き換える。 図 スタックエリア 〇リターンアドレスを書き換える そもそもこのプログラムはコマンドライン引数をそのままコピーしているため、簡単にバッファオーバーフローを引き起こし、さらに書き込む値もコントロールできる。 今日のネタ 同じようなプログラムをもとに自分でバッファオーバーフローを引き起こして、プログラムを...