포렌식 아티팩트 중에는 점프 목록(Jump List)라는 것이 있다. 각 어플리케이션 또는 시스템에서 자주 사용 되거나 최근에 사용 되었던 것들에 대해서 지역성 있게 윈도우 운영체제 자체에서 사용이력을 관리하기 위한 기술이라고 생각하면 되는데, 이번 글에서는 점프 목록에 대한 다른 문서들에서 언급되지 않은 이야기를 해보고자 한다.


기본적인 점프 목록에 대해서는 Forensic-Proof에서 자세하게 설명하고 있으니 참고하기 바란다. 이번 글에서는 다른 문서나 블로그 포스트에서 다루지 않았던 이야기를 하기 때문에 기본적인 설명을 생략할까 한다.


점프 목록 포렌식 기본 : http://forensic-proof.com/archives/1904


위 글을 읽었다면 점프 목록에는 "AutomationDestination" 이라는 것과 "CustomDestination" 이라는 것이 있는 것을 파악 했을 것이다.

AutomationDestination은 최근 사용한 목록이나 사용자가 고정 시킨 것들에 대한 정보가 포함되어 있고, CustomDestination은 자주 사용되는 목록이나 작업(task) 목록 정보가 포함된다.


여기서 AutomationDestination 폴더에 저장되는 파일들은 모두 OLE 파일 구조를 가지고 있어, 실제 우리가 원하는 정보는 OLE 파일 구조 내부에 Stream에 들어 있다. Stream은 모두 하나의 링크(lnk)파일 구조를 가지고 있어 OLE 구조에서 Stream만 추출이 가능하다면 쉽게 세부 정보들을 출력 해 낼 수 있다. 또 OLE 구조 제일 마지막 부분에는 "DestList"라는 이름의 Stream이 존재하는데 해당 스트림은 윗단에 존재하는 각 Stream들의 간략한 정보를 가지고 있어, 이 부분도 분석에 있어 고려를 해야 하는 부분이지만, 점프목록 분석 도구들의 대부분이 DestList Stream에 대해 분석을 해주지 않는다.


그리고 CustomDestination의 경우 표준 파일 구조가 존재하지 않는다. 이런 이유로 대부분의 점프 목록 도구는 CustomDestination 파일을 분석 해주지 않지만, tzworks의 jmp 도구만이 해당 파일을 분석하여 출력 해 준다.


이번 글에서는 도구들이 분석에서 간과하는 "DestList Stream"과 "CustomDestination" 파일 구조에 대해 알아보고자 한다.


1. DestList Stream

DestList Stream은 간단한 정보만을 가지고 있어, 다른 파일구조에 비해 간단하다. 해당 Stream의 구조를 살펴보면 다음과 같다.


[그림 1 - DestList Stream 구조]


참고로 [그림 1]의 구조는 DestList Stream에서 32 오프셋을 건너 띈 이후에 연속으로 존재한다. 각 항목에 대한 설명은 다음과 같다.


 - Check Sum : 가리키고 있는 Stream의 Check Sum 값이 저장되어 있다.

 - New Volume : Birth Volume ID 값이 아닌 Volume에서 해당 파일이 수정되면 파일이 수정 될 때의 Volume GUID 값이 저장 된다.

 - Object ID 1: 어떤 ID 값이 저장되는지 밝혀지지 않았지만, 다음에 존재하는 Object ID 2와 동일한 값을 저장한다.

 - Birth Volume ID : 가리키고 있는 Stream이 생성 된 Volume GUID 값이 저장 된다.

 - Object ID 2 : 어떤 ID 값이 저장되는지 밝혀지지 않았지만, 이전에 존재하는 Object ID 1과 동일한 값을 저장한다.

 - Machine ID : 해당 Stream이 생성 된 시스템의 이름 값이 저장 된다.

 - Entry ID : 가리키고 있는 Stream의 이름이 저장 된다.

 - File Access Count : Stream의 접근 횟수를 부동소수점으로 표현한 값을 저장하고 있다.

 - Last Record Time : Stream의 마지막 수정 시간을 저장하고 있다.

 - pin : 메타데이터 구조의 끝을 알리는 값으로 항상 0xFFFFFFFF 값을 가지고 있다.

 - Unicode String Length : 뒷 부분에 위치하는 Unicode 문자열의 길이를 저장하고 있다. 실제 길이는 Unicode의 2byte 특성 때문에 해당 값에 2를 곱해야 한다.

 - Unicode String : Stream에서 가지고 있는 문자열을 Unicode 형태로 저장하고 있다.


