bug hunting







# Bug Hunting (1) - Exploitable 취약점 분류



취약점에는 다양한 종류가 있다. 


똑같은 crash 가 발생하더라도, 해당 버그는 Exploit 할수도, 불가능 할수도 있다. 


여기서 Exploit 이라 함은 코드 실행 흐름을 변경하여 원하는 코드를 실행할 수 있는, 즉 Code Execution 이 가능한가이다.


간단한 설명과 함께 분류해 보았다.





1. Memory Corruption


 - 대표적인 Exploit 유형으로, 주로 잘못된 함수 사용 등에 의해 발생




 1.1. Stack Buffer Overflow

  

    - 스택상의 메모리 영역을 침범하여 덮어쓰는 유형의 버그


    - 공격기법 : Direct EIP Overwrite, SEH Overwrite, ECX one byte Overflow, RTL(Return To Library), Fake EBP, Fake ESP, ROP


    - 방어기법 : Stack Guard, Stack Cookie, DEP/NX, ASLR



 1.2. Heap Buffer Overflow


    - 힙 메모리 영역을 침범하여 덮어쓰는 유형의 버그


    - 공격기법 : VFT Overwrite(Virtual Function Table Overwrite), Function Pointer Overwrite




 1.3. Format String Bug


    - 포맷 스트링을 사용하지 않은 잘못된 함수 사용으로 인하여 %n 등으로 특정 주소값을 덮어씌우는 공격기법


    - 공격기법 : dtors Ovewrite, Got Overwrite, RET Overwrite 




 1.4. Use-After-Free


    - Free 로 해제된 객체, 포인터를 사용하는 경우 발생하는 버그로, 최근 많이 발견되는 유형 중 한가지이다.(특히 웹브라우저)

   

    - 공격기법 : Heap Spray -> 정밀 Heap Spray, DEPS(엘리멘탈 속성 spray), JIT Spray 등



 1.5. Double Free


    - free() 로 이미 해제된 메모리를 한번 더 해제하려 할때 발생하는 버그




 1.6. Integer Overflow


    - 자료형마다의 경계값(최대,최소값) 차이점 등에 의해 발생하는 버그













가벼운 에디터 툴을 찾아보다가, akelpad 라는 툴을 찾게 되었다. 메모장과 비슷하지만 플러그인 등을 제공하여 


가벼우면서도 다양한 기능을 제공하고 있었다.  조금 사용하던중 취약점을 찾아보자 라는 생각이 문득 들어서 소스코


드를 다운받아 살펴보기 시작했다. 


결론부터 말하면 취약점을 찾았고, exploit 에 성공했다.  :)


http://akelpad.sourceforge.net/en/index.php









취약함수인 strcpy 위주로 검색을 해보니 역시나 존재했다. 쓰지 말라고 아무리 말해도 쓴다. ㅎㅎㅎ 





처음엔 간단한 메모리커럽션 으로 생각해서 쉽게 exploit 이 가능한 취약점이라 생각했다. 해당 소스는 설정파일인 


AkelPad.ini 에서 CmdLineBegin 과 CmdLineEnd 항목을 읽어올 때 복사할 크기를 지정하지 않는 strcpy 함수를 


사용하기 때문에 발생한다. 



하지만 이렇게 쉬울리가 없겠지....금방 몇가지 문제가 발생했다. -_-;


1) 설정파일이 UTF-16 인코딩이 되어 있음 

   -> 유니코드로 인식되어 00 바이트 추가 ( 47 -> 47 00 )


2) stack bof 가 아닌 heap bof 

   -> 함수 포인터나 기타 exploit 가능한 상황을 찾아야 함







다시 정확한 분석을 위해 디버깅을 진행하며 확인해 보았다. A, B 등의 문자를 채워넣으면 ntdll 의 특정 함수에서 


예외처리로 걸려서 넘어가질 않았고, "G" 로 하니 잘 넘어갔다. 아마 입력된 문자로 어떤 주소값이 만들어 지고, 이 주


소값이 제대로 된 주소가 아니면 ntdll 에서 에러를 뱉으며 종료되는 것 같았다. exploit 을 위해서는 어플리케이션으로


돌아가야 하므로 이것저것 찾아보다 보니 "G" 는 470047 인데, 이 주소값은 이 어플리케이션 모듈의 이미지 주소였


다. 


 어쨌든, 아래와 같이 간단히 python 코드를 제작하여 다시 디버거를 통해 실행시켜 보았다.





뚜둥~ CALL EAX  와 함께 00470047 주소를 호출하려 하고 있다. 이말은 EAX 가 내가 입력한 GGG... 에 의해 변경


이 되었고, 이 주소를 CALL 한다는 것은 이버그가  Exploitable 하다는 뜻이었다. 





좀더 자세히 살펴보면 CALL EAX 를 하기 전 특정 Heap 주소에서 어떤 값을 EAX 에 넣어주고 있다. 이 주소의 값이 


내가 입력한 GGG 에 덮어씌워 진 것이라 짐작할 수 있다. 




CALL [Reg] 형태의 명령은 보통 함수 포인터를 사용하는 코드이다. IDA 를 통해 자세히 살펴보면, 아래와 같이 해당 


주소는 MonitorFromPoint 함수의 주소를 얻어와 저장해 둔 메모리 주소이다.  bof 에 의해 이 값이 변조되어 실제


CALL EAX 가 이루어질 시점엔 EAX 가 특정 임의의 값으로 변조되어 있던 것이었다.






이제 취약점 분석은 끝났으니 간단히 exploit 을 제작해 보자. 




# exploit 을 위한 정보 


1) Unicode 인코딩 파일포맷 -> ascii 강제저장으로 우회


2) 47 00 47 00 코드도 Nop 코드이므로 그냥 47004700 사용 ( 정상적으로 이 버그 코드에 도달하기 위해서 47004700 을

    사용해야함. AAAA.. 등은 중간에 ntdll 에 잡아먹힘. )


3) 0x470047 주소는 내가 입력이 가능한 Buffer 임 -> 쉘코드 위치


4) 쉘코드는 간단한 cmd 실행 코드 사용


위를 종합한 payload 는 다음과 같다.



     1          2              3                  4

dummy + nop + shellcode + dummy(overwrite function pointer)


4 에 의해 function pointer 가 470047로 덮어씌워지고, 2로 점프한 뒤 3을 만나 쉘코드를 실행하게 될 것이다.


이제 직접 실행을 해보자.









CALL EAX 가 실행되는 시점에 EAX 는 0x470047 로 변경되어 있으며, 아래와 같이 해당 주소에는 미리 입력해둔 


Nop + Shellcode 가 존재한다.




CALL 0x470047




Nop Sled




ShellCode 실행






CMD !!  Exploit 성공~!! :)



















+ Recent posts