해당 글은 닉 호프만(Nick Hoffman)님께서 2014년 12월 03일에 작성한 글을 번역함.
링크 :
https://securitykitten.github.io/2014/12/03/vm-checking-and-detecting.html
2014년에 공개된 안티 VM 기능이 있는 악성코드를 조사하여 해당 VM 체크 및 감지하는 루틴만 알아보고자 함.
첨부 파일에 악성코드 샘플을 첨부함.
파일명 : ozohrr.exe
종류 : 백도어
증상 :
파일 타입 : Win32 EXE
파일 사이즈 : 63.00 KB (64,512 bytes)
MD5 : de1af0e97e94859d372be7fcf3a5daa5
SHA1 : 6b0c9722abf07f2ebdeb5363021593ba9bde7a17
SHA-256 :
a924ac85724c695f2ae8f06f7a52bb34d5a518894e01cab39566793b6cfd6003
VirusTotal 결과값 :
샘플 다운로드 링크(암호 : koromoon1004) :
https://drive.google.com/file/d/17MpqBMtLfIuwCU_ih9wUJUBKz9mise3G/view?usp=sharing
( 01 ) Sleep 확인
GetTickCount() 함수를 호출한 다음 500 밀리초 동안 Sleep 후 다시 GetTickCount() 함수를 호출함.
만약 두 카운트 차이가 450 밀리초보다 클 경우 테스트를 통과함.
이 검사는 RETN 4 또는 Sleep() 함수 후킹으로 부터 패치를 방지할 수 있음.
( 02 ) 디버거 확인
IsDebuggerPresent() 함수를 사용하여 디버거를 확인함.
IsDebuggerPresent() 함수는 파라미터는 필요 없고 현재 프로세스가 유저 모드 디버거에 의해 호출된 것이면 0 이 아닌 값을 반환함.
다음으로 CheckRemoteDebuggerPresent() 함수를 사용하여 디버거를 확인함.
CheckRemoteDebuggerPresent() 함수는 인자로 주어진 해당 프로세스가 디버깅되고 있는지를 결정하는 함수임.
함수의 첫 번째 인자는 확인할 프로세스의 핸들, 두 번째 인자는 결과값을 저장할 버퍼임.
( 03 ) 사용자 이름 확인
GetUserNameA() 함수를 호출하여 사용자 이름을 확인하는 작업을 수행함.
그런 다음 toupper() 함수를 대문자로 변환함.
대문자로 변환 후 결과 문자열을 가지고 다음과 같은 이름에 대해서 확인함.
MALTEST
TEQUILABOOMBOOM
SANDBOX
VIRUS
MALWARE
( 04 ) 파일 경로 확인
위 사용자 이름을 확인하는 작업과 비슷한 루틴임.
여기서는 파일 경로를 확인하는 GetModuleFileNameA() 함수를 호출함.
그런 다음 toupper() 함수를 대문자로 변환함.
대문자로 변환 후 결과 문자열을 가지고 다음과 같은 이름에 대해서 확인함.
\SAMPLE
\VIRUS
SANDBOX
( 05 ) Wine 실행 확인
KERNEL32.DLL 에서 서비스되는 wine_get_unix_file_name 이 포함되어 있는지 여부를 검사함.
( 06 ) 가상화 프로그램 DLL 로딩 확인
GetModuleHandleA() 함수를 호출하여 가상화 프로그램 DLL 목록들을 검사함.
sbiedll.dll (Sandboxie)
dbghelp.dll (vmware)
api_log.dll (SunBelt SandBox)
dir_watch.dll (SunBelt SandBox)
pstorec.dll (SunBelt Sandbox)
vmcheck.dll (Virtual PC)
wpespy.dll (WPE Pro)
( 07 ) VMware 확인
레지스트리 키 "HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0" 에서 식별자 값과 VMware 데이터를 찾음.
또한, 레지스트리 키 "SOFTWARE\VMware, Inc.\VMware Tools" 에서 VMware Tools 존재 여부를 확인함.
( 08 ) VirtualBox 확인
레지스트리 키 "HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0" 에서 식별자 값과 VBOX 데이터를 찾음.
그리고 레지스트리 키 "HARDWARE\Description\System" 에서 SystemBiosVersion 값과 VBOX 데이터를 찾음.
"SOFTWARE\Oracle\VirtualBox Guest Additions" 항목을 통해 GuestAdditions 값을 체크함.
VirtualBox 비디오 드라이버와 관련된 레지스트리 키 "HARDWARE\Description\System" 에서 VideoBiosVersion 값과 VIRTUALBOX 데이터를 찾음.
( 09 ) QEMU 확인
레지스트리 키 "HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0" 에서 식별자 값과 QEMU 데이터를 찾음.
그리고 레지스트리 키 "HARDWARE\Description\System" 에서 SystemBiosVersion 값과 QEMU 데이터를 찾음.
( 10 ) 드라이브 크기 확인
최종적으로 드라이브 크기를 확인함.
CreateFileA() 함수를 이용하여 PhysicalDrive0 에 대한 핸들을 얻음.
그런 다음 반환된 핸들을 사용하여 DeviceIoControl() 함수의 매개변수 dwIoControlCode 값 7405C 를 전달함.
(IOCTL_DISK_GET_LENGTH_INFO)
위 함수의 출력을 받아 기가바이트 크기로 표시된 드라이브 크기를 1073741824 로 분할함.
하드 드라이브의 사이즈가 10 보다 작을 경우 악성코드 실행을 중지함.
댓글 없음:
댓글 쓰기