상세 컨텐츠

본문 제목

0x03 - x64 ROP(Return Oriented Programming)

카테고리 없음

by 킹갓해커다똥 2020. 12. 17. 14:28

본문

x64 ROP(Return Oriented Programming)

이번 문서에서는 RTL에 이어 64비트 환경에서의 ROP를 다루겠습니다. ROP는 NX bit와 ASLR 보호기법, 코드 서명과 같은 보호기법을 우회할 수 있는 공격 기법입니다. NX bit만 걸려있을때는 RTL 기법으로 공격이 가능하나, ASLR과 같은 보호기법이 적용되었을때는 스택이 랜덤화되어 ROP를 이용해줘야 합니다. 이전 문서에서 얘기했듯이 64비트는 레지스터 기반이기 때문에 ROP에서도 마찬가지로 프로그램이 사용하는 메모리에 있는 가젯(gadgets)이라고 불리는 기계 명령어를 사용해야 합니다.
Lazencax64bit 예제를 기준으로 ROP를 진행하겠습니다. 아래는 예제 코드입니다. read 함수에서 buf의 50의 크기보다 더 큰 256바이트의 값을 쓸 수 있는 부분에서 버퍼오버플로우가 발생하네욧!

해당 파일을 gcc로 컴파일하겠습니다.

컴파일한 바이너리 파일의 소유자와 그룹을 root로 소유권을 설정 해준 뒤, setuid를 활성화 시켜줍니다.

공격은 아래와 같은 순서로 진행합니다.
1. setresuid 함수를 이용해 권한을 root(0)으로 변경
2. system함수를 이용해 "/bin/sh" 실행

공격에 필요한 조건은 ret까지의 거리, "/bin/sh",printf, system, setresuid의 오프셋거리, rdi/rsi/rdx 레지스터을 사용할 수 있는 가젯(setresuid의 인자가 총 3개니까 3번째 인자까지 전달 가능한 rdi/rsi/rdx 레지스터 필요)
ROP를 하기 위해선 첫번째로 ret까지의 거리를 구해야겠죳? push rbp에 브레이크 포인트를 걸어 초기 rsp( 즉 ret의 주소)를 구합니다.

브레이크 포인트는 아래와 같이 걸면됩니다.

브레이크 포인트를 건 후 프로그램을 실행시킵니다.

레지스터 정보를 확인해보면 rsp의 값이 0x7ffe8f30b4f8 인것을 확인할 수 있습니다!

이번에는 buf 변수의 주소를 확인하기 위해 read 함수 위치에 브레이크 포인트를 건 후 프로그램을 실행시킵니다.

레지스터 정보를 보면 두번째 인자( read(0, buf, 256) )를 나타내는 rsi 의 값이 0x7ffe8f30b4b0인 것을 확인할 수 있습니다. return address의 주소에서 buf의 주소를 빼주면 ret까지의 거리가 72가 구해집니다.

이제 공격에 사용할 함수와 문자열("/bin/sh")의 오프셋값을 구하기 위해 공유라이브러리의 주소를 확인합니다. 오프셋 값을 구하는 이유는 시작주소가 0x7f93e0ee1000 인것을 확인할 수 있습니다.

라이브러리상에 있는 "/bin/sh"의 문자열 주소 확인한 후, 라이브러리의 시작 주소를 빼서 "/bin/sh"까지의 오프셋 거리를 구합니다.
"/bin/sh"의 오프셋: 0x18ce17

printf, system, setresuid 의 주소를 확인한 후 동일한 방식으로 오프셋 거리를 구합니다
printf의 오프셋: 0x55810
system의 오프셋: 0x453a0
setresuid의 오프셋: 0xcd5f0

이제 인자전달과 함수 실행에 필요한 가젯을 찾습니다. 프로그램이 사용하고 있는 가젯에서 한개의 인자를 전달할때 필요한 pop rdi ; ret ; 가젯을 확인했습니다.

두번째 인자와 세번째 인자를 전달할 가젯이 프로그램 상에 없기 때문에 라이브러리에서 이를 대체할 수 있는 가젯을 찾습니다. (pop rdx ; pop rsi ; ret ; 확인)


exploit 코드입니다.


exploit 코드를 통해 쉘을 실행시켰습니다.



출처: https://kinggod-daddong.tistory.com/23 [킹갓다똥]
공부하면서 참고한 자료
PLT&GOT 참고 : shayete.tistory.com/entry/4-Return-to-Library-RTL

4. Return to Library (RTL)

Shayete입니다. 4번째 시간에는 최신환경의 우분투에서 Return to library 기법을 학습하겠습니다. Return to Libc 기법은 말 그대로, 라이브러리의 함수로 리턴해서 그 함수를 실행할 수 있습니다. 가령,

shayete.tistory.com

CTF 예제 :rookie0705.tistory.com/5 (코드게이트 2018 Baskin Robins 31)

[CODEGATE 2018] Baskin Robins 31

친구한테 바이너리파일을 받아서 한번 풀어봤다. 누구나 한번쯤해본 베스킨라빈스 게임이다. 이제 ida로 한번 열어보자 main을 보니깐 힌트는 ROP라고 한다 그럼 취약점을 찾아보자 버퍼에 0xb0(176)

rookie0705.tistory.com