BuringStraw

BuringStraw

ROPリターンオリエンテッドプログラミング

ゼロから一までの最初のパスを理解できなかった部分をメモしておきます。

長い議論:#

現代のオペレーティングシステムでは、一般的には MPU(メモリ保護ユニット)メカニズムがあり、メモリページの単位でプロセスのメモリ使用権限を設定できます。メモリの権限には読み取り(R)、書き込み(W)、実行(X)があります。CPU が実行権限のないメモリ上のコードを実行すると、オペレーティングシステムはプログラムを即座に終了します。

デフォルトでは、脆弱性緩和のルールに基づいて、プログラムには書き込みと実行の両方の権限を持つメモリは存在しません。そのため、プログラムのコードセグメントやデータセグメントを変更して任意のコードを実行することはできません。このような脆弱性緩和メカニズムに対して、特定の命令シーケンスにプログラムを戻すことでプログラムの実行フローを制御する攻撃技術があり、それがリターンオリエンテッドプログラミング(Return-Oriented Programming、ROP)と呼ばれています。

ret(0xc3)命令で終わる命令フラグメント(ガジェット)を使用して ROP チェーンを構築し、任意の命令の実行を実現し、最終的に任意のコードの実行を実現します。具体的な手順は次のとおりです:プログラムで実行可能なメモリセグメント内のすべての ret 命令を検索し、ret の前のバイトに有効な命令が含まれているかどうかを確認します。有効なフラグメントとしてマークされた場合、一連の ret で終わるこのような命令を見つけた後、これらの命令のアドレスを順番にスタックに配置します。これにより、対応する命令を実行した後、その終わりの ret 命令がスタックのトップにある新しい Gadget にプログラムの制御フローを渡します。スタック上のこの連続した Gadget は ROP チェーンを構成し、任意の命令の実行を実現します。

手順:#

サンプルコード:https://buuoj.cn/challenges#[第六章 CTF 之 PWN 章] ROP

ROPgadget --binary ropを使用してすべてのガジェットを取得します。

ガジェットが少なすぎるため、libc のロードアドレスを取得し、その中から syscall を見つける必要があります。

このペイロードを使用すると、puts のアドレスを取得できます(pop_rdi は pop rdi のガジェットです)。

具体的な原理:

リターンアドレスは 0x12 バイト後にあります。

leaveを実行するときにpop_rdiがスタックのトップにあります(上記のものはクリアされました)。

retを実行すると、pop_rdiが存在するアドレスにジャンプし、スタックのトップのpop_rdiをポップします。その後、スタックトップはputs_gotです。

puts_gotputsの実際のアドレスを指すポインタです。

次に、pop_rdiを実行して、puts_gotrdiに配置します。

putsに ret し、呼び出し規約に従って(既存の puts 呼び出しを参照)、rdiputsの引数なので、アドレスが出力されます。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。