간혹 DestList Stream 내부에 [그림 1] 구조가 깨져 있을 수 있다. 데이터를 쓰는 도중에 시스템에 오류가 생겨 쓰기 동작 예기치 못하게 중지 되는 경우인데, 이때 해당 구조가 깨져있는지를 확인하려면 pin 데이터를 확인하면 된다. pin 데이터는 항상 0xFFFFFFFF이기 때문에 해당 값이 아니라면 구조에 문제가 있는 것으로 판단 할 수 있다. 또 Entry ID의 값이 AutomaticDestination 내부에 존재하는 Stream의 이름이 아니라면 이 또한 해당 구조에 문제가 있다고 판단 할 수 있다.


아래는 구현한 도구의 결과 샘플이다.


 [DestList]

 JumpList File Name : AutomaticDestinations\1b4dd67f29cb1962.automaticDestinations-ms

 Stream Name : 3

 Check Sum : 446aed6629321199

 New Volume ID : 0648918d3e59f140b41967735b7fdb49

 Object ID_1 : 1fca1e3db7bbe311beeb000c29501e46

 Object ID_2 : 1fca1e3db7bbe311beeb000c29501e46

 Birth Volume ID : 0648918d3e59f140b41967735b7fdb49

 Machine ID : msdn-special

 File Access Count : 4.17815044784e-08

 Last Record Time : 2014/04/04 14:09:21 Fri

 String Data : ::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Music.library-ms


file_display_auto_result.txt



2. CustomDestination

CustomDestination의 구조는 표준으로 정해져있지 않다. 불규칙적으로 lnk 구조가 여러개 존재한다. 크게 구조를 본다면 다음과 같다.

[그림 2 - CustomDestination 파일 구조]


[그림 2]와 같은 구조에서 lnk 구조를 파악하려면 lnk 구조를 카빙해야 한다. lnk 구조는 헤더의 크기가 76byte로 이를 나타내는 필드의 값이 0x4C000000 값으로 고정이 되어 있으며, 파일의 GUID 값이 항상 00021401-0000-0000-C000-000000000046으로 고정이기 때문에 해당 값들을 이용 해 카빙을 수행하면 대략적인 lnk 구조를 파악 할 수 있다.


하지만 CustomDestination 파일 구조에서는 깨진 lnk 구조가 존재 할 수 있다. 깨진 lnk 구조는 ExtraData의 블록 시그니처 값으로 확인하면 쉽게 확인 할 수 있다. tzworks의 lp 도구도 slack 옵션을 이용하면 해당 방법을 이용 해 lnk 구조를 카빙하여 그 결과 값을 보여준다.


ExtraData 구조체는 성질이 optional이기 하지만, 실제로는 필수 구조체이다. 해당 구조체에 Machine ID 등에 값이 저장되기 때문이다. ExtraData 구조체 내부에는 또 여러개의 구조체 블록이 존재하는데, 이때 각 구조체 블록들은 블록 시그니처를 가지게 된다. 해당 시그니처는 몇 개 되지 않기 때문에 해당 시그니처들로 lnk 구조가 정상적이지 않은지 판별 할 수 있다.


아래는 구현한 도구의 결과 샘플이다.


 [-] Lnk Structure Carving ...

 JumpList File Name : CustomDestinations\5d696d521de238c3.customDestinations-ms

 Offset(10) : 7042

 Lnk Attributes : ARCHIVE

 Lnk Created Time(Local) : 2014/03/04 13:23:43 Tue

 Lnk Modified Time(Local) : 2014/04/30 10:46:34 Wed

 Lnk Accessed Time(Local) : 2014/04/24 09:26:06 Thu

 Drive Type : DRIVE_FIXED

 Lnk Size : 841032

 Volume Serial Number : 2718108183

 Local Base Path : C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

 Relative Path :

 Working Directory :

 Target File Description :

 Command Arguments : http://for-md.org/

 Icon Location : C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\JumpListIcons\670E.tmp

 NetBIOS Name : maj3sty

 MAC Address : e9-1f-74-82-03-a1

 ItemIDList : P???i↖+00?/C:\?얛PPROGRA~2|絶??얛P*RProgram Files (x86)@shell32.dll-21817P1dD?Google:絶dD?dD?*?GoogleP1얛?Chrome:絶dD?얛?*BChrome\1얛?APPLIC~1D絶dD?얛?*~?Application\2H?쁃( chrome.exeB絶dD?얛?뺄@chrome.exe

 ExtraData : 1SPS?XF퍵8C샜?쁬?



점프 목록을 통해 우리가 지금까지 얻었던 데이터들 이외에 많은 데이터들이 있었다는 것을 알 수 있었다. 해당 데이터들의 해석은 분석가들이 해야 할 몫이기에 여기서는 따로 언급하지 않았다.


지금까지 소개한 데이터들로 인해 분석가들이 조금 더 많은 흔적들을 찾고 어떠한 행동에 대해 밝혀냈는데 도움이 되었으면 좋겠다.


 * 참고 : 현재 글에서 소개한 도구는 내부적인 검토가 끝난 후 무료로 배포 될 예정입니다.


안티 포렌식에서 가장 간단하게 할 수 있는 것 중 하나가 시간 변경이다. 운영체제의 시간을 변경하여 두면 이후에 일어나는 일들의 시간이 시스템 시간에 맞춰지기 때문에 추후에 타임라인 분석등을 진행 했을 때 분석에 어려움을 겪을 수 있다. 이번 글에서는 사용자가 운영체제에서 지원하는 기능으로 시간을 변경 했을 때 어떤 흔적들이 남는지 카테고리 분류별로 알아볼 예정이다.


해당 글에서 정한 카테고리는 프리패치, 이벤트로그, 레지스트리, 파일시스템 로그 총 4가지 분류이며, 각각의 카테고리별로 Windows XP와 Windows 7을 중심으로 컨트롤 패널 기능과 명령 프롬프트 기능을 이용했을 때 남는 흔적들을 정리 해 보도록 하겠다.


1. Prefetch

 1) Windows XP

