Return Oriented Programming(ROP) -x64
- ROP( Return-oriented programming )는 공격자가 실행 공간 보호(NXbit) 및 코드 서명(Code signing)과 같은 보안 방어가있는 상태에서 코드를 실행할 수있게 해주는 기술이다.
- RTL + Gadgets
- 이 기법에서 공격자는 프로그램의 흐름을 변경하기 위해 Stack Overflow 취약성이 필요하고, "가젯(Gadgets)"이라고 하는 해당 프로그램이 사용하는 메모리에 이미 있는 기계 명령어가 필요하다.
- 각 가젯은 일반적으로 반환 명령어(ret)로 끝이나며, 기존 프로그램 또는 공유 라이브러리 코드 내의 서브 루틴에 있다.
Gadgets - POP; POP; POP; RET
x86의 경우 pop 명령어의 피연산자가 중요하지 않았지만, x64에서는 호출 규약 때문에 피연산자가 매우 중요하다.
x64의 ROP에서 POP 명령어의 역할은 다음과 같다.
- ESP 레지스터의 값을 증가시켜 함수를 연속으로 호출하는 것
- 호출할 함수에 전달될 인자 값을 레지스터에 저장하는 것
- 인자 값은 Stack에 저장되어있음
- 해당 역할 때문에 필요한 Gadgets을 찾기가 어려워짐
예를 들어 다음과 같은 형태의 Gadgets을 사용 된다.
- 호출할 함수의 첫번째 인자 값을 저장 : "pop rdi; ret"
- 호출할 함수의 두번째 인자 값을 저장 : "pop rsi; ret"
- 호출할 함수의 첫번째, 세번째 인자 값을 저장: "pop rdi; pop rdx; ret"
다음과 같은 방법으로 여러 개의 함수를 연속해서 실행할 수 있다.
- x64에서는 Gadgets을 이용해 인자 값을 레지스터에 저장한 후에 함수를 호출한다.
- 아래 예제는 read() 함수 호출 후 System() 함수를 호출하게 된다.
Overflow
다음과 같이 Breakpoints를 설정한다.
- 0x400756: vuln 함수 코드 첫부분
- 0x40079a: read() 함수 호출 전
read 함수의 인자인 buf의 시작주소는 rsi 레지스터가 가르키고 있음.
offset : 72
Exploit method
ROP 기법을 이용한 Exploit의 순서는 다음과 같다.
- setresuid 함수를 이용해 권한을 root(0)으로 변경
- system 함수를 이용해 "/bin/sh" 실행
이를 코드로 표현하면 다음과 같다.
setresuid(0,0,0)
system(binsh)
payload를 바탕으로 공격을 위해 알아내어야 할 정보는 다음과 같다.
1. "/bin/sh"문자열이 저장된 영역
2. libc offset
- printf
- system
- setresuid
3. 가젯의 위치
- pop rdi,ret
- pop rsi,ret
- pop rdx,ret
그렇다면 이제 필요한 것들을 모두 찾아보자!
Find the Libc address of the "/bin/sh"
"/bin/sh" offset : 0x18ce17
Get offset of printf, system, and setresuid functions
위와 같이 offset을 확인할 수 있다.
printf(libcbase) : 0x55810
system : 0x453a0
setresuid : 0xcd5f0
Find gadget using rp++
/rp-lin-x64 -f /lib/x86_64-linux-gnu/libc-2.23.so -r 2 | grep "pop rdx"
0x00115189 영역에 "pop rdx ; pop rsi ; ret ;" 코드를 사용하겠다.
pop rdi; ret : 0x400843
pop rsi; pop r15; ret : 0x400841
Exploit
위의 논리대로 exploit 코드를 짜보았다.
참고
https://www.lazenca.net/display/TEC/02.ROP%28Return+Oriented+Programming%29-x64
'Hacking > Pwnable' 카테고리의 다른 글
[P4C] Pwnable problem 1 (0) | 2021.04.10 |
---|---|
[Pwnable] python으로 인자 및 stdin 전달 (0) | 2021.04.01 |
[Pwnable] Lazenca - ROP(x86) 정리 (0) | 2021.03.29 |
[Pwnable] PLT, GOT (0) | 2021.03.21 |
[Pwnable] Lazenca - RTL(x64) 정리 (0) | 2021.03.21 |