私はInfoSec研究所でこの記事を読んでいました。
http://resources.infosecinstitute.com/an-introduction-to-returned-oriented-programming-linux/#gref
そして、彼がROPチェーンを行うまで、追跡することができました。
彼はprintfとexecveのオフセットが328160であることを発見しました。
次に、次のROPガジェットを見つけます。
0x804886eL: add eax [ebx-0xb8a0008] ; add esp 0x4 ; pop ebx
0x804861fL: call eax ; leave ;;
0x804849cL: pop eax ; pop ebx ; leave ;;
私はexecveの絶対アドレスをeaxにロードしてからeaxを呼び出すことを理解していますが、私が迷うのは彼のやり方です。
ガジェット:
0x804886eL: add eax [ebx-0xb8a0008] ; add esp 0x4 ; pop ebx
Eaxと[ebx-0xb8a0008]を追加し、次のガジェットが呼び出すためにeaxに保存します。
現在の目標は、ebxにprintf @ gotの絶対アドレスを含めることですが、代わりに0x138e9ff4をebxにロードします。理由は次のとおりです。
printf @ got + 0xb8a0008 = 0x138e9ff4
ASLRが有効になっていて、printf @ gotは毎回異なる必要があるため、彼が値0x138e9ff4を計算する方法がわからないので、ebxにロードされる値も必要です。
あなたが持っている任意の入力をいただければ幸いです
私はそれが記事で非常に不十分に説明されていることに同意します。いったい何が起こっているのかを理解するのに何回か読んだ。
重要な部分はここにあります:
ここでの目的は、execve()を実行するための連鎖ROPを構築することです。ご覧のとおり、この関数のGOTエントリはなく、libcはランダム化されています。
まず、GOTのlibc関数アドレスをリークし、簡単な計算を行って、正確なexecve libcアドレスを取得します。
彼らは、単一のlibc関数がどこにあるかを知らせる情報漏えいがあると想定しています。この場合、例としてprintfを使用しています。
そこから、エクスプロイトはもっと理にかなっています:
最初のステップは、pop; pop; leave
ガジェットを使用して、eaxに0x328160を、ebxに0x138e9ff4を入力することです。そのadd
命令が実行されると、0x138e9ff4-0xb8a0008 = 0x8049fecが計算されます。これは、例のprintf @ gotのアドレスです。これは、printfのグローバルオフセットテーブル(GOT)エントリのアドレスであり、実際のprintf関数自体のアドレスではないことに注意してください。 GOTのベースアドレスは、通常のLinuxではランダム化されていません(grsecで強化されたカーネルにある可能性があります。まだ調べていません)。
これで、命令は基本的にadd eax, [0x8049fec]
になります。攻撃者はlibcのターゲットバージョンのprintfとexecveの間の距離が0x328160であることを知っているため、この命令が実行されると、GOTからprintf関数のアドレスが取得され、それに0x328160が追加されます(ポップによってプリロードされたeaxから)ポップリーブ)execveのアドレスをeaxにロードします。
次に、call eax
がexecveを実行します。