Windows XP의 경우 시작표시줄에 있는 패널을 이용 해 날짜를 변경하려 할 경우 RUNDLL32.EXE의 프리패치가 생성되며 해당 참조 목록에 W32TIME.DLL이 존재한다. 하지만, 컨트롤 패널을 열었을 경우에도 해당 흔적이 남기 때문에 날짜를 변경 했다고 확정 할 수는 없다.


[그림 1] -  W32TIME.DLL


 2) Windows 7

Windows 7의 경우 컨트롤 패널을 이용할 경우 RUNDLL32.EXE의 프리패치가 생성되며 RUNDLL32.EXE의 참조 목록에 TIMEDATE.CPL이 존재한다. 하지만, 컨트롤 패널을 열었을 경우에도 해당 흔적이 남기 때문에 날짜를 변경 했다고 확정 할 수는 없다.


[그림 2] - TIMEDATE.CPL


프리패치의 경우 응용프로그램의 실행과 관련이 있을 뿐, 기능의 수행과는 관련이 없어 정확하게 날짜를 변경했다는 확인을 할 수는 없다. 확인이 아닌 정황만을 포착할 수 있으므로 프리패치에서 이와 같은 흔적들을 발견했다면 다른 추가 흔적을 분석 해 시간변경이 이루어졌다는 것을 파악해야 할 것이다.


그리고 Windows XP/7은 명령프롬프트를 이용해서 날짜를 변경 했을 때 CMD.EXE 프리패치만 생성 될 뿐, 뭔가를 파악하거나 의심할만한 흔적이 남지 않는다.


2. Event Log

 1) Windows XP

Windows XP의 경우 컨트롤 패널과 명령프롬프트를 이용 해 시간을 변경하였을 경우 다음과 같은 이벤트로그들이 남는다.


 - Event ID 520 : Security 카테고리에 남으며, 변경 전/후의 시간을 알 수 있다. 해당 이벤트로그는 컨트롤 패널과 명령프롬프트 모두 남는다.


[그림 3] - 컨트롤 패널을 이용하여 변경 하였을 시 생성되는 이벤트로그 모습


[그림 4] - 명령프롬프트를 이용하여 변경 하였을 시 생성되는 이벤트로그 모습


해당 이벤트 로그에서는 시간을 변경한 사용자, 프로세스, 변경 전/후의 시간 정보를 모두 알 수 있다.


 - Event ID 577 : Security 카테고리에 남으며, Event ID 520 이벤트가 남기전에 생성되는 이벤트로그로 어떤 권한을 사용 했는지 알 수 있는데 시간 변경 권한은 SeSystemtimePrivilege을 이용한다. 520 이벤트의 기록이 사라졌더라도 시스템 시간을 변경했다는 사실을 파악 할 수 있다.


[그림 5] - 시스템 시간 변경을 위해 SeSystemtimePrivilege 권한을 사용하여 이벤트로그가 남은 모습


명령프롬프트를 사용했을 경우에도 577 이벤트로그는 컨트롤 패널과 동일하게 생성된다. 하지만 위 두 가지의 이벤트로그는 설정을 통해서만 남으므로 기존에 해당 이벤트로그가 생성될 수 있도록 설정을 해주어야 한다.


 2) Windows 7

Windows 7의 경우 컨트롤 패널과 명령프롬프트를 이용 해 시간을 변경하였을 경우 다음과 같은 이벤트로그들이 남는다.


 - Event ID 4616 : Security 카테고리에 남으며, 변경 전/후의 시간을 알 수 있다. 해당 이벤트로그의 생성을 위해서는 설정이 필요하다.


[그림 6] - Event ID 4616


 - Event ID 20000 : Application and Service Logs\Microsoft\Microsoft\Windows\DateTimeControlPanel\Operational 카테고리에 남으며, 컨트롤 패널에 의한 시간 변경이 이루어졌을 때 생성되는 이벤트 로그이다. 명령프롬프트를 이용 해 시간을 변경하면 해당 카테고리에는 이벤트로그가 생성되지 않는다.


