특정 프로세스를 감추는 은폐(stealth) 기법에 대해 설명하고, 예제 파일을 통해서 실습을 해보도록 하겠습니다.

 

<photo : mashleymorgan on flickr>


아래 내용은 이전 포스트에서 이어지는 내용입니다.
API Hooking – '스텔스' 프로세스 (1)



프로세스 은폐(stealth) 동작 원리 (User Mode)


프로세스 은폐(stealth)에 관한 내용은 이미 많은 정보가 공개되어 있습니다.
그 중에서 유저 모드(User Mode)에서 가장 널리 사용되는 "ntdll!ZwQuerySystemInformation() API 후킹 방법"에 대해서 살펴보겠습니다.

* 커널 모드의 프로세스 은폐 기법은 (유저 모드에 비해) 더 강력하고, 더 고급 기법입니다. 향후 제 블로그에서 자세히 다루도록 하겠습니다.


#1. 프로세스 은폐(stealth) 개념

스텔스 전투기는 레이다에 포착되지 않기 위해서 각종 첨단 과학을 동원하여 전투기 자체를 (기존 전투기와 다르게) 완전히 새롭게 개발 하였습니다. 즉, 작업 대상이 스텔스 전투기 자신입니다.

반면에 은폐 프로세스의 개념은 이와는 정반대입니다.
특정 프로세스를 은폐시키기 위해서 나머지 모든 프로세스들의 메모리에 침투하여 API 를 후킹합니다. 즉, 작업 대상은 다른 프로세스입니다.

은폐 프로세스의 개념을 스텔스 전투기의 설명에 적용해보면 아래와 같습니다.

그냥 일반 전투기를 띄워 보낸 후 모든 레이다를 고장내면(조작하면), 그 일반 전투기는 그 순간부터 스텔스 전투기가 되는 것과 같은 이치입니다.

이것이 바로 은폐(stealth) 프로세스의 개념입니다.


#2. 관련 API

프로세스(Process)는 커널 객체이기 때문에 (유저 모드 프로그램은) API 를 통해서만 접근이 가능합니다. 일반적으로 유저 모드에서 프로세스를 검색하기 위한 API 는 아래와 같이 2 종류가 있습니다.

HANDLE WINAPI CreateToolhelp32Snapshot(
    DWORD    dwFlags,
    DWORD    th32ProcessID
);

* 출처 : http://msdn.microsoft.com/en-us/library/ms682489(VS.85).aspx

BOOL EnumProcesses(
    DWORD*   pProcessIds,
    DWORD    cb,
    DWORD*   pBytesReturned
);

* 출처 : http://msdn.microsoft.com/en-us/library/ms682629(VS.85).aspx

위 2 가지 API 모두 내부적으로 ntdll!ZwQuerySystemInformation() API 를 호출합니다.

NTSTATUS ZwQuerySystemInformation(
    SYSTEM_INFORMATION_CLASS    SystemInformationClass,
    PVOID    SystemInformation,
    ULONG    SystemInformationLength,
    PULONG   ReturnLength
);

* 출처 : http://msdn.microsoft.com/en-us/library/ms725506(VS.85).aspx

ZwQuerySystemInformation() API 를 이용하여 실행중인 모든 프로세스들의 정보(구조체)를 연결 리스트 형태로 얻을 수 있습니다.

그 연결 리스트를 조작하면(리스트에서 빼내면) 해당 프로세스는 은폐 되는 것입니다.

따라서 유저 모드에서는 CreateToolhelp32Snapshot() 나 EnumProcess() API 를 후킹할 필요 없이  ZwQuerySystemInformation() API 하나만 후킹하면 확실하게 특정 프로세스를 은폐 시킬 수 있습니다.


#3. Global Hooking 개념

우리가 은폐하고자 하는 프로세스를 test.exe 라고 하겠습니다.
실행중인 ProcExp.exe (또는 taskmgr.exe) 프로세스의 ZwQuerySystemInformation() API 를 후킹 하면 ProcExp.exe 는 test.exe 를 찾지 못할 것입니다.

