メモリとスタック
オーバーフローの仕組み
「メモリとスタック」はCoddyKit上の無料Ethical Hacking Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはEthical Hacking Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ethical Hacking Academyコースには全4レッスンが含まれています。
プロセスメモリのレイアウト
プログラムを実行すると、オペレーティングシステムはプログラムに、複数の領域に分かれたメモリレイアウトを割り当てます。具体的には、text(コード)、data/BSS(グローバル変数)、heap(動的割り当て)、stackです。
バッファオーバーフローは多くの場合スタックを悪用するため、その仕組みを理解することが不可欠です。
スタックとは
stackは、関数呼び出しに使われるメモリ領域です。ローカル変数、関数の引数、リターンアドレスを保存します。
x86では、スタックは下方向に成長します。データをプッシュすると、スタックポインターは低位アドレス側へ移動します。オーバーフローが発生したとき、この方向が重要になります。
スタックフレーム
関数を呼び出すたびにスタックフレームが作成されます。通常、フレームにはローカル変数、保存されたベースポインター(EBP)、リターンアドレス(保存されたEIP)が含まれます。
リターンアドレスは、関数の処理が終了した後にCPUがどこから実行を再開するかを示します。これを制御することが、スタックオーバーフロー悪用の核心です。
主要なレジスター
32ビットx86で重要なレジスターは次のとおりです。
- ESP:スタックポインター。スタックの先頭を指します。
- EBP:ベースポインター。現在のフレームの基準となります。
- EIP:命令ポインター。次に実行する命令のアドレスを指します。
EIPを制御できれば、実行フローを制御できます。
バッファとは
bufferは、ローカルの文字配列など、サイズが固定されたメモリ領域です。プログラムは、データがその領域内に収まることを想定しています。
プログラムが長さを確認せずに、バッファの容量を超えるデータをコピーすると、余分なデータが隣接するメモリ領域へあふれ出します。
char buffer[64];
strcpy(buffer, user_input); // no bounds checkオーバーフロー
バッファオーバーフローは、入力がバッファのサイズを超え、スタック上で隣接するデータを上書きすると発生します。
保存されたEBPとリターンアドレスはローカルバッファのすぐ後ろに配置されるため、十分に長い入力を与えるとリターンアドレスを上書きし、制御フローを乗っ取ることができます。
危険な関数
オーバーフローは通常、長さをチェックしない安全でないC関数が原因で発生します。
strcpy、strcat、sprintf、getsです。
strncpyやsnprintfのようなより安全な代替関数はサイズ制限を受け取りますが、レガシーコードには危険な関数が数多く残っています。
gets(buffer); // never use: no length limit at allEIPを上書きすると何ができるか
脆弱な関数から戻るとき、CPUは(攻撃者が制御する)リターンアドレスをEIPに取り出し、そこへジャンプします。
EIPを自身が注入したマシンコード(shellcode)の位置に設定すると、CPUはプログラムの権限でそれを実行します。
リトルエンディアンのアドレス指定
x86はリトルエンディアンです。複数バイトの値は最下位バイトから格納されます。リターンアドレスを0x080414C3で上書きするには、バイトを逆順に書き込みます。
エンディアンを間違えるのは初心者によくあるミスで、エクスプロイトが何のエラーも出さずに失敗する原因になります。
address 0x080414C3 -> bytes \xc3\x14\x04\x08最新の防御機構
最新のシステムには、エクスプロイトを難しくする防御機構が追加されています。
- DEP/NX:スタックを実行不可としてマークします。
- ASLR:メモリアドレスをランダム化します。
- スタックカナリア:リターン前に上書きを検出します。
このコースでは基礎を学ぶため、古典的なケース(防御機構が無効)に焦点を当てます。
それでも重要である理由
最新の防御機構によって古典的なスタックオーバーフローは難しくなっていますが、基礎は依然として不可欠です。組み込みシステム、IoT、レガシーソフトウェアには、こうした防御機構がまったくない場合がよくあります。
基本ケースを習得することは、最新の緩和策を回避するROPのような高度な手法を学ぶ前提条件でもあります。
クイックチェック
攻撃者が最終的に制御したい値を思い出してください。
まとめ
これで基礎を理解できました。
- スタックにはローカル変数、保存されたEBP、リターンアドレスが格納され、下方向に伸びます。
- ESP、EBP、EIPは主要なx86レジスタです。EIPを制御すると実行を制御できます。
strcpyやgetsのような安全でない関数がオーバーフローを引き起こします。- x86はリトルエンディアンであり、最新の防御機構はDEP、ASLR、カナリアです。
次はプログラムをファジングして、クラッシュオフセットを見つけます。
よくある質問
「メモリとスタック」レッスンは無料ですか?
はい。「メモリとスタック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ethical Hacking Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ethical Hacking Academyコースには全4レッスンが含まれています。
「メモリとスタック」で何を学びますか?
オーバーフローの仕組み ブラウザで直接実行するハンズオンコードでEthical Hacking Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Ethical Hacking Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのEthical Hacking Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「メモリとスタック」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このEthical Hacking Academyレッスンでコードを書いて実行できますか?
はい。すべてのEthical Hacking Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。