[그림 7] - Event ID 2000


 - Event ID 1 : System 카테고리에 남으며, 변경 전/후의 시간을 알 수 있다. 해당 이벤트로그는 컨트롤 패널과 명령프롬포트 상관없이 생성 된다.


[그림 8] - Event ID 1


 - Event ID 34 : System 카테고리에 남으며, 시간 변경 여부를 확인 할 수 있다. 시간을 변경 할 때 발생하는 오류를 기록하는 이벤트로그인데 해당 이벤트로그를 통해 정확한 시간 변경 값을 알수는 없지만, 시간을 임의로 변경하려고 했던 행동에 대한 판단은 가능하다. 해당 이벤트 로그의 생성을 위해서는 설정이 필요하며, 명령프롬프트를 이용한 시간변경에도 동일한 이벤트로그가 남는다.


[그림 9] Event ID 34


참고로, Windows XP에도 Event ID 34와 동일한 이벤트로그가 남는다.


3. Registry

 1) Windows XP

 - HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{75048700-EF1F-11D0-9888-006097DEACF9}\Count\HRZR_EHAPCY:gvzrqngr.pcy


위 레지스트리 값을 분석하면 컨트롤 패널인 timedate.cpl의 실행 횟수를 알 수 있다. 그러나 프리패치 흔적과 마찬가지로 시간을 변경했다는 확인은 할 수 없다.


 2) Windows 7

Windows 7은 시간을 변경하였을 때 레지스트리에 흔적이 남지 않는다.


4. FileSystem Log

 1) Windows XP

Windows XP의 경우 프리패치등의 파일이 생성되는 것을 제외하고는 시간변경과 관련 된 흔적이 남지 않는다.


 2) Windows 7

Windows 7의 경우 기본적으로 위에서 소개 되었던 DateTimeControlPanel\Operational 이벤트 로그가 생성되기 때문에 해당 이벤트 로그의 생성을 위해 파일의 생성 이벤트가 발생한다.


[그림 10] - FileSystem Log


5. 결론

시스템 시간 변경에 관련한 흔적은 의외로 많은 곳에 남는다. 기본적으로 남는 흔적이 아닌 것도 있지만, 간단한 설정으로 얻을 수 있는 정보들이다. 정보를 얻어 이러한 행동을 파악하는 것도 중요하지만 사전에 방지하는 것이 더 중요한 일이다. 간단하게 Windows의 로컬보안정책을 통해 아래와 같은 사항을 적절히 수정한다면 사전에 시스템 시간 변경을 방지 할 수 있다.


[그림 11] - 로컬보안정책(Windows 7)


[그림 12] - 로컬보안정책(Windows XP)



  1. BlogIcon 카카루 2014.06.05 04:36

    윈도우2000프로페셔널 버전에 시간변경 기록을 확인하는 방법이 궁금합니다

    • Favicon of https://maj3sty.tistory.com BlogIcon MaJ3stY 2014.06.11 13:45 신고

      Windows 2000의 경우 XP와 거의 동일합니다.

      추가적인 분석을 해봐야 정확하겠지만, XP와 2000은 커널이나 다른 형태가 대부분 유사하므로 남는 흔적또한 대부분 동일합니다.

  2. Favicon of https://shihis123.tistory.com BlogIcon Ghomdori 2020.08.27 09:02

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

우리나라는 한글과 컴퓨터 회사에서 만든 한컴오피스를 공공기관부터 시작 해 일반 사용자들까지 굉장히 많이 쓰고 있어, 공격자들에게 공격 타겟으로 많이 설정되어 공격을 당하곤 한다. 한컴 오피스에서 특히 '한컴오피스 한글'은 많은 해커들에게 공격 타겟이 되곤 하는데, 얼마전부터는 특정 대상을 공격하는데도 '한컴오피스 한글'의 제로데이 취약점이 이용되기도 하였다.


해당 글에서는 윈도우에서 지원하는 로깅인 이벤트 로그에서 APT 공격 또는 악성코드 공격에 해당하는 이벤트 로그를 살펴볼까 한다.

본글에서 이루어진 작업들은 모두 Windows 7 32bit Enterprise, 한컴오피스 한글 2010에서 진행되었으면, 공격에 사용 된 샘플은 실제로 배포 되었던 '북한방송 주요논조.hwp' 파일로 진행 하였다.


해당 글에서 중점적으로 볼 부분은 '공격의 시점'과 '공격의 유무 판단'이다. 정확히 언제 어떤 부분을 통해 공격이 진행 되었는지 파악해 보고자 한다.


사용자가 공격 샘플을 정상 파일로 오인하고 실행을 하게 되면, 한글 문서가 열리며 공격은 시작하게 된다. 공격이 시작되면 다음과 같은 이벤트로그 카테고리에 흔적이 남게 된다.


[Application and Service Logs\Microsoft\Microsoft\Windows\WER-Diagnostics\Operational]

