Safe SEH라는 이름의 작은 도전…

@codemaru · April 09, 2010 · 6 min read

#0

Safe SEH라는 기술은 SEH 하이재킹 기법을 방지하기 위해서 MS에서 만든 것으로 실행 파일에 등록된 SEH 핸들러만 실행되도록 하는 간단한 기술이다. 핵심 원리는 프로그램을 컴파일할 때 실행 파일에 SEH 핸들러 목록을 기록해 두고, 운영체제가 예외를 처리할 때 그것을 참조해서 빌드될 때 등록된 핸들러인지 검사하는 것이다. Visual C++ 2003부터는 이렇게 Safe SEH를 지원하기 위해서 실행 파일을 빌드하면 해당 실행 파일의 IMAGE_LOAD_CONFIG_DIRECTORY 구조체의 SEHandlerTable이 가리키는 곳에 해당 실행 파일에서 사용하는 모든 핸들러를 등록해 놓는다.

예외가 처리되는 관점에서 살펴보면 다음과 같은 흐름으로 진행된다. 예외가 빵하고 터지면 RtlDispatchException 함수가 호출된다. RtlDispatchException 함수에서는 RtlIsValidHandler를 호출해서 지금 실행하려는 예외 처리 핸들러가 적합한지를 검사한다. RtlIsValidHandler 함수가 수행하는 일이 앞서 설명한 내용이다. RtlIsValidHandler는 예외 실행기를 찾기 위해서 PEB를 뒤져서 예외 실행기가 포함된 모듈을 찾는다. 찾았다면 해당 모듈의 IMAGE_LOAD_CONFIG_DIRECTORY 구조체의 SEHandlerTable를 조사해서 지금 실행하려는 예외 핸들러가 거기 등록되어 있는지 찾는다. 동일한 주소의 핸들러가 있다면 실행시켜 주고, 그렇지 않으면 실행시키지 않는다.

장황하게 설명했는데, 사실 Safe SEH라는 기술은 소개된지 제법 시간이 흘렀으며, XP 이상의 운영체제는 모두 이 기능을 지원한다. 그런데 이 구식 기술에 발목이 잡혀서 이틀째 Safe SEH와 사투를 벌였다. 앞서 소개한 기본 지식만 본다면 운영체제를 속이는 일은 제법 쉬워 보인다. 내가 시도했던 한 가지 방법은 Fake DLL을 사용하는 것이다. Fake DLL을 로드한 다음에 PEB 정보를 변경해서 해당 DLL의 주소 영역을 조작하고 임의로 로드하는 코드의 SEH 핸들러를 해당 모듈의 SEHandlerTable에 등록하는 것이다. 말로하면 쉽지만 실제로 이 작업을 완벽하게 수행하는 것도 쉬운 일은 아니다. 어쨌는 그 쉽지 않은 일을 어제 코딩해서 테스트를 했는데, ‘그렇지!’ 라는 탄성을 질러야 하는 부분에서 계속 한숨을 쉴 수 밖에 없었다. 운영체제가 생각보다 쉽게 속지 않았던 것이다.

여기까지 하고는 저녁 약속이 있어서 퇴근을 했다. 흠~

#1

오늘 출근해서 디버깅 작업을 좀 더 해 보았다. 그러자 원인은 의외로 간단한 곳에 있었다. 운영체제 코드가 앞서 이야기 한 것처럼 단순하게 구성되어 있지 않았던 것이 이유였다. 운영체제는 매번 PEB를 탐색하지 않고, 로딩이 완료된 경우에는 LdrpInvertedFunctionTable이라는 내부 전역 테이블에서 그 값을 찾도록 되어 있었다. DLL이 로드될 때 해당 테이블에 정보가 추가되는 것으로 보인다. 속도적인 측면에서 유리하도록 하기 위해서 그렇게 구성해 둔 것으로 판단된다. 결국 싱거운 이야기지만 정상적으로 우회하기 위해서는 LdrpInvertedFunctionTable을 조작해야 한다는 결론이 나온다. (물론 한 가지 방법이 그렇다는 것이고, 이 걸 우회할 수 있는 방법을 여러 수 천 가지가 존재한다.)

오늘은 제대로 예외처리기가 호출되는 것을 볼 수 있었다. 물론 탄성을 지르지는 못했고, 잠시 모니터를 향해 썩소를 날리는 것으로 만족했다.

#2

디버깅을 끝내고 퇴근을 하는데 이런 저런 생각이 든다. 거짓말이 거짓말을 부르는 것처럼 한 번 문서화되지 않은 기술을 사용하고 나니 계속 더 많은 문서화되지 않은 가정들을 프로그램에 도입하게 되는 듯한 느낌이 가슴을 후벼판다. 그런 가정과 지식들이 계속 모이다보면 결국 나중에는 아무도 이해하지 못하는 그런 괴물이 되는 것은 아닐까, 라는 생각도 잠시 머리 속을 헤집는다. 아이러니 한 사실은 근데 또 그런 걸 이해하는게 능력으로 취급되기도 한다는 점이다. 그래서 , <Windows 구조와 원리>와 같은 책들이 불티나게 팔리는 지도 모르겠다. 요지경 속이다.

덧) 더 공부하시고 싶으신 분들은 아래 자료를 참고하시면 도움이 될 것 같군요.

http://blackhat.com/presentations/bh-usa-08/Sotirov_Dowd/bh08-sotirov-dowd.pdf

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중