반응형

Retrun-Oriented Programming (ROP)


이전 return to libc 공격에서는 System함수와 exit함수를 사용하였다. 하지만 System 함수가 라이브러리에 없을 경우에는 어떻게 공격을 하는가? 요즘 시스템들은 취약한 함수들을 제거하기 시작했다.
따라서 code chunk들을 연결하여 원하는 동작을 수행 할 수 있도록 잘 엮어서 공격을 할 수 있다.

Chanining Function Calls (WITHOUT ARGUMENT)

(함수 인자가 없는 경우를 다루겠다. 인자가 있는 경우는 너무 복잡하다.)

아래의 그림과 같이 함수들을 배치해주면 된다.

그러면 어떻게 원하는 동작을 하도록 하게 할까?

return to libc 공격에서는 공격자가 system함수가 수행되길 원한다. 하지만 위험한 함수들은 제거되므로 code chunk를 엮어서 사용하여야 한다.

위 그림과 같이 원하는 글자를 가져와 조합하면 원하는 문장을 만들 수 있다. 이와 같이, 이미 존재하는 코드 조각들을 맞추면 즉, 이미 있는 명령어들의 조각을 찾아서 조합하면 system이나 execve과 같이 구성을 할 수 있다.

따라서

- 코드 주입이 필요없다.

- libc 함수를 호출할 필요가 없다.

- 원래코드를 수정할 필요가 없다.

먼저 명령어들의 조각들을 조합하여 합치기전 instruction sequences와 gadget을 알아야한다.

- intstruction sequences는 작은 명령들의 순차이다. 명령어 순차는 2~5개의 명령으로 구성되어 있다.

- instruction sequences는 반드시 return으로 끝나야한다.

- gadget은 순차들을 체인으로 연결한 것이다.

- 하나의 gadget은 특정한 업무를 수행한다. ( load, store, xor, branch와 같은)

이러한 가젯들을 연결하여 원하는 행동을 할 수 있다. 그리고 또한 ROP역시 Code Reuse Attack이다.

버퍼 오버플로우를 일으키는 프로그램이 있을 때, payload를 다음과 같이 구성한다.

패턴1 (버퍼) + 패턴2 (saved Ebp) + ret_addr1 + ret_addr2 + ret_addr3 + Argument + ret_addr4 + ret_addr_5 + ret_addr+6

그러면 다음과 같이 순차적으로 동작할 것이다.

하지만 3번째 명령어를 보면 pop을 하므로 인자가 필요하다.

따라서 Return Address 3 위에 Argument를 넣어준다.

그리고 순차적으로 6번째 명령어까지 실행이 될 것이다.

Unintended Instruction Sequences


프로그래머가 의도하지 않은 방식대로 명령어 조합이 가능해진다.

valid한 명령어의 중간 부분에 있는 주소로 점프하게 만들면 의도하지 않은 명령어 순차가 실행되게 된다.

의도되지 않은 명령 순차들이 x86 아키텍쳐에서 가능한 이유는

  1. 명령어는 가변이다. (CISC)

  2. unaligned memory access

    N으로 나누어 떨어 지지 않고 임의의 주소로부터 읽기가 가능하다.

    e.g)

b8, 13, 00, 00, 00 중 아무곳부터 읽기가 가능하다.

위의 그림을 보면 mov와 jmp 명령어가 다음과 같은 Byte values를 가지는 것을 알 수 있다. 하지만 여기서 정상적으로 b8부터 읽는 대신에 첫번째 00으로 점프하게 하거나, return을 00으로 한다면 [b8 13] , [00 00], [00 e9]와 같이 되며, add %al, (%eax)와 같이 다른 명령어가 된다.

처음 의도한 move, jump 명령어가 add, add, return으로 바뀌게 된다.

Gadget 예시


0x8010ABCD 주소안의 0xDEADBEEF를 eax 레지스터에 로드하려고 할때.

먼저 가젯을 구성하고, 버퍼 오버플로우를 일으킨뒤 Sequence 1을 가르켜 실행되게 한다.

 

위와 같이 payload를 구성해야한다. 패턴1(버퍼) + 패턴2(saved Ebp) + ret_addr_1 + "\x8D\xAB\x10\x80" + ret_addr_2

 

리틀 엔디안이므로 주소를 반대로 적고 movl 64(%eax), %eax이므로

eax 주소에서 64만큼 더해서 그곳에 있는 값을 eax로 가져오므로 

원하는 DEADBEEF가 있는 주소 0x8010ABCD 에서 64만큼 뺀 주소를 넣어야한다.

 

 

순차적으로 실행이 되며 최종적으로 eax레지스터에 DEADBEEF가 들어가게 된다.

 

 

 

 

ROP 공격은 NX bit(Non executable stack)을 우회할 수 있다.

하지만 이러한 공격을 하기위해 프로그램 언어와 컴퓨터 구조, 함수 동작원리 등을 이해하고 있어야한다.

 

이러한 공격을 막기위해선, 가젯 Free Code를 사용하여 가젯 구성을 막아 공격을 막을 수 있다.

728x90
반응형

'공부 > 보안' 카테고리의 다른 글

Access Control MAC (2)  (0) 2020.12.03
Access Control & DAC (1)  (0) 2020.12.03
Return-tol-libc Attacks  (0) 2020.10.17
Other Overflow Attacks  (0) 2020.10.16
Buffer Over flow 2  (0) 2020.10.16
블로그 이미지

아상관없어

,