공격의 판단을 어떻게 해야 할까? WER-Diagnostics\Operational 로그에서 Event ID 2에 해당하는 로그는 힙의 손상을 알려주는 로그이다. 대부분의 한글 문서를 이용한 APT 공격은 힙 메모리 취약점을 기반으로 하기 때문에 취약점을 이용한 공격이 이루어질 때에는 heap overflow 기법을 사용하게 된다. 이 때 힙의 손상이 일어나게 되면 윈도우는 이를 catch하여 이벤트 로깅을 수행한다.


[그림 1] - Event ID 2


이벤트 로그가 기록 된 날짜가 공격이 시작 된 시점이라고 볼 수 있다.  


[Application(응용 프로그램)]

[그림 2] - Event ID 1000


Event ID 1000은 Window Application Error 로그로 공격자의 공격이 완벽하게 끝날 경우 남지 않을 수 있는 로그이다. 하지만, 사용자마다 환경이 다양하고 설정이 다양하기 때문에 공격자가 완벽하게 공격을 끝내기란 쉽지 않기 때문에 해당 로그도 눈여겨 볼만하다. 해당 이벤트 로그에서는 공격 당한 응용 프로그램의 이름, 응용 프로그램 시작 시간등을 알 수 있다. 응용 프로그램의 시작 시간은 NTFS FileTime(Big Endian) 타입이다.


[그림 3] - Event ID 1001


[그림 3]에서 보이는 Event ID 1001은 WER(Windows Error Reporting) 정보이다. 프로세스 충돌이나 에러와 관련 된 정보들이 기록되어 있으며, 프로세스가 정상적으로 종료 될 때에는 남지 않는다. 공격을 당했다는 사실을 뒷받침 할 수 있는 참고용으로 보면 된다.


[그림 4] - Event ID 3001


Event ID 3001은 프로세스간의 관계를 보여준다. 간혹 다른 프로세스에서 다른 프로세스를 Kill하는 경우가 있는데 이때 프로세스는 강제적으로 종료 된 것이므로 exit가 아닌 Terminate 상태를 가지게 되고 윈도우는 이를 이벤트 로그로 남긴다. 하지만, 해당 이벤트 로그는 윈도우에서 기본으로 남기는 이벤트 로그가 아니며, Silent Process Exit Monitoring 설정을 통해 남기게끔 해야 한다. 설정은 두 가지 방법이 있다. 첫 번째로 레지스트리를 이용하는 방법, 두 번째로 도구를 이용한 방법이 있다.

레지스트리를 이용하는 방법은 아래의 레지스트리 경로로 접근 해 GlobalFlag(REG_DWORD) 값을 생성하여 0x200으로 설정하여 주면 된다.


키 : HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProcessName\GlobalFlag 

값 : 0x200


또 다른 방법으로는 도구를 이용하는 방법이 있다. 도구는 Windows Debugging 툴을 설치하면 gflag.exe 라는 도구가 있는데, 해당 도구를 통해 설정을 하면 된다. 해당 도구의 자세한 사용법은 여기를 참고하기 바란다.


참고로 해당 이벤트로그 카테고리에는 Event ID 3000 로그도 남는다. 해당 로그는 프로세스의 생성 시간, 종료 타입, 종료 시간을 담고 있는데, 프로세스의 타입을 파악하면 프로세스가 시스템에 의한 종료 또는 사용자에 의한 종료인지 프로파일링이 가능하다.


[Security(보안)]

간혹 취약점을 이용하는 공격은 권한을 상승하는 행위도 한다. 이때 권한에 관한 이벤트 로그는 Security 카테고리에 남는다.


[그림 5] - Event ID 4624


해당 로그는 계정 로그온에 관한 이벤트 로그인데, 강제적인 권한 상승에도 해당 로그가 남는다. [그림 5]에서 보는 로그도 공격 샘플이 강제적으로 탈취한 SYSTEM 권한이다. 이 다음으로 해당 계정에 부여 된 여러가지 권한들을 보여주는 Event ID 4672가 곧바로 생성 된다.


[시간 연속성을 이용한 분석]

하나의 이벤트 로그로만 본다면 공격이란 것을 파악 할 수 없지만, 시간 연속성을 이용 해 분석 해 보면 공격의 특정한 시점과 흐름을 파악 할 수 있다. 다음은 공격 샘플의 흔적들을 시간 순으로 정리 해본 것이다.


1. 문서 파일 실행(프로세스 생성) : 2014-04-04 04:57:18

2. heap overflow 발생(공격의 시작) : 2014-04-04 오후 04:57:24

3. 권한 상승 : 2014-04-04 오후 4:57:24

4. 응용 프로그램 오류(공격 실패) : 2014-04-04 오후 4:57:24

5. 프로세스 종료 : 2014-04-04 오후 4:57:33


