달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2017. 7. 5. 09:04

[Windows] C++ vtable overwrite Security/Exploits2017. 7. 5. 09:04

1. Virtual Method Table(Virtual Call Table, vtable)

런타임 메소드 바인딩을 지원하기 위해 프로그래밍 언어에서 사용하는 방법이다. 

클래스가 가상 함수(또는 가상 메소드)을 정의할 때마다, 대부분의 컴파일러들은 클래스에 숨겨진 멤버 변수를 추가하는데, 이것은 (가상) 함수들에 대한 포인터들의 배열들(가상 메소드 테이블(VMT 또는 Vtable)라고 불리는)을 가리킨다. 이 포인터들은 실행 기간 도중에 정확한 함수를 가리키게 되는데, 왜냐하면 컴파일 타임에는 베이스 함수가 호출될 것인지 또는 베이스 클래스를 상속한 클래스에 의해서 구현될 지 알려져 있지 않기 때문이다.

출처 : https://ko.wikipedia.org/wiki/가상_메소드_테이블




2. vtable Overwrite 


단지 저 위에 있는 글만 보았을 때 잘 감이 오지 않는다. 

따라서 어떤식으로 동작하는 지 확인하면서 어떻게 익스플로잇이 가능한지 살펴보도록 하겠다. 


우선 테스트로 사용할 코드는 아래와 같다. 


[그림 1] 소스 코드 


위 코드에서 클래스를 인스턴스화 할 때 ECX 레지스터에 스택의 주소를 전달한 뒤 함수를 호출하는데

해당 함수는 단순히 전달받은 스택 주소에 클래스의 vtable 주소를 저장한다. 


그리고 난 뒤 멤버 함수를 호출할 때 vtable이 저장된 스택의 주소를 ECX 레지스터에 저장하고

이를 참조하여 함수를 호출하게 된다. 


[그림 2] 클래스 할당 및 멤버 함수 호출


아래의 그림은 멤버 함수 안에 있는 어셈블리어인데 이를 확인하면 조금 더 이해하기 쉬울 것이다.

ECX 레지스터를 새로운 멤버 함수의 스택 공간에 저장하고 가상 함수를 호출할 때는 이를 참조하는 것을 볼 수 있다. 


여기서 멤버 함수 내의 스택 공간에 저장한 값은 단지 최초에 저장된 vtable 위치라는 것을 주의해라. 


[그림 3] 멤버 함수내 가상함수 호출 과정


[그림 4]는 멤버 함수의 스택 구조를 나타낸다. 

위에서 설명한 바와 같이 vtable을 참조하는 모습을 볼 수 있다. 


[그림 4] 멤버 함수 스택 구조 


소스코드에서 볼 수 있는 것처럼 전달받은 파라미터의 길이를 검증하는 코드가 없기 때문에 오버플로우가 발생하는 것을 볼 수 있다. [그림 5]에서 vtable이 저장되어 있는 곳이 파라미터로 전달된 값으로 채워진 것을 볼 수 있다. 


[그림 5] vtable overwrite


이후 가상 함수를 호출할 때 vtable을 참조하는 과정에서 예외가 발생하게 된다. 


[그림 6] 예외 발생 




대충 이런식으로 취약점이 발생한다. 

개념을 정리하는 관점에서 흐름만 나열해보았다. 




♧ 틀린 내용은 혼자만 아시지 마시고 저도 알려주세요 - ㅅ-!

'Security > Exploits' 카테고리의 다른 글

[Linux] 쉘코드 모음집  (0) 2017.07.06
[Windows] 쉘코드 모음집  (0) 2017.07.06
[Linux] 쉘코드 제작 요약 설명  (0) 2017.07.06
[Linux] Heap overflow using unlink - 번역글  (0) 2017.07.06
:
Posted by einai