BuringStraw

BuringStraw

ROP戻り指向プログラミング

ゼロから一の最初の回で理解できなかった部分を記録する

長文:#

現代のオペレーティングシステムは、比較的整った MPU メカニズムを持っており、メモリページの粒度に従ってプロセスのメモリ使用権限を設定できます。メモリ権限には、読み取り可能(R)、書き込み可能(W)、および実行可能(X)が含まれます。一度 CPU が実行権限のないメモリ上のコードを実行すると、オペレーティングシステムは直ちにプログラムを終了します。

デフォルトでは、脆弱性緩和のルールに基づき、プログラム内には同時に書き込み可能かつ実行可能なメモリは存在しないため、プログラムのコードセクションやデータセクションを変更して任意のコードを実行することはできません。このような脆弱性緩和メカニズムに対抗するために、プログラム内の特定の命令列に戻ることでプログラムの実行フローを制御する攻撃技術が存在し、これをリターン指向プログラミング(Return-Oriented Programming、ROP)と呼びます。

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

プロセス:#

例: https://buuoj.cn/challenges#[第六章 CTF 之 PWN 章] ROP

ROPgadget --binary ropを使用してすべての gadget を取得

少なすぎるので、libc のロードアドレスを取得し、その中で syscall を探す

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

具体的な原理:

戻りアドレスは 0x12 バイト後にあります、

leaveに到達したときにpop_rdiがスタックのトップにあります(上のものはクリアされています)

retに到達すると、pop_rdiのあるアドレスにジャンプし、スタックのトップのpop_rdiをポップしますので、その後スタックのトップはputs_gotになります

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

その後pop_rdiを実行し、puts_gotrdiに入れます。

putsに ret し、呼び出し規約に従い(プログラムに既存の puts 呼び出しを参照)、rdiputsの引数であるため、アドレスが出力されます。

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