만약 공격 샘플의 공격이 성공하였다면, 4번 대신 프로세스 생성의 이벤트 로그(Event ID 592)가 있을 수 있다. 3번과 4번은 초까지의 시간이 같아 순서를 정확히 알 수 없지만, 공격의 흐름을 생각 해 보면 권한 상승 후 프로세스 생성 또는 파일 생성 등의 악성행위를 하려 할 때 응용 프로그램의 취약한 모듈과 환경의 영향으로 응용 프로그램이 예기치 않게 종료되는 것이 상식적으로 더 맞아 위와 같이 배치하였다.


한글 문서를 대상으로 살펴보았지만, MS Office 군도 세계적으로 많은 취약점이 발견되고 사용된다. MS Office는 Windows와 같은 회사에서 탄생한 제품이기 때문에 이벤트 로그내에 따로 MS Office의 이벤트 로그만 남겨지는 곳이 있다.


경로 : Application and Service Logs\Microsoft Office Sessions


위 경로로 들어가면 MS Office 군의 비정상적인 종료와 관련 된 로그를 볼 수 있어, 해당 로그와 위에서 소개 된 여러 로그들을 토대로 공격의 판단/시점등을 파악 할 수 있다.


[결론]

APT가 정교한 공격이라고는 하지만, 악성코드 제작자 대부분은 모든 환경을 고려해서 악성코드를 제작하지 않는다. 그러므로 위에서 소개 된 여러 이벤트 로그들이 충분히 남을 수 있고, 해당 이벤트 로그들을 통해 공격의 여러가지 정보들을 파악 할 수 있다. 때에 따라 필요한 이벤트 로그가 Windows의 기본 설정으로 되어 있지 않아 남지 않을 수 있으므로 사전에 필요한 이벤트 로그들을 체크하여 대비를 해 두는 것이 좋다고 생각한다.

NTFS에는 M(Modified), A(Accessed), C(Created), E($MFT Entry Record Update Time)이 있습니다. 

파일의 이동과 복사 등의 많은 상황에 따라 시간 값이 변화 되는 특징을 정리 해 보았습니다.

외워두면 편하겠지만, 외워야 할 경우들이 많아서 참고 시 참고용도로 보시면 좋을 것 같습니다.

<그림을 클릭하면 크게 보실 수 있습니다.>

얼마 전 Shmoocon 컨퍼런스에서 물리 메모리를 대상으로 한 안티 포렌식 기술이 발표되었다. 

ADD(Attention-Deficit-Disorder)라고 하는 PoC Tool과 함께 발표되었는데 아이디어는 상당히 간단하다. 이번 글에서는 해당 기술의 원리를 알아보고 탐지 방법을 알아 볼 예정이다.


1. 들어가며

메모리 포렌식은 지금까지 굉장히 빠른 발전을 해 왔다. 그 중에서 Volatility가 단연 사람들에게 많이 알려지고 발전도 가장 많이 되어 있는데, ADD는 Volatility가 메모리를 분석 할 때의 방법을 역으로 이용 해 허위 메모리 정보를 삽입 해 분석가의 분석 시간과 시야를 방해 한다. 예를 들어, 프로세스 목록에서 허위 프로세스를 삽입 해 분석가가 허위 프로세스와 진짜 목적의 프로세스를 구분하는데 시간을 오래 걸리게 한다던가, 네트워크 연결 정보를 허위로 삽입하여 분석가의 분석 시간을 늘린다던가 하는 방법이 있다.


현재 해당 기술은 Process, Network Connection, File Object에 대해서만 구현이 되어 있는 상황인데, 발표자는 발표를 통해 해당 기술을 더 발전 시켜 Mutexes, Symlinks, Drivers, DLL 등을 추가로 연구 해 구현하겠다고 밝혔다. 발표가 나고 얼마 지나지 않아 그 자리에서 발표를 듣던 사람이 해당 기술을 분석 할 수 있는 방안을 블로그를 통해 내놓았는데 글을 살펴본 결과, ADD 도구를 사용 했을 때의 아티팩트를 수집 해 허위 아티팩트를 구별 해 내는 방법이었다. 하지만 이 기술은 도구가 아닌 악성 프로세스(루트킷 등)이 많이 사용 할 수 있는 기술이기 때문에 조금 더 범용적으로 해결 방안을 찾아야 한다.


위 블로그 글에서 제시한 방법은 굉장히 간단하면서 정확하다. 하지만 도구에만 적용이 되기 때문에 활용범위는 그다지 크지 않다. 방법은 다음과 같다.


[블로그 글에서 제시한 방법]

 1. 메모리에서 유니코드 문자열을 모두 추출 한다.


 2. 유니코드 문자열 목록에서 도구에서 사용 된 옵션 또는 프로그램의 이름 등의 특정 문자열을 검색한다.


 3. 명령 행에서 사용 된 인자 값들을 보고 허위 아티팩트들을 가려낸다.


