Digital Forensics/Windows Registry

Shellbags 생성/갱신 기준

geunyeong 2020. 3. 25. 19:36

#

Shellbags 레지스트리를 설명하는 글들은 너무나도 많다. 하지만 레지스트리가 언제 생성되고 갱신되는지를 설명하는 글은 없는 듯하여 조사해봤다.

 

맨 밑에 요약 정리가 있다. 귀찮으면 스크롤바 쭉 내리면 된다.

 

 

 

#환경

Windows 10 Pro x64 1909 버전을 가상머신에 설치해 분석했다.

 

 

 

#탐색기 - 폴더 열람 후 정상종료

가장먼저 explorer.exe를 사용하여 폴더를 탐색하는 경우를 조사했다. 

 

초기 Shellbags 레지스트리 모습이다. 설치 직후인데 BagMRU 키 밑에 0, 1, 1/0, 총 3개 키가 처음부터 존재했다.

 

탐색기 주소창을 이용해 %UserProfile%(사용자 홈폴더) 경로에 직접 접근한 후 레지스트리를 확인해봤다. 아무런 변화가 없다.

 

탐색기를 정상 종료한 후 레지스트리를 확인해보면 BagMRU 키 밑에 2라는 Data와 Key가 추가된 걸 볼 수 있다. 덤으로 MRUListEx Data의 Value를 보면 처음 4바이트에 0x00000002가 추가되었다.

 

 

 

#탐색기 - 다른 폴더로 이동

이번엔 다른 폴더로 이동했을 때 생성/갱신 여부를 확인해봤다. 탐색기를 열고 %UserProfile%에 직접 접근한 후 다음 폴더들을 차례로 방문했다.

 

1. %UserProfile%\Pictures (사용자 홈폴더\사진)

2. %UserProfile%\Pictures\Saved Pictures (사용자 홈폴더\사진\저장된 사진)

 

캡쳐를 제대로 못 했는데, '저장된 사진' 폴더에 txt 파일을 만든 후 탐색기를 종료하지 않고 레지스트리를 확인해보면 BagMRU\2 키 밑에 새로운 키가 만들어졌음을 볼 수 있다. 2 옆에 '>' 모양의 아이콘이 생긴 걸 보면 폴더를 이동하기만 해도 Shellbags 레지스트리가 생성/갱신 됨을 알 수 있다. (위에선 2 밑에 하위키가 없었다.)

 

나중에 확인해본 사실인데 사진 폴더로 종료하지 않고 이동만 해도 BagMRU\2 밑에 0 하위키가 만들어졌다.

 

탐색기를 정상 종료하고 레지스트리를 다시 확인했다. BagMRU\2\0에 들어있는 0 Data의 Value를 확인해보면 Saved Pictures라는 문자열이 보인다. BagMRU\2\0\0은 '저장된 사진' 폴더라는 걸 알 수 있다.

 

UsrClass.dat 파일을 추출해 REGA로 열어보면 Shellbags 레지스트리에 Saved Pictures 폴더에 접근한 기록이 남아있다. Reg Time을 보면 해당 폴더에 접근했던 시간이 UTC+0로 표시되고 있다. KST(UTC+9)로 변환하면 17:35로, 위 캡쳐화면에서 보여주는 시간과 일치한다.

 

 

 

#API - GetOpenFileName

이번엔 파일 선택 다이얼로그를 제공해주는 GetOpenFileName API를 사용한 경우를 조사해봤다.

 

이번에도 초기 레지스트리는 위와 같다.

 

#include <stdio.h>
#include <Windows.h>

const wchar_t* BASEDIR = TEXT("C:\\Users\\geunyeong");

int main()
{
	OPENFILENAME OpenFileName = { 0, };
	wchar_t FilePath[MAX_PATH] = { 0, };
	
	OpenFileName.lStructSize = sizeof(OPENFILENAME);
	OpenFileName.hwndOwner = NULL;
	OpenFileName.lpstrFilter = NULL;
	OpenFileName.lpstrFile = FilePath;
	OpenFileName.nMaxFile = MAX_PATH;
	OpenFileName.lpstrInitialDir = BASEDIR;

	if (GetOpenFileName(&OpenFileName))
	{
		wprintf(TEXT("Selected file is %s\n"), OpenFileName.lpstrFile);
	}

	return 0;
}

