분석하기에 앞서 컴퓨터 구조를 먼저 살펴봐야 한다. 기본 요소이자 분석대상이기 때문이다.
위에서 아래로 4계층이 사용자의 명령이 흘러가는 방향이다.
1. Application(사용자 명령을 처리 하기 위한 방법을 정의한 것, 컴파일러/데이터베이스/상용프로그램…, 프로그램을 실행하다가 실행시간이 바뀌었을 때, 내부 메타데이터의 변경 여부를 확인해 입증해볼 수 있음, 해시 변화 분석 및 테스트.)
2. Operation System(사용자 인터페이스 정의, 입출력 보조, 자원관리/ 파일시스템을 해석해 사용자의 명령이 하드웨어에 인터페이스 될 수 있도록 하는 역할 수행, 메모리를 효율적으로 관리하도록 artifact 분석)
3. File system(자료 기억 장치에 파일을 저장과 관리하기 위한 체계를 정의한 것, 파일을 관리하기 위해 필요한 정보들을 “Meta data”라고 칭함. - 중요한 이유가 파일 시스템 상에 어떤 artifact가 남는건지 분석할 필요가 있기 때문)
4. Hardware(컴퓨터 연산을 위해 필요. 교과서적으로 다 알지만, 컴퓨터를 다 분해해본 학생 수가 적다. 컴퓨터 연산을 위해 필요한 자원들,CPU,기억장치, 입출력 장치)
그러다 수업 중 다음과 같은 질문이 나왔다.
Q: windows 운영체제의 artifacts는 왜 남는가?
수업 중 답변으로 다음과 같은 답변이 나왔다.
프로그램 행위 기반 artifact가 남기 때문에 그리고 event log이 남기 때문. (정확히는 log라서 남는 게 아니라, event log의 시간을 수정한 기록까지 남아있음. 그래서 다시 돌아온 세션 기간 사이에 사건 관련된 것들을 찾아낼 수 있다, 또한 windows10부터 system reset 초기화 기능이 있는데, 파일만 날릴 수 있고, 설정까지 전부다 날릴 수 있다. 이는 log파일의 string값을 없애는 방법을 이용한다.)
헷갈리는 부분이라 다음과 같이 구체적인 예시와 함께 추가 조사를 진행했다.
artifact라 함은, 운영체제를 사용하면서 자동으로 생성되는 흔적을 말한다.
BoB 수업시간에 생성증거와 보관증거에 대해 배웠다. 생성증거는 시스템이나 애플리케이션이 자동으로 생성한 데이터 생성증거는 시스템이 자동으로 생성한 데이터이기 때문에 보관증거와 달리 전문법칙이 적용되지 않아 증거로서 가치가 높다. 이러한 생성증거를 artifact라고 한다.
예시로는 메타데이터, registry, event log, 프리/슈패치 등이 있다.
반면 보관증거는 사람의 생각이나 감정을 표현하기 위해 사람이 직접 작성한 것이라 볼 수 있다. 보관증거의 예시로 직접 작성한 메일의 내용이나 블로그 및 소셜 네트워크 작성, 직접 작성한 문서 등이 포함된다. 우리는 생성증거에 초점을 둔다.
특히 윈도우 artifact란, 앞서 생성증거의 예시로 들었던 registry와 같이 윈도우의 기능을 구현하는데 있어 필요한 요소로부터 찾을 수 있는 증거 정보다.
윈도우 artifact의 대표적인 예시로 LNK file을 들 수 있다.
LNK 파일은 Microsoft Windows 운영 체제에서 사용되는 바로 가기(Shortcut) 파일 - (사용자가 쉽게 액세스할 수 있는 작업을 실행하는 데 사용됨.)로 볼 수 있다.
이 파일은 특정 프로그램, 파일, 폴더 또는 웹 페이지에 대한 참조를 포함하는 작은 파일로 생각하면 된다.
일반적으로 바탕 화면이나 작업 표시줄, 시작 메뉴 등에 있는 아이콘 같은 gui로 알려진 것들은 실제 프로그램이나 파일의 위치로 직접 가리키지 않는다. 이들은 LNK 파일을 통해 해당 위치를 참조한다. 특히 바탕화면 외에도 최근 문서 폴더나 시작 프로그램 등에 생성될 수 있다. 만약 사용자가 LNK 파일을 더블 클릭하게 되면 해당 프로그램, 파일 또는 폴더가 실행된다.
LNK 파일의 Structure
보통 LNK 파일의 Structure를 말할 때, Shell Link Binary File Format의 구조로 설명한다.
Shell Link Binary File Format는 기본적으로 5개 구조체로 이루어져있다고 말한다.
- SHELL_LINK_HEADER(default): 이는 76byte의 기본적인 헤더 정보로 식별정보나 타임스탬프, 선택적인 구조의 형태가 명시된 플래그의 정보를 포함한다.
- LINKTARGET_IDLIST(optional): 대상의 다양한 정보를 가진 구조로, 선택적인 항목이다. 선택적인 이유는 HasLinkTargetIDlist와 shellLinkHeader flag가 설정된 경우에만 존재하게 된다.
- LINKINFO(optional): 마찬가지로 선택적인 항목으로, 링크 대상을 분석하기 위한 데이터가 명시되어 있다.
- STRING_DATA(optional): 역시 선택항목으로 shellLinkHeader flag의 bits에 의해 지정된다.
- EXTRA_DATA(optional): 링크 대상에 대한 화면 표시 정보를 비롯한 문자열 코드 페이지와 환경변수 등의 정보를 저장하게 된다.
LNK 파일이 남는 원인
우선 LNK 파일이 남는(생성되는) 원인(조건)은 아래와 같다.
1) 사용자가 편의를 위해 바로가기를 생성한 경우
2) local (+ remote) 데이터 파일, 문서를 연 경우
3) 특정한 응용프로그램을 실행할 때 바탕화면에 자동으로 생성되는 경우(바탕화면에 해당 파일이 저장되도록 파일 경로가 설정된 경우)
4) 바탕화면이 아니더라도 사용자의 설정 또는 컴퓨터 기본 설정에 따라 최근 문서 폴더나 시작 프로그램에 저장되는 경우
5) 프로그램을 설치할 때, 설치 프로세스는 종종 시작 메뉴나 바탕 화면에 프로그램에 대한 바로 가기가 생성되는 경우
6) 사용자가 실행한 프로그램이나 파일은 운영 체제에 의해 실행 기록이 남는 경우
LNK 파일을 남기는 게 운영체제에게 주는 효율
1. Fast Access and efficient work flow
아무래도 가장 큰 효율은 빠르게 access 가능하다는 것이다. LNK 파일을 활용하면 자주 사용하는 프로그램과 파일과 폴더에 빠르게 접근 가능하도록 할 수 있다. 더불어 사용자 개인 설정을 통해 바탕화면이나 작업 표시줄, 시작 메뉴에 바로가기를 생성해 작업 효율을 향상시킨다.
2. (execution) History
운영체제 상에 실행한 프로그램이나 실행 파일에 대한 기록을 갖는다. LNK 파일을 이용하면 사용자는 이전에 사용한 프로그램에 대한 기록을 쉽게 확인하고 접근 가능한 특징을 갖게 된다. 이는 1번과 유사한 맥락으로 사용자의 work flow를 쉽게 파악 가능하다는 장점으로 볼 수 있다.
3. customizing and user-defined attribute
LNK 파일을 사용해 각 사용자의 기호에 맞게 여러 속성들을 조정할 수 있다는 장점이 존재한다. 이러한 특징은 사용자 정의에 따라 다르게 동작하게 만드는 유연성 제공을 목표로 한다.
4. Management of program and file
LNK 파일은 프로그램과 파일의 위치를 가리키기 때문에, 해당 파일이나 프로그램의 위치가 변경되더라도 손쉽게 찾을 수 있다는 특징이 있다. 따라서 파일 관리에 있어 용이성이 큰 장점으로 꼽히며 3번과 동일 맥락에서 유연성을 높여 maintainability를 높이는 효과가 있다.
LNK파일이 가지는 기타 특징
LNK 파일은 바로가기를 통해 사용자의 작업 흐름을 향상시키는 것은 물론, 앞서 말했듯이 자주 사용하는 프로그램이나 파일에 빠르게 액세스하게 해준다는 특징이 있다.
또한 LNK 파일은 다양한 속성을 포함할 수 있는데 특히 다음의 요소를 포함하는 경우가 일반적이다.
1) Shell Item ID List (SHELLITEMID): 앞서 설명한 (file, folder 또는 program과 같은) shortcut에 대한 location또는 target에 대한 Identifier(식별자 정보)를 포함한다. 여기 ID list에는 file path, volume ID, and item attributes 정보가 포함된다.
2) File Attributes: LNK files은 (file size, creation/modification dates, and file attributes (read-only, hidden, etc.))에 대한 정보가 담긴 target item의 attributes들을 저장한다.
3) Icon Location: target item과 관련된 icon의 위치를 지정할 수 있게 된다. 여기에는 아이콘 인덱스를 포함하게 된다.
4) Target Path: 바로가기가 가리키는 항목(프로그램, 파일 또는 폴더)의 경로가 포함된다.
그 밖에도
5) Command-Line Arguments(:target item에 전달해야 할 추가적인 command line 또는 parameter값 저장 가능.)
6) Working Directory
7) Hotkey(단축키)
등이 존재한다.
LNK 파일 분석도구
LNK 파일을 분석할 수 있는 도구에는 LECmd, ShellBagsView, lnk-parse, 010editor, NirSoft ShellExView, Magnet AXIOM, 등이 있다. 이러한 도구를 이용해 LNK파일의 내용을 분석해 각각의 기능과 속성을 분석하는데 도움이 된다.
먼저 LECmd는 command line tool로 알려져있다. 이는 파일 경로나 아이콘의 위치와 같은 LNK 파일의 속성을 확인해 볼 수 있도록 지원한다.
다음으로, ShellBagsView는 windows 쉘 폴더 구조를 분석하는 툴로 유명하다. 해당 툴은 LNK 파일이 참조하는 폴더 경로와 폴더가 열린 시간 등의 정보를 바로 확인 가능한 장점을 지닌다.
lnk-parse는 LNK 파일 분석 도구 중 python을 이용하는 툴이다. 해당 툴은 LNK 파일의 속성과 component들을 파싱하고 여러 정보들을 따로따로 추출해 낼 수 있는 장점을 가진다.
https://pypi.org/project/LnkParse3/ -> LnkParse3 1.2.0 다운 링크
다음으로 LNK 파일을 생성했을 때, 이를 010editor를 이용해 분석하는 실습을 진행해보자.
010editor는 LNK파일의 포맷을 자동으로 분석해주는 특징이 있다. 물론 LNK 파일 뿐 아니라 다른 PE 파일이나 DOCX, PDF 파일 등 다양한 파일 분석을 제공하나, LNK 자동 분석에 있어 상당히 간편한 방식으로 볼 수 있어 유용하다.
먼저 quicksort 구현을 위해 test.py 파일을 만들어두었는데, 이 파일의 바로가기 파일을 생성해 바탕화면에 두었다.
다음으로 010editor를 설치한 뒤, 해당 프로그램에서 lnk file을 분석하는 툴을 추가로 설치해야 한다.
설치하고 나면 lnk file로 target file을 열 수 있다는 문구가 뜬다.
해당 파일을 열자 아래와 같은 화면을 볼 수 있었다.
위 부분에서 상단 Hex값 4C 00 00 00 01 14 02 00는 LNK를 명시하는 값들이다. windows shell link(short)를 나타낸다.
아래 링크 참고
https://www.garykessler.net/library/file_sigs.html
File Signatures
ACKNOWLEDGEMENTS The following individuals have given me updates or suggestions for this list over the years: Devon Ackerman, Nazim Aliyev, Marco Barbieri, Vladimir Benko, Arvin Bhatnagar, Jim Blackson, Keith Blackwell, Alex Boschma, Sam Brothers, David Bu
www.garykessler.net
아래는 template results를 확대 캡쳐한 값.
각 요소의 Name, value, start position(hex), size(hex), color(경계표시 정보)의 정보를 담고 있다.
위에서 살펴보았던 LNK file의 structure 중, SHELL_LINK_HEADER,LINKTARGET_IDLIST, LINKINFO, STRING_DATA, EXTRA_DATA 의 5가지 요소 모두를 확인할 수 있었다. 사실 SHELL_LINK_HEADER만 제외하면 나머지는 optional 요소라 필수적이지 않은데도 해당 바로가기 파일에는 5가지 요소가 모두 있었다.
5가지 요소의 HEX 코드로 표시된 부분은 아래와 같다. 파란색 밑줄이 바로 해당 영역이다.
template results를 잘 보면, 값이 6개 인 것을 알 수 있는데, 이는 STRING_DATA 값이 총 2개이기 때문이다. 첫째는 STRING_DATA Relative_path, 둘째는 STRING_DATA workingDir에 해당한다. 이름에서 추측할 수 있듯이 Relative_path는 상대경로가 지정되어 있고, value를 보면 .\test.py라고 되어 있음을 알 수 있다. 마찬가지로 workingDir는 working directory를 의미하기에 현재 바탕화면의 위치를 절대 경로로 표시하고 있다. C:\users\~~Desktop과 같은 식으로.
1. SHELL_LINK_HEADER
SHELL_LINK_HEADER의 하위 항목을 살펴보면 다음과 같다.
uint32 HeaderSize
구조체의 크기를 명시하는 값으로 value값이 그 값이 4c로 고정되어 있다. 이를 16진수로 나타내면 0x0000004C와 같다.
GUID LinkCLSID[16]
괄호 안 16은 사이즈를 의미한다. CLSID는 COM 클래스 개체를 식별하는 전역적으로 고유한 식별자라고 알려져있다. 말이 조금 어려운데, 실행 중 상태일 때 클래스에 대한 정보를 알려주는 식별자라고 생각하면 된다. 여기서 COM 클래스는 component objet model의 약자로써, 애플리케이션 간의 상호작용이나 코드의 재사용을 지원하는 framework에 해당한다.
위 사진에서 볼수 있듯이 그 값은 항상 고정되어 있다. (value에 그 값이 명시되어 있으면 그 값으로 고정되어 있다는 것.) - {00021401-0000-0000-C000-000000000046}
struct LinkFlags sLinkFlags
shell link와 구조체의 유무에 대한 정보가 명시되어 있는 값이다. - flag에는 28개가 존재한다.
struct FileAttributes sFileAttributes
링크 되어 있는 대상에 대한 정보가 명시되어 있는 데이터다.
FILETIME CreationTime
이는 링크 대상의 생성시간을 나타내는 값이다. UTP(Universal Time Coordinated)를 기준으로 한다.
FILETIME AccessTime
링크 대상의 Access시간을 나타내는 값이다. 마찬가지로 UTP를 기준으로 한다.
FILETIME WriteTime
링크 대상의 Write 시간을 나타내는 값이다. UTP기준이다.
uint32 FileSize
링크 대상의 크기를 나타낸다.
uint32 IconIndex
아이콘의 위치를 인덱스화 한 값이다.
enum ShowCommand
application의 에상된 윈도우의 상태값.
해당 값은 총 3가지의 종류가 존재한다. Normal, Mazimized, Minnoactive 가 그것이다.
첫번째는 응용프로그램이 열려있고, 윈도우에도 정상적으로 표시되는 상태를 의미한다.
두번째는 응용프로그램이 열려있고, 키보드 포커스도 있으나 윈도우에는 표시되지 않는 상태를 의미한다.
마지막은 응용프로그이 열려있고, 키보드 포커스가 없으며 윈도우 상에도 표시되지 않는 상태를 의미한다.
* 키보드 포커스란?
컴퓨터 시스템에서 현재 활성화된 응용 프로그램 또는 컨트롤에 대한 입력을 키보드로 전달하는 상태
(컨트롤 입력 -> 키보드)
키보드 포커스 상태에 있으면 키보드로부터 사용자의 입력을 받을 수 있게 된다.
uint16 Hotkey
바로가기 키가 참조하는 application을 실행하는 데 있어 필요로 하는 키값.
uint16 Reserved[0]
0으로 고정
uint32 Reserved[1]
0으로 고정
uint32 Reserved[2]
0으로 고정
2. LINKTARGET_IDLIST
아래 사진은 LINKTARGET_IDLIST의 하위 리스트를 나타낸다.
IDlist를 나타내는 값들로, sIDList값을 가리킨다. 더불어 unit16 terminalID값도 내포하는데, 0으로 그 값이 고정되어 있다.
uint16 IDListSize
IDlist에 대한 사이즈 정보 값.
여기서 idlist는 일반적으로 파일시스템이나 데이터 구조에서 사용되는 개념으로 알려져있는데, 식별자 ID들의 목록을 의미한다. 일반적으로 IDList는 계층 구조를 가지게되는데, 부모를 참조하는 식별자와 해당 항목 자체의 식별자로 구성되게 된다.
struct IDList sIDList[0], struct IDList sIDList[1]
여기는 IDlist에 itemID list를 저장한다. (구조 배열) // 사실 itemIDlist가 따로 존재한다. 존재한다면 해당 list가 itemID구조 배열인 것으로 보아야 한다.
또한 IDlist에는 itemIDSIZE와 data로 이뤄지는데, data에는 item 상의 shell data source에 정의된 데이터가 표시된다고 한다.
아래 첨부된 사진을 보면 byte data가 size 30만큼의 배열로 할당된 것을 볼 수 있는데, 각 배열 위치마다 서로 다른 값들이 들어간 것을 확인할 수 있다. 아래 data에 들어있는 값은 signed integer에 해당한다. 가령 byte data[4]는 그 값 -15이므로 이를 signed hex값으로 F1과 같이 표현한 것을 볼 수 있다. 주목할 만한 것은 data[6]과 data[13]이다. 'q'와 'o'char를 포함한다. 이는 각 상태를 나타내는 값인 경우가 많은데, 보통 q는 quit, o는 open으로 해석된다.
uint16 TerminalID
itemID의 끝을 의미한다. 여기에는 무조건 terminal 조건인 0으로 나타낸다.
GUID CLSID값은 앞서 다루었지만, COM 클래스 객체를 식별하기 위해 사용하는 식별자라고 생각하면 된다.
아래 GUID CLSID 값은 {B4BFCC3A-DB2C-424C-B029-7FE99A87C641}로 지정되어 있다. 이 값은 바탕화면 값이다.
아래 2번째 그림과 링크 참고.
3. LINKINFO
LINKINFO는 링크의 원본 위치를 찾지 못할 때 해결하기 위한 정보를 명시하는 값이다.
상당히 많은 값들이 있으며, 1번 구조체 값고 마찬가지로 구조체의 헤더값, 헤더의 크기, flag값들이 존재한다.
uint32 LinkInfoSize
구조체 크기
uint32 LinkInfoHeaderSize
구조체 헤더의 크기
struct LinkInfoFlags sLinkInfoFlags
uint32 VolumelDOffset
volume offset (필드 시작점 )
uint32 LocalBasePathOffset
마찬가지로 해당 필드의 시작
...
string CommonPathSuffix[1]
localbasepath필드에 문자열을 합친 대상 링크나 해당 링크에 대한 아이템에 대한 경로를 구성하는데 사용되는 CP(code page)에 의해 정의 NULL로 끝나는 문자열이다.
세부 파일 목록은 다음과 같다.
4. STRING_DATA
세부 파일 목록은 다음과 같다.
<struct StringData Relative_path >
uint16 CountCharacters
unsigned int 16bit 형, 문자열의 개수 값 저장.
wchar_t String[9]
16bit 유니코드 값 저장 - wchar(wide character)
<struct StringData WORKING DIR>
uint16 CountCharacters
unsigned int 16bit 형, 문자열의 개수 값 저장.
wchar_t String[20]
16bit 유니코드 값 저장 - wchar(wide character)
5. EXTRA_DATA
세부 파일 목록은 다음과 같다.
TrackerDataBlocksTrackerDataBlock
PropertyStoreDataBlock sPropertyStoreDataBlock
uint32 TerminalBlock
TrackerDataBlocks TrackerDataBlock : 구조체 내부의 구조체 필드 값을 나타내는 정보, 해당 구조체에 포함된 다른 데이터 블록에 대한 정보를 나타내는 것으로 추측. (unit32의 signature, length,version에 대한 정보와 더불어 GUID의 정보가 포함됨. - GUID fileDroid, volumnDroid... 고정 상수값)
PropertyStoreDataBlocks PropertyStoreDataBlock : TrackerDataBlocks TrackerDataBlock 와 마찬가지로 unit32의 signature, length,version에 대한 정보와 더불어 GUID의 정보가 포함되어 있음.
uint32 TerminalBlock: 가장 마지막 값으로 0으로 고정된 값. 크기는 4로 고정. unsigned int 32bit 타입 Terminal Block 변수를 가리킴. PropertyStoreDataBlocks PropertyStoreDataBlock에서도 하위 항목에 포함된 값인데, 마지막에 다시 명시해준 데에는끝을 다시 강조하기 위해서다. 여기에는 무조건 terminal조건인 0으로 나타낸다.
※참고 문헌 :
1. https://aawjej.tistory.com/197 (artifact에 관한 내용)
2. https://liz09045.tistory.com/33 (디지털 증거)
3. https://c0wb3ll.tistory.com/entry/LNK-File-Structure ,https://whitesnake1004.tistory.com/591(LNK 파일의 구조)
4. https://binaryforay.blogspot.com/2016/02/introducing-lecmd.html (분석 툴)
5. https://teamsign.tistory.com/6(분석 툴)
'Best of the Best 12th' 카테고리의 다른 글
펌웨어 공유기(iptime) 해킹 (0) | 2023.07.15 |
---|---|
정보보안 전문가 관점에서 Generative AI (-chat gpt)의 활용방안 (0) | 2023.07.09 |
BOB 회고록, Best of the Best in Improvement (0) | 2023.07.04 |
[Algorithm] Bubble sort (1) | 2023.07.03 |
보안컨설턴트 (0) | 2023.07.02 |
댓글