위 방법은 사용자가 직접, 또는 프로그램에서 System() 함수를 사용 했을 때 메모리에 남는 명령 줄로 허위 아티팩트르 가려내는 간단한 방법이지만 앞에서 말했듯이 해당 기술은 악성코드가 사용 했을 때 그 위력이 더 크기 때문에 악성코드에서 사용 했을 때와 사용자가 사용 했을 때를 모두 감안한 측면에서 바라보아야 한다. 


이제부터 기술의 원리, 탐지 방안등에 대해서 이야기 해 보도록 하겠다.


2. ADD 원리

Volatility는 메모리 이미지에서 여러가지 검증 단계를 거쳐 정보들을 분석 해 사용자에게 보여준다. 하지만 이 검증 단계만 모두 만족한다면 허위 정보 또한 진짜 정보로 둔갑 할 수 있다.


 2.1 Fake Process

 ADD는 Fake Process 정보를 다음과 같은 검증 단계를 모두 만족 할 수 있도록 인위적으로 생성 해 메모리에 삽입한다.


그림 1 - Process Check 1


그림 2 - Process Check 2


위와 같은 Volatility의 검증 단계를 ADD는 다음과 같이 만족하였다.


그림 2 - ADD Fake Process


간단하게 살펴보면 사용자에게 Process Name, PID, CimeL, CTimeH, ExitTmeL, ExitTimeH을 받고 EPROCESS에 삽입 할 최소한의 정보와 함께 EPROCESS를 생성하기 위해 만든 허위 EPROCESS 구조체에 넣고 OBJECT_HEADER 구조체와 함께 해당 구조체를 메모리에 임시저장 해 둔다. 허위 EPROCESS 구조체는 다음과 같다.


그림 3 - 허위 EPROCESS 구조체


여기서 중요한 사실은 EPROCESS의 구조체 모두에 대한 정보를 생성하지 않는다는 것이다. 넣을 부분만 알아보기 편하게 기존의 EPROCESS 구조체 멤버와 동일하게 변수를 선언하고 다른 부분들은 DWORD f<숫자>형태로 선언해 크기만 맞추어 주었다. 사실 EPROCESS의 모든 정보를 생성하여 실제 프로세스처럼 넣어주게 될 경우, 새롭게 프로세스를 하나 생성하는 편이 훨씬 제작자나 퍼포먼스 측면에서 좋기 때문에 굳이 생성하여 넣어 줄 필요가 없는 것이다.


임시저장 된 구조체는 디바이스 드라이버로 전송 되어 커널 메모리에 적재되는데 이 부분은 모든 기능을 알아본 후에 살펴보도록 하자.


 2.2 Fake Network Connection

 Network Connection에 대한 Volatility의 검증 단계는 다음과 같다.


그림 4 - Network Connection Check


ADD는 위 검증 단계를 모두 만족하기 위해 다음과 같은 허위 정보를 생성하였다.


그림 5 - Fake Network Connection


들어가는 정보가 Fake Process와 다를 뿐 순서나 원리는 동일하다.


 2.3 Fake File Object

 File Object에 대한 Volatility의 검증은 다음과 같다.


그림 6 - File Object Check


그림 - 7 Fake File Object


위 세가지 방법들로 생성 된 허위 구조체 정보는 다음과 같이 DeviceIOControl() 함수를 통해 디바이스 드라이버 파일(ADDdriver.sys)로 전송 된다.


그림 8 - DeviceIOControl()


방법들을 보면 공통적으로 Tag가 보인다는 것을 알 수 있다. 그래서 ADD는 드라이버 파일에서 커널 메모리를 할당 받아 Tag를 부여하고 바로 뒷 공간에 유저영역에서 생성한 구조체들을 저장 해 Volatility가 EPROCESS를 스캐닝 할 때 허위 정보로 판단하지 못하도록 한다.


드라이버 파일에는 ADDDeviceControl() 함수가 있고 DeviceIOControl() 함수가 실행되면서 드라이버 파일에 있는 DriverEntry() 함수에 IRP_MJ_DEVICE_CONTROL 메시지가 전달 되어 MajorFunction[]에 있는 ADDDeviceControl() 함수가 실행 된다.


ADDDeviceControl() 함수에는 다음과 같이 ExAllocatePoolWithTag() 함수로 태그와 함께 커널 메모리를 할당 받는 부분을 확인 할 수 있다.


그림 9 - ExAllocatePoolWithTag()


커널 메모리를 할당 받을 때 부여하는 태그는 총 3개로 각 태그가 의미하는 바는 다음과 같다.


 - 0xE56C6946 : File Object Artifact


 - 0xE36F7250 : Process Artifact


 - 0x45706354 : Network Artifact