간단하게 GetOpenFileName만 호출하고 끝나는 프로그램을 작성해서 64bit release로 컴파일 한 후 가상머신으로 옮겼다.

 

%UserProfile%\Pictures\Saved Pictures 폴더를 열람한 후 파일 선택 다이얼로그를 끄지 않고 레지스트리를 확인해봤다. BagMRU\2\0 키 0 Data의 Value를 확인하면 Saved Pictures라는 문자열을 볼 수 있다. 폴더를 열람하는 순간 레지스트리가 생성/갱신된다.

 

 

 

# HTML - input type file

#API - GetOpenFileName에서 봤듯이 다이얼로그 형태로 폴더를 열람하면 레지스트리가 생성/갱신된다. 때문에 웹에서 파일을 업/다운로드 할 때도 파일 선택 다이얼로그를 사용할테니 레지스트리에 변화가 있을 거라 생각했다.

 

초기 레지스트리 내용은 그림과 같다.

 

<html>
<head></head>
<body>
	<input type="file"></input>
</body>
</html>

파일 선택 다이얼로그를 호출하기 위한 HTML 코드는 위와 같다.

 

엣지 브라우저로 html 파일을 열고 파일 선택 다이얼로그를 호출한 다음 '저장된 사진' 폴더에 접근했다. #API - GetOpenFileName에서와 마찬가지로 창을 닫지 않고 레지스트리를 확인하면 Saved Pictures에 대한 Shellbags 레지스트리가 생성된 걸 볼 수 있다.

 

 

 

#API - FindFirstFile, FindNextFile

그렇다면 폴더 속 파일이나 폴더 목록을 확인하는 FindFirstFile, FindNextFile API만을 사용하면 어떨까.

 

초기 레지스트리 내용이다.

 

#include <Windows.h>
#include <stdio.h>

const wchar_t* EXPLORED_FOLDER = TEXT("C:\\Users\\geunyeong\\*");

int main()
{
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;

	hFind = FindFirstFile(EXPLORED_FOLDER, &FindFileData);

	if (hFind == INVALID_HANDLE_VALUE)
	{
		puts("error occurred");
	}
	else
	{
		wprintf(TEXT("%s\n"), EXPLORED_FOLDER);
		do 
		{
			wprintf(TEXT("\t%s\n"), FindFileData.cFileName);
		} while (FindNextFile(hFind, &FindFileData));

		FindClose(hFind);
	}

	return 0;
}

%UserProfile% 폴더에 들어있는 파일과 폴더 목록을 보여주는 간단한 코드다.

 

cmd로 해당 프로그램을 실행시킨 후 레지스트리를 확인해봤다. 아무런 변화가 없었다. cmd를 종료하고 나서도 레지스트리엔 아무런 변화가 없었다.

 

 

 

#정리

Shellbags 레지스트리는 파일 탐색 다이얼로그(대화 상자)를 제공하는 "탐색기 프로그램(explorer.exe)"이나 "GetOpenFileName API"를 통해 폴더를 열람/이동 할 때 마다 실시간으로 생성/갱신 된다는 걸 알 수 있었다. 다이얼로그로 접근하지 않는 경우(cmd에서 cd 명령, Find*File API)에는 레지스트리 변화가 없었다.

 

때문에 악성코드에 의한 파일 유출 시에는 큰 의미가 없다고 생각된다. 반대로 사용자가 직접 악성행위를 한 경우에는 (다이얼로그를 사용했다는 가정 하에) 아주 중요한 의미를 가진다. 파일 선택 다이얼로그를 사용해도 Shellbags 레지스트리를 변경하므로 웹을 통한 파일 유출 시에도 참고자료로 사용할 수 있을 것이다.

 

#API - GetOpenFileName에서 만들었던 프로그램을 Process Monitor로 캡쳐한 사진이다. 다수의 RegCreateKey API를 호출하는데 생성/갱신하는 키의 경로가 Shellbags 레지스트리 경로다. 파일 선택 다이얼로그 코드에 Shellbags 레지스트리를 생성/갱신하는 코드가 있다고 추정할 수 있으며, 이 때문에 Find API로는 레지스트리가 갱신되지 않는 것이다.