Lazenca | RTL(Return to Libc) – x64

133210·2021년 7월 26일
0

2020 시스템

목록 보기
19/25
post-thumbnail

1 System V AMD64 ABI

Solaris, Linux, FreeBSD, macOS에서 “System V AMD64 ABI” 호출 규약을 사용함. Unix, Unix 계열 운영체제의 표준
∙ 레지스터 RDI, RSI, RDX, RCX, R8 및 R9정수 및 메모리 주소 인수가 전달됨
∙ 레지스터 XMM0, XMM1, XMM2, XMM3, XMM4, XMM4, XMM5, XMM6 및 XMM7부동 소수점 인수가 전달됨.

4개의 인자를 전달 받고, 반환값은 ret 변수에 저장함

앞 코드를 cdecl 형태의 assembly code로 변환. 4개의 인자 값을 mov 명령어를 이용해 레지스터에 저장. 함수 호출 후 반환된 값은 EAX 레지스터에 저장되며, 해당 값을 ret 변수에 저장

2 Example

∙ 앞 x86의 test 코드를 아래와 같이 Build

System V AMD64 ABI 함수 호출 규약 형태를 확인 가능.
main() 함수에서 vuln() 함수의 인자 값을 mov 명령어를 이용해 각 레지스터에 저장

각 레지스터에 저장된 vuln() 함수의 인자 값 확인 가능

vuln() 함수는 printf() 함수에 인자를 전달하기 위해 인자를 재배치 함
printf() 함수의 첫번째 인자는 “%d, %d, %d, %d”. 이로 인해 각 레지스터 값이 재배치 됨

각 레지스터에서 printf() 함수에 전달되는 인자 값 확인 가능

ret2libc 기법을 사용하기 위해서는 각 레지스터에 값을 저장할 수 있어야 함.
Return Address 영역에 “pop rdi, ret” 코드가 저장된 주소 값을 저장
Return Address 다음 영역에 해당 레지스터에 저장 할 인자 값 저장
그 다음 영역에 호출 할 함수의 주소 저장. 이러한 방식을 ROP라고 함

3 Proof of concept

∙ x86에서 사용했던 코드를 다음과 같이 Build

0x400676: vuln() 함수의 첫번째 명령어
0x4006e0: read() 함수 호출
0x4006e7: vuln() 함수의 RET 명령어

ESP 레지스터가 가리키고 있는 최상위 Stack의 주소는 0x7fffffffe498
0x7fffffffe498 영역에 Return address(0x4006f6)가 저장되어 있음

buf 변수의 위치는 0x7fffffffde50이며, Return address 위치와 72byte 떨어져 있음

Return address 값이 변경된 것 확인 가능 (0x7fffffffde98 영역에 0x4a4a4a4a4a4a4a4a이 저장됨)

Libc 영역에서 System() 함수의 주소 찾을 수 있음

“/bin/sh” 문자열 또한 찾을 수 있음

pwndbg에서는 ropsearch 명령어가 존재하지 않음

4 Exploit

0개의 댓글