즉, Volatility는 EPROCESS Scanning 방법을 이용 할 때 Tag를 먼저 찾고 그 이후에 있는 EPROCESS를 파싱하기 때문에 해당 방법을 사용하면 허위 정보도 Volatility는 진짜 정보로 인식하게 되는 것이다. 허위 정보가 삽입 된 메모리 이미지를 Volatility로 분석하였을 경우 다음과 같이 나오게 된다.


그림 10 - 허위 프로세스 정보


허위 정보는 pslist로는 나오지 않고 psscan으로 스캔해야 나온다. 이런 결과를 자세히 보지 않는다면 숨겨진 악성 프로세스라고 오해를 할 수 있다. 이제 이에 대한 탐지 방법을 알아보도록 하자.


3. ADD 탐지 방법

먼저 제작자가 밝힌 탐지 방법에 대해서 잠깐 보도록 하자. 발표자는 발표 당시, ADD 탐지 방안으로 "고양이와 쥐 게임", ADD Driver Hunt 등을 언급하였다. "고양이와 쥐 게임"은 서로 계속해서 단점을 보완해 나가는 것을 말하며, ADD Driver Hunt는 커널 메모리를 받기 위해 사용하는 디바이스 드라이버를 찾아내는 것을 말한다. 하지만 필자는 이번 글에서 이와 다른 방법을 소개 해 보고자 한다. 필자가 밝히는 방법은 영구적인 방법이 아닌 한시적인 방법이고 완벽하지 않은 방법이라는 것을 알아두기 바란다. 이 기술에 대한 최종적인 탐지 방안은 제작자가 밝힌 "고양이와 쥐 게임"이 가장 현실적인 방안이다.


 3.1 Fake Process 탐지 방법

위에서 보았듯이 허위 EPROCESS 구조체를 작성하여 허위 정보를 생성하지만 모든 필드를 사용하지는 않는다. 허위 프로세스는 Volatility에서 제공하는 Volshell로 EPROCESS를 보면 쉽게 파악이 가능하다.


그림 11 - Fake Proces EPROCESS DeviceMap 필드


대표적으로 EPROCESS에는 필수적으로 들어가야 할 필드들이 존재한다. 그 중에 DeviceMap이라는 필드가 존재하는데 해당 필드는 사용자 별로 사용자 상태 정보를 저장하는 필드이기 때문에 값이 필수적으로 삽입되어야 한다.


또, 허위 프로세스는 스레드를 가지고 있지 않다. 그렇기 때문에 thrdscan 등의 플러그인을 사용 해 ETHREAD 구조체를 스캔 해 보면 쉽게 허위 프로세스를 파악 할 수 있다.


마지막으로 아직 기술이 초기 상황이어서 그런지 어딘가 모르게 허술하다. 실제 프로세스의 EPROCESS와 비교해 보면 크기부터 조금씩 다르며 필드 또한 모두 쓰이지 않기 때문에 내포하고 있는 정보가 거의 없어 프로세스라고 하기에 조금 무리가 있어 보인다. 그래서 아직까지는 EPROCESS와 여러 프로세스적 요소들을 결합하여 분석하면 쉽게 허위 프로세스를 찾아 낼 수 있다.


해당 기술에 대한 대응방안이 계속해서 공개되고 안티 포렌식 기술에서 이를 대응하면 할수록 점점 CreateProcess()를 통해 프로세스를 생성하는 것이 오히려 더 편하게 느껴지므로 해당 방법은 더 이상 발전은 무의미 할 것으로 생각 된다.


 3.2 Fake Network Connection

해당 기술에 대한 대응방안은 뚜렷하게 없다. 하지만 분석하는데 해당 기술은 크게 영향을 미치지 못한다. 허위 프로세스를 식별하여 진짜 프로세스를 찾아내면 진짜 프로세스를 분석하여 진짜 네트워크 연결을 판별 할 수 있기 때문에 해당 기술에 대한 탐지 방안은 독립적으로 존재하지 않지만 독립적으로 존재할 필요도 없다.


 3.3 Fake File Object

해당 기술에 탐지 방안은 굉장히 쉽다. 해당 메모리를 이미징 한 PC의 디스크와 대조해 보면 된다. Volatility에서 filescan 플러그인을 사용하면 Root 경로부터 파일의 경로를 표시하여 준다. 그러므로 디스크에서 해당 경로에 실제로 파일이 존재하는지만 확인하면 된다.



4. 마치며

정말 재밌는 기술이다. 물리메모리를 대상으로 한 안티 포렌식 기술은 지금까지 별로 없었다. 하지만 해당 기술로 안티 포렌식 기술은 메모리를 대상으로 하여 한단계 발전하였음을 느낄 수 있었다. 아직은 많이 부족한 기술이지만 앞으로 악성 프로그램들이 사용하지 말란 법도 없으며, 또 사용 했을 경우 그 효과는 꽤 클 것으로 예상이 되는 만큼 해당 기술의 탐지 방안도 미래를 내다보며 연구되어야 한다고 생각 된다.

+ Recent posts