* ProcExp.exe = 프로세스 익스플로러, taskmgr.exe = 윈도우 작업 관리자

위와 같이 하면 ProcExp.exe(또는 taskmgr.exe) 프로세스 하나에 대해서 test.exe 가 은폐되었다고 말할 수 있습니다.

하지만 이 방법에는 두 가지 문제점 이 있습니다.

첫 번째 문제점은 후킹 대상 프로세스 개수 입니다.
프로세스 검색 유틸리티가 과연 이 두 가지뿐 일까요?
이들 외에도 수 많은 프로세스 검색 유틸리티가 있을 것이며, 사용자가 직접 만든 유틸리티도 있을 수 있습니다. 따라서 시스템에 실행중인 모든 프로세스를 후킹 해야만 내 프로세스가 은폐되었다고 확신할 수 있습니다.

두 번째 문제점은 새로 생성되는 프로세스입니다.
만약 사용자가 ProcExp.exe (또는 taskmgr.exe) 를 하나 더 실행하면 어떻게 될까요?
첫 번째 ProcExp.exe 프로스세는 이미 후킹이 되어 있으므로 test.exe 프로세스를 찾지 못하겠지만, 두 번째 실행된 ProcExp.exe 프로세스는 후킹 되지 않았으므로 test.exe 프로세스를 정상적으로 찾아 낼 것입니다.

이 두 가지 문제를 정리해 보면 우리는 test.exe 프로세스를 완전히 숨기기 위해서 시스템에 실행 중인 모든 프로세스의 ZwQuerySystemInformation() API 를 후킹해야 하며, 추가적으로 나중에 실행되는 모든 프로세스에 대해서도 똑 같이 후킹을 해줘야 합니다. (물론 자동으로 해줘야겠지요.)

이것이 바로 global hooking 의 개념입니다.
(이러한 global hooking 에 대해서는 뒷부분에서 따로 설명하도록 하겠습니다.)



실습


HideProc.exe

stealth.dll


HideProc.exe 는 실행중인 모든 프로세스에게 Stealth.dll 파일을 인젝션 시키는 역할을 합니다.
Stealth.dll 은 인젝션 된 프로세스의 ntdll!ZwQuerySystemInformation() API 를 후킹하는 역할을 합니다.

위 두 파일을 이용해서 notepad.exe 프로세스를 은폐시켜 보도록 하겠습니다.

* 참고!
위 실습 파일은 “global hooking – 새로운 프로세스”에 대한 대책이 없는 버전입니다.
따라서 HideProc.exe 실행 이후에 생성된 프로세스는 자동으로 후킹 되지 않습니다.
그에 대해서는 따로 설명 드릴 예정입니다. 참고하세요.



#1. notepad.exe, procexp.exe, taskmgr.exe 를 실행시켜 주세요.


#2. 아래와 같이 HideProc.exe 를 실행합니다.

<Fig. 1>

실행 파라미터에 대해서 간략히 설명 드리겠습니다.

-hide/-show : 은폐 시킬 때는 –hide, 은폐 해제 시에는 –show
process name : 은폐 시킬 프로세스 이름
dll path  : 인젝션 시킬 DLL 파일 경로


#3. 모든 프로세스에 stealth.dll 파일이 제대로 인젝션 되었는지 확인합니다.

Process Explorer 을 이용해서 stealth.dll 을 검색합니다.

<Fig. 2>

실행중인 모든 프로세스에 stealth.dll 파일이 인젝션 된 것을 확인 할 수 있습니다.

* 사실은 시스템 프로세스들(PID 0 & PID 4)에 대해서는 (시스템 안정성을 위해) 인젝션 시키지 않았습니다. (notepad.exe 프로세스 은폐에는 아무 상관 없습니다.)


#4. procexp.exe 와 taskmgr.exe 에서 notepad.exe 프로세스가 사라진걸 확인합니다.

<Fig. 3>

<Fig. 4>

