ブウリップ
具体的なWPについては、他のブロガーのWPを参考にしてください。
ここでは、これら 2 つのペイロードがどのようにして成功するかについて、私の理解の一部のみを共有します。
payload = b'a' * 23 + p64(0x401186 + 1)
payload = b'a' * 23 + p64(0x401198) + p64(0x401186)
関連する知識ポイント:
- スタックのアライメント: スタック ポインターは 16 バイトで割り切れる必要があります (ただし、私が使用している 64 ビットの Ubuntu20 は 8 バイトです)
これら 2 つのペイロードが使用できる理由については、私が理解しているところによると、スタックのアライメントとは何の関係もないようです。理由としては、システム関数内にxxm0の値が16バイトで割り切れる命令があり(スタックアライメントの意味かもしれませんが、その点は気づきませんでした)、xxm0の値が16バイトで割り切れる必要があるためです。 RSPと関係があります。具体的な参照リンク: http://blog.enew.cn/archives/958。次に、これら 2 つのペイロードが利用できる理由を説明します。
payload = b'a' * 23 + p64(0x401186 + 1)
0x401186 は、プログラム pwn1 の system("\bin\sh") の開始アドレスに対応します。最初の命令はスタック命令プッシュ rbp で、これによりスタックの長さが変更されます。つまり、rsp が変更されます。次の命令に直接ジャンプしても、システム関数の通常の呼び出しには影響しません。Push rbp は前の関数のスタック フレームを保存することですが、ここではシステム関数を実行することが目的なので、後で前のスタック フレームを復元する必要はありません。
したがって、このステートメントによれば、実際に Push rbp 命令を nop すれば、ペイロードで +1 を付けずにこの命令を使用できるようになります。
payload = b'a' * 23 + p64(0x401198) + p64(0x401186)
アドレス 0x401198 の対応する命令は ret であり、ペイロードにはさらに 8 バイトあることを意味します。システム関数のプッシュ命令の 8 バイトの影響と相まって、依然として 16 バイトで均等に分割して実行できます。通常は。
上記はあくまで私の個人的な理解ですので、間違いがございましたらご批判、ご指摘をお願いいたします。