이 멀티파트 시리즈의 첫 번째 글에서는 Elastic Security Labs 팀의 멀웨어 연구원들이 REMCOS 위협에 대해 간단히 소개하고, 구성 로딩부터 감염된 컴퓨터 웹 브라우저 정리까지 실행 흐름의 전반부를 자세히 설명합니다.
서문
Elastic Security Labs는 영향력이 큰 위협에 대한 조사를 계속하고 있으며, REMCOS 버전 4.9.3의 내부 복잡성에 초점을 맞추고 있습니다. Pro (11월 26, 2023).
Breaking-Security에서 개발한 REMCOS는 레드팀 구성 도구로 시작했지만 이후 거의 모든 분야를 대상으로 하는 모든 종류의 위협에 채택된 소프트웨어입니다.
1월 중순에 분석을 수행했을 때, 이 멀웨어는 ANY.RUN에서 가장 많이 보고된 멀웨어 제품군이었습니다. 또한, 최근 3월 4.9.4 버전 출시 발표 (,)에서 알 수 있듯이 여전히 활발히 개발 중입니다.92024
분석에 사용된 모든 샘플은 동일한 REMCOS 4.9.3에서 파생되었습니다. Pro x86 빌드. 이 소프트웨어는 문자열 및 바이트 관련 연산에 std::string 클래스를 집중적으로 사용하여 C++로 코딩되었습니다.
REMCOS에는 회피 기법, 권한 에스컬레이션, 프로세스 주입, 녹화 기능 등 다양한 기능이 포함되어 있습니다.
이 글 시리즈에서는 다음에 대한 광범위한 분석을 제공합니다:
- 실행 및 기능
- Elastic의 ES|QL 쿼리를 사용한 탐색 및 헌팅 전략
- 약 80개의% 구성 필드 복구
- 약 90개의% C2 명령 복구
- 각 IDA Pro 스크린샷 아래의 샘플 가상 주소
- 그리고 더!
질문이나 피드백이 있으시면 소셜 미디어 @elasticseclabs 또는 Elastic 커뮤니티 Slack에서 언제든지 문의해 주세요.
구성 로드하기
REMCOS 구성은 SETTINGS 라는 리소스 내의 암호화된 블롭에 저장됩니다. 이 이름은 여러 버전의 REMCOS에서 일관되게 나타납니다.
멀웨어는 리소스 섹션에서 암호화된 구성 블롭을 로드하는 것으로 시작합니다.
암호화된 구성을 로드하기 위해 다음 Python 스크립트와 Lief 모듈을 사용합니다.
import lief
def read_encrypted_configuration(path: pathlib.Path) -> bytes | None:
if not (pe := lief.parse(path)):
return None
for first_level_child in pe.resources.childs:
if first_level_child.id != 10:
continue
for second_level_child in first_level_child.childs:
if second_level_child.name == "SETTINGS":
return bytes(second_level_child.childs[0].content)
4.9.3 버전은 포티넷 연구진이 이전에 설명한 것과 동일한 구조와 암호 해독 체계를 유지하고 있음을 확인할 수 있습니다:
암호 해독 키와 암호화된 데이터 블롭이 포함된 구조를 '암호화된 구성'이라고 하며, 다음과 같이 표시됩니다:
struct ctf::EncryptedConfiguration
{
uint8_t key_size;
uint8_t key[key_size];
uint8_t data
};
다음 스크린샷에서 볼 수 있듯이 구성은 여전히 RC4 알고리즘을 사용하여 해독됩니다.
구성을 해독하기 위해 다음 알고리즘을 사용합니다.
def decrypt_encrypted_configuration(
encrypted_configuration: bytes,
) -> tuple[bytes, bytes]:
key_size = int.from_bytes(encrypted_configuration[:1], "little")
key = encrypted_configuration[1 : 1 + key_size]
return key, ARC4.ARC4Cipher(key).decrypt(encrypted_configuration[key_size + 1 :])
이 구성은 \x7c\x1f\x1e\x1e\x7c 문자열을 구분 기호로 사용하여 g_configuration_vector 이라고 부르는 글로벌 벡터를 분할하여 초기화하는 데 사용됩니다.
이 시리즈의 뒷부분에서 구성에 대한 자세한 설명을 제공합니다.
UAC 바이패스
구성에서 enable_uac_bypass_flag (색인 0x2e)가 활성화되면 REMCOS는 알려진 COM 기반 기술을 사용하여 UAC 우회를 시도합니다.
사전에 REMCOS는 탐지를 피하기 위해 프로세스를 가장합니다.
REMCOS는 이미지 경로와 명령줄을 explorer.exe 문자열로 바꾸고 나중에 사용할 수 있도록 원본 정보를 전역 변수에 저장하여 현재 프로세스의 PEB 구조를 수정합니다.
잘 알려진 기법은 CoGetObject API를 악용하여 Elevation:Administrator!new: 모니커를 CMSTPLUA CLSID 및 ICMLuaUtil IID와 함께 전달하여 상승된 COM 인터페이스를 인스턴스화하는 것입니다. 그런 다음 REMCOS는 인터페이스의 ShellExec() 메서드를 사용하여 관리자 권한으로 새 프로세스를 시작하고 종료합니다.
이 기술은 이전에 2023년에 작성된 Elastic Security Labs 문서에 설명되어 있습니다: Windows UAC 우회 탐색: 기법 및 탐지 전략.
아래는 Elastic Defend 에이전트를 사용해 이 익스플로잇을 탐지한 최근 스크린샷입니다.
UAC 비활성화하기
구성(색인 0x27)에서 disable_uac_flag 이 활성화된 경우, REMCOS는 reg.exe Windows 바이너리를 사용하여 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\SystemEnableLUA 값을 0 으로 설정하여 레지스트리에서 UAC를 비활성화합니다."
설치 및 지속성
구성에서 enable_install_flag (색인 0x3)가 활성화되면 REMCOS가 호스트 컴퓨터에 자동으로 설치됩니다.
설치 경로는 다음 구성 값을 사용하여 구성됩니다:
install_parent_directory(색인0x9)install_directory(0x30)install_filename(0xA)
악성 코드 바이너리가 {install_parent_directory}/{install_directory}/{install_filename} 으로 복사됩니다. 이 예에서는 %ProgramData%\Remcos\remcos.exe 입니다.
구성에서 enable_persistence_directory_and_binary_hiding_flag (색인 0xC)를 활성화하면 설치 폴더와 악성코드 바이너리는 슈퍼 숨김(사용자가 숨김 파일 또는 폴더 표시를 활성화하더라도 Windows에서 시스템 속성으로 파일을 보호하기 위해 파일을 숨긴 상태로 유지) 및 읽기 전용, 숨김 및 시스템 속성을 적용하여 읽기 전용으로 설정됩니다.
설치 후 REMCOS는 구성에서 다음 플래그 중 활성화된 플래그에 따라 레지스트리에 지속성을 설정합니다:
enable_hkcu_run_persistence_flag(색인0x4)HKCU\Software\Microsoft\Windows\CurrentVersion\Run\enable_hklm_run_persistence_flag(색인0x5)HKLM\Software\Microsoft\Windows\CurrentVersion\Run\enable_hklm_policies_explorer_run_flag(색인0x8)HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\
그런 다음 ShellExecuteW 을 사용하여 설치 폴더에서 멀웨어를 다시 실행한 다음 초기 프로세스를 종료합니다.
프로세스 인젝션
구성에서 enable_process_injection_flag (색인 0xD)를 활성화하면 REMCOS는 탐지를 피하기 위해 지정된 프로세스 또는 하드코딩된 목록에서 선택한 Windows 프로세스에 자신을 삽입합니다.
enable_process_injection_flag 은 부울이거나 대상 프로세스의 이름일 수 있습니다. 참(1)으로 설정하면 주입된 프로세스는 다음 옵션 중에서 "최선의 노력" 방식으로 선택됩니다:
iexplorer.exeieinstal.exeielowutil.exe
참고: REMCOS에서 사용할 수 있는 주입 방법은 하나뿐이며, 프로세스 주입에 대해 이야기할 때는 여기에 설명된 방법을 구체적으로 언급합니다.
REMCOS는 프로세스 주입을 위해 고전적인 ZwMapViewOfSection + SetThreadContext + ResumeThread 기법을 사용합니다. 여기에는 공유 메모리를 통해 주입된 바이너리에 자신을 복사하고 ZwMapViewOfSection 을 사용하여 매핑한 다음 SetThreadContext 및 ResumeThread 메서드를 사용하여 실행 흐름을 REMCOS 진입점으로 탈취하는 작업이 포함됩니다.
CreateProcessW API를 사용하여 일시 중단 모드에서 대상 프로세스를 생성하고 GetThreadContext API를 사용하여 해당 스레드 컨텍스트를 검색하는 것으로 시작됩니다.
그런 다음 ZwCreateSection API를 사용하여 공유 메모리를 생성하고 ZwMapViewOfSection API를 사용하여 원격 프로세스에 대한 핸들과 함께 대상 프로세스에 매핑합니다.
다음으로 바이너리는 헤더와 섹션을 공유 메모리에 복사하여 원격 프로세스에 로드됩니다.
필요한 경우 재배치가 적용됩니다. 그런 다음 WriteProcessMemory API를 사용하여 PEB ImageBaseAddress 를 수정합니다. 그 후 스레드 컨텍스트가 REMCOS 진입 지점을 가리키는 새 진입 지점으로 설정되고 프로세스 실행이 재개됩니다.
아래는 에이전트가 이 프로세스 주입 기법을 탐지한 것입니다:
로깅 모드 설정
REMCOS에는 구성의 logging_mode (색인 0x28) 필드에서 선택할 수 있는 세 가지 로깅 모드 값이 있습니다:
- 0: 로깅 없음
- 1: 트레이 아이콘에서 최소화 시작
- 2: 콘솔 로깅
이 필드를 2 으로 설정하면 프로세스 주입이 활성화된 경우에도 콘솔이 활성화되고 추가 정보가 노출됩니다.
브라우저 정리
enable_browser_cleaning_on_startup_flag (색인 0x2B)가 활성화되면 REMCOS는 호스트에 설치된 웹 브라우저에서 쿠키와 로그인 정보를 삭제합니다.
공식 문서에 따르면 이 기능의 목표는 비밀번호 도용에 대한 시스템 보안을 강화하는 것입니다:
현재 지원되는 브라우저는 인터넷 익스플로러, 파이어폭스, 크롬입니다.
정리 프로세스에는 FindFirstFileA, FindNextFileA, DeleteFileA API를 사용하여 브라우저의 알려진 디렉토리 경로에서 쿠키와 로그인 파일을 삭제하는 작업이 포함됩니다:
작업이 완료되면 REMCOS는 콘솔에 메시지를 인쇄합니다.
구성에서 두 가지 관련 필드를 언급할 가치가 있습니다:
enable_browser_cleaning_only_for_the_first_run_flag(색인0x2C)browser_cleaning_sleep_time_in_minutes(색인0x2D)
browser_cleaning_sleep_time_in_minutes 구성 값은 작업을 수행하기 전에 REMCOS가 절전 모드로 전환되는 시간을 결정합니다.
enable_browser_cleaning_only_for_the_first_run_flag 을 활성화하면 REMCOS를 처음 실행할 때만 청소가 수행됩니다. 그 후 HKCU/SOFTWARE/{mutex}/FR 레지스트리 값이 설정됩니다.
이후 실행 시 값이 존재하고 레지스트리에 설정되어 있으면 함수가 직접 반환합니다.
이것으로 첫 번째 글의 끝입니다. 두 번째 파트에서는 워치독부터 C2와의 첫 번째 통신까지 REMCOS의 실행 흐름 후반부를 다룹니다.