위의 <Fig. 3> 과 <Fig. 4> 를 보시면 notepad.exe 프로세스가 분명히 실행 중이지만, procexp.exe 와 taskmgr.exe 에서 notepad.exe 프로세스가 사라진걸 확인하실 수 있습니다.

* 메모장의 윈도우가 보이기 때문에 프로세스가 완벽히 숨은 게 아니라고 생각하실 수 있겠습니다만, 우리의 목표는 프로세스 은폐이기 때문에 윈도우는 그냥 놔뒀습니다. 참고로 윈도우를 사라지게 하려면 SetWindowPos() API 등을 사용하시면 됩니다.


#5. notepad.exe 프로세스를 다시 보이도록 합니다.

HideProc.exe 를 –show 모드로 실행시킵니다. (stealth.dll 을 ejection 시켜줍니다.)

<Fig. 5>

procexp.exe 와 taskmgr.exe 에서 notepad.exe 프로세스가 정상적으로 보이는지 직접 확인해보시기 바랍니다.


다음 번에는 예제 소스 파일을 상세하게 분석해보도록 하겠습니다.

API Hooking – '스텔스' 프로세스 (3)


ReverseCore

위 글이 도움이 되셨다면 추천(VIEW ON) 부탁 드려요~

저작자 표시 비영리 변경 금지
신고
  1. RED_BIT 2009.12.17 08:19 신고 댓글주소 | 수정 | 삭제 | 댓글

    오랫만에 1등하는것 같네요.ㅎㅎ
    노트북이라... 대략 40개 이상의 프로세스들이 히히낙낙 거리고있는데...
    웬지 무서운...
    잘봤습니다~ > <//

    • ReverseCore 2009.12.17 18:46 신고 댓글주소 | 수정 | 삭제

      RED_BIT님, 안녕하세요.
      잘 보셨나요? ^^
      감사합니다.

    • 쵸밥 2010.01.16 11:17 신고 댓글주소 | 수정 | 삭제

      헐 ㅇㅁㅇ ,, 그러고 보니

      그간 신경 안쓰고 살았는데 프로세스가 48개네요 ,,
      (포멧한 직후,, 백신깔고 SP3설치하는중,,)

      노트북은 프로세스가 많은가 ㅇㅅ ㅇ,,

  2. hoon038 2009.12.18 00:31 신고 댓글주소 | 수정 | 삭제 | 댓글

    아 코어님의 명강의 정말 많은도움 되고 있습니다.
    나중에는 은폐 프로세스를 찾는 방법도 포스팅 해주셧으면 좋겠네요 ㅎㅎ

    • reversecore 2009.12.18 10:58 신고 댓글주소 | 수정 | 삭제

      hoon038님, 안녕하세요.

      말씀하신 은폐 탐지 방법도 재밌는 글이 될꺼 같네요 ^^

      사실 제가 쓰는 글 중에는 다른 분들의 의견, 아이디어가 반영된 부분이 많답니다. 다음 글을 쓸 때 도움으 많이 되지요~

      좋은 정보 감사드립니다.

  3. 개숭이 2009.12.18 11:04 신고 댓글주소 | 수정 | 삭제 | 댓글

    1편에 CreateRemoteThreaed방법으로 Injection을 쓴다고 Tech Map에 표시는 해두셨지만, 이유는 안나와 있어서요..

    혹시 "SetWindowsHookEx쓰면 되는데... 저절로 해주는데.."라는 생각하실분들이 있을거 같네요..

    아, 그리고 Tech Map들 보면 맨 우측 API부분에 CreateRemoteThread부분에 빨간색 친거 맨 아래에 쳐야 맞는거같은데.. 이전 것두 그런게 있고요//

    사소한 것들이여서 언급안하고 넘어갈수도 있는 부분인데, 연재글을 읽는 입장으로서, 초보자입장으로서 염려되어 리플하나 남겨봅니다.. 심각하게 받아들이진 말아주세요///

    • reversecore 2009.12.18 11:06 신고 댓글주소 | 수정 | 삭제

      개숭이님, 안녕하세요.

      네~ 지금 읽어 보니 과연 그렇군요. ^^
      처음 접하시는 분들은 그런 의문이 생기겠네요~

      TechMap 그림도 지적하신 내용이 맞습니다. ^^
      아래쪽 API 에 표시해야 하는데, 위쪽에 해버렸네요.

      좋은 지적 감사합니다.
      글의 완성도를 높이는데 도움을 주셔서 정말 감사드려요~

    • 개숭이 2009.12.18 11:13 신고 댓글주소 | 수정 | 삭제

      사실 제가
      reversecore님이 API Hooking 연재 진행중이실때
      계속 CreateRemoteThread만 쓰시네? 무슨이유일까? 이런생각을 했었거든요.. SetWindowsHookEx로 인젝션해서 API Hook하는 내용도 나올까 싶었는데 그후로 계속 CreateRemoteThread만 쓰셔서^^;;

    • reversecore 2009.12.18 11:23 신고 댓글주소 | 수정 | 삭제

      개숭이님, 제 블로그를 보고계셧군요. ^^

      SetWindowsHookEx 는 메시지 후킹 설명때 했었고, 자체적인 한계 때문에 개인적으로 CreateRemoteThread 를 선호 한답니다.

      다음번(마지막) API Hooking 실습예제도 CreateRemoteThread 를 썼는데요... ㅎㅎ
      말씀하신대로 SetWindowHookEx 로 변경 가능한지 확인해 보겠습니다.

      저도 이왕이면 다양한 방법을 많이 소개해 드리는 편이 좋다고 생각합니다.

      좋은 제안 감사드려요~ ^^

  4. 개숭이 2009.12.18 11:38 신고 댓글주소 | 수정 | 삭제 | 댓글

    마음과 몸은 이미 주말이네요..
    일이 손에 안잡혀서 서핑중입니다ㅋㅋㅋ
    아 갑자기 궁금한게 있는데요, CreateRemoteThread를 사용해서 32bit프로세스(32bit dll, 32bit injector)에서 64비트 프로세스로 인젝션이 가능한가요? SetWindowsHookEx는 어떨까요?

    • ReverseCore 2009.12.21 11:14 신고 댓글주소 | 수정 | 삭제

      개숭이님, 안녕하세요.
      답변이 늦었네요~

      전 아직 64bit 를 경험해보지 못해서 뭐라 말씀드리기 어렵네요 ^^

      32->32, 64->64 는 당연히 잘 되겠죠.
      32->64 만 확인해보면 되겠네요...

  5. mAn1aS 2009.12.23 10:18 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료 잘보고 있습니다. 다음 글이 기다려 지는군요^^ 연말 잘보내세요

  6. 쵸밥 2009.12.26 04:47 신고 댓글주소 | 수정 | 삭제 | 댓글

    혹시 forum.exetools (EXETOOLS) 가입되어 있는 분 있나요 T^T?

    W32Dasm Patch 3.0 final 이 그 홈페이지에 있길레 받고싶은데. .
    영어가 너무 어려워서 가입을 못하네요 마지막에 무슨 코드를 쓰라는데 T^T..
    구글 번역기 돌리며 몇시간을 시도해봤지만 실패네요 T^T..

    http://forum.exetools.com/showthread.php?t=2396

    요거 혹시 받는게 가능하신 분 있으면 tortlxkq@naver.com 으로 좀 보내주시겠어요 흑 T^T..

    P.S 메리 그리숨엇수 하세요 ^^*

    • ReverseCore 2009.12.28 00:49 신고 댓글주소 | 수정 | 삭제

      쵸밥님, 안녕하세요.

      W32Dasm 을 찾으시는군요.
      해당 링크는 패치파일 이군요?

      이번에 OllyDbg2.0 Final Beta 가 출시되었는데,
      제작자가 DisAsm 을 크게 강화했다고 하니 참고하시기 바랍니다.

      감사합니다.

  7. Elephunk 2009.12.29 20:08 신고 댓글주소 | 수정 | 삭제 | 댓글

    w32dasm 3.0 patch
    http://tinyurl.com/ydwms9y
    여기서 [W A S M . R U] 링크 들어가면 있습니다

    • reversecore 2009.12.30 10:26 신고 댓글주소 | 수정 | 삭제

      ^^
      익살스런 링크입니다.

      Elephunk님, 감사합니다.

    • 쵸밥 2009.12.31 06:23 신고 댓글주소 | 수정 | 삭제

      ㅋㅋㅋ 너무 깜찍한 메시지ㅋㅋ
      이게 그리 어렵냐 이거 만드신건가요 ㅋㅋ
      넘넘 감사해요 ㅜ

      이렇게 금방 이런 페이지를 만들수도 있나보네요 ^^;;
      웹도 참 재밋는것 같네요 ㅋ 감사합니다 ^^*

      w32dasm patch 3.0 bratpatch3.zip 으로만 검색했는데 ㅜ
      그렇게 치니깐 많이 나오네요 감사합니다 ^^*
      웹페이지 너무 귀여워요 ^^*

  8. 지나가는이 2010.03.24 14:30 신고 댓글주소 | 수정 | 삭제 | 댓글

    흠.. 이거 64비트에서는 안되네요..

    • reversecore 2010.03.25 23:33 신고 댓글주소 | 수정 | 삭제

      지나가는이님, 안녕하세요.

      아~ 그렇군요.

      제 주변에 64bit 테스트 환경이 없어서 한번도 테스트 해보지 못했습니다.

      향후 환경이 갖춰지면 디버깅해서 수정하도록 하겠습니다.

      감사합니다.

  9. QhQh 2010.05.14 18:36 신고 댓글주소 | 수정 | 삭제 | 댓글

    Windows XP SP3와 7에서 테스트 하셨다고 하셨는데

    VMware로 SP3를 설치하고 하니깐 안되네요

    혹시 방화벽 해제라던지 다른 변경을 해야 가능하고 그런가요:?

    • QhQh 2010.05.14 18:41 신고 댓글주소 | 수정 | 삭제

      아 해결했습니다
      바탕화면에서 실행을 했었는데
      폴더명에 한글이 포함되면 안되는거였군요 ㅎㅎ
      괜한 삽질

      잘 보고 있습니다^^

    • reversecore 2010.05.17 01:57 신고 댓글주소 | 수정 | 삭제

      QhQh님, 안녕하세요.

      아마 한글이 문제가 아니라 띄어쓰기가 문제일것 같네요.

      C:\Documents and Settings\ReverseCore\바탕 화면>HideProc.exe -show notepad.exe "c:\Documents and Settings\ReverseCore\바탕 화면\stealth.dll"

      위와 같이 stealth.dll 경로를 따옴표("")로 묶어 주시면 정상적으로 작동 될 것입니다.

      잘 안되시면 다시 질문 올려 주세요~

      감사합니다.

  10. 김병화 2010.06.24 14:26 신고 댓글주소 | 수정 | 삭제 | 댓글

    HideProc.exe -hide abc.exe d:\stealth.dll 을 하니,

    OpenProcess<3976> failed!!!
    OpenProcess<4040> failed!!!

    tasklist 해보니,
    V3LSvc.exe 3976 Console 0 2,276 K
    V3LTray.exe 4040 Console 0 1,028 K

    음,,, 안철수백신에는 숨겨지지가 않는군요,
    안철수백신에 숨겨지지 않는것 뿐만아니라, tasklist로는 abc.exe가 보이네요.

    백신이 설치되지 않은 다른PC에 해봤습니다.
    결과는 잘됩니다.
    tasklist로도 숨겨져 있네요.

    제가 뭔가 잘 못하는건가 싶네요, ^^;

    • reversecore 2010.06.25 10:26 신고 댓글주소 | 수정 | 삭제

      위에 언급하신 내용은 매우 정상적인 결과입니다.

      V3 제품의 자체 프로세스 보호기법 때문에 OpenProcess() 에러가 발생한 것입니다. 이 경우 보통 방법으로는 해당 프로세스에 침투할 수 없습니다.

      이런류의 프로세스 메모리에 침투하는 방법이 여러가지 있긴 한데요...
      기법마다 껀껀이 설명드리기도 어렵고...
      악성코드에서 많이 쓰는 거라 설명하기도 거북한 상황입니다. ^^

      당분간은 보호 프로세스에 침투하는 방법에 대한 강좌는 계획에 없습니다.

      감사합니다.

  11. 김병화 2010.06.25 16:03 신고 댓글주소 | 수정 | 삭제 | 댓글

    ㅎㅎㅎ;;
    정상이군요.
    백신도 숨겨지나 싶어서 궁금해서 물어봤습니다...
    근데 신기하네요.

    저는 랭귀지를 잘못해서 실제 적용은 못하겠네요.
    ㅎㅎㅎ;;여튼 좋은구경하고 갑니다.
    그리고, 제 홈피주소가 스팸이 되었더군요.
    제가 이쪽으로 트래백을 잘못보낸적이 있는거 같습니다.
    ^^

  12. 안녕하세요 2010.07.15 04:48 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료 잘 보고 있습니다 ~

    한가지 궁금한 점이 있는데요

    이게 윈도우 작업 관리자에서 프로세스 탭 에서는 사라지는데요

    응용 프로그램 탭 에는 그대로 있네요 ㅋ

    혹시 응용 프로그램 탭에서도 같이 없앨 수 있는 방법이 있을까요?

    • reversecore 2010.07.15 23:54 신고 댓글주소 | 수정 | 삭제

      네, 프로세스 목록에서만 감추기 때문에 윈도우는 그대로 보이는 것입니다.

      윈도우까지 같이 없애주시면 작업관리자의 응용프로그램 탭에서 사라집니다.

      윈도우 없애는 건 윈도우 메시지를 보내거나 관련 API 를 사용하면 쉽게 될 것입니다.

      위 예제는 API Hooking 을 위주로 작성한 거라 윈도우는 그대로 놔뒀습니다. 분명 윈도우는 있는데, 프로세스만 사라지는 현상을 보여주려고 말이지요.

      윈도우 감추기는 검색해 보시면 금방 찾으실 겁니다.

      감사합니다.

  13. 안녕하세요. 질문 2010.09.02 16:03 신고 댓글주소 | 수정 | 삭제 | 댓글

    hideproc.exe 실행시켜봤는데 0.5초만에 저절로 꺼지던데 왜 이런건가요?
    윈도우xp 서비스팩2사용중입니다.

    • ReverseCore 2010.09.04 16:43 신고 댓글주소 | 수정 | 삭제

      그렇게 동작하는게 정상입니다. ^^

      작업관리자에서 notepad.exe 가 안보인다면 성공입니다.
      (WinXP SP3 에서 테스트 하였습니다.)

      감사합니다.

  14. usrobj 2011.08.04 23:42 신고 댓글주소 | 수정 | 삭제 | 댓글

    업계에서 어느 정도 일해야 저런 API까지 다 알고 그럽니까 ㅎ
    요즘 윈도우 시스템 프로그래밍 책 보면서 틈틈히 블로그 글 보지만 언제나 봐도 신기하기도하고 어렵기도하고...

  15. 난나놔 2013.07.07 06:46 신고 댓글주소 | 수정 | 삭제 | 댓글

    dll에 직접 훅을 걸거나... 이미 훅되어 있다면 32비트는 5바이트 64비트는 12바이트 점프한거나...
    커널에서 훅을 걸거나...64비트는 커널 진입전 까지 코드를 복사해서 커널로 진입하거나... ssdt 보호모드에서 구경만 하거나... 잠이나 자거나...

  16. alfheimr 2017.02.03 01:02 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다





티스토리 툴바