Steam 악성코드 분석: Beyond The Dark의 UnityPlayer.dll DLL Side Loading

Steam 악성코드 분석: Beyond The Dark의 UnityPlayer.dll DLL Side Loading

이 글의 영문 버전 링크

게임 플랫폼으로 유명한 스팀(Steam)은 유료뿐만 아니라 무료 게임도 서비스한다. 만약 스팀의 보안 시스템의 탐지를 피해 악성 파일을 무료 게임으로 업로드만 할 수 있다면 수많은 게이머들을 감염시킬 수 있는 공격 수단으로 활용될 수 있을 것이다. 이런 대담한 시도는 실제로 번번히 이루어져 종종 스팀 게임 라이브러리에 악성 파일이 포함됐다는 소식을 들을 수 있다.

이번에는 최근 무료 게임으로 업로드된 Beyond The Dark 게임에 포함된 악성 파일에 대한 분석 글을 작성했다. 현재 시점에서 게임 페이지는 남아있으나, 이미 스팀 측에서 악성 여부를 인지해 다운로드가 불가능하게 만들었다.

Beyond The Dark 스팀 페이지

1. File Info

다음은 Beyond The Dark 게임에 포함된 악성 파일에 대한 정보다. 절대 Host 환경에서 실행하지 않도록 주의해야 한다.

UnityPlayer.dll

  • MD5 : 4A7B088EC76C2513432901BC9616D675
  • SHA256 : B37CEA499EFAD35FF5AF7E73F34F17840C2D14DD6CD21E3345D22A39140B4D45
  • FileSize : 7,819,776 바이트
  • FileType : DLL64(.NET)
  • 통신 서버 : hxxps[:]//435123332155.com/api.php

WindowsCodecs.dll

  • MD5 : DD6F25C9E750D96E26F4717F63A416F6
  • SHA256 : FC4317EBABFBCA8A9DBD307F16EEEE553E659FB9F931BFF4D858871D6215540B
  • FileSize : 13,268,480 바이트
  • FileType : DLL64

RunPE.dll

  • MD5 : 0C42EC5B8C0C53DC170B944754D38E5C
  • SHA256 : 57BE85F23890FC8D2E3AC6B6123FB1D5B79777F7630C9550A18CB6C14A66288C
  • FileSize : 54,272 바이트
  • FileType : DLL64
  • 비고 : Fileless.

mirar.exe

  • MD5 : ACBBD4AF7F93FEDD4DB990EAEC94CD1F
  • SHA256 : 131B2C66BC614EDE57D0645C4CB2D407EB4F2EDBB394C1FB28A5E0BAEB97629D
  • FileSize : 11,545,600 바이트
  • FileType : EXE64(.NET Reactor)
  • 통신 서버 : 435123332155.com
  • 비고 : 정상 RegAsm.exe 에 인젝션됨. Fileless.

2. 악성 행위 분석

2.1 Beyond The Dark.exe

공격은 사용자가 Beyond The Dark.exe 파일을 실행하면서 시작된다. 이 실행 파일을 실행하면 Crash 가 발생해 정상적인 게임이 불가능하지만 UnityPlayer.dll 파일을 로딩하는 DLL 의존성을 가진다.

공격자는 Unity 게임 엔진 파일로 위장한 악성 DLL UnityPlayer.dll 을 실행 파일과 같은 경로에 둠으로써 DLL Side Loading 을 유도한다.

악성 DLL UnityPlayer.dll 을 로딩하는 Beyond The Dark.exe 파일

2.2 UnityPlayer.dll

로딩된 UnityPlayer.dll 은 .NET 언어로 빌드된 64bit DLL 파일이다. dnSpy 로 분석한 결과, DLL 은 실행 시 호스트 이름, MAC 정보를 수집하고 두 정보를 이용해 client id를 생성한다.

시스템 정보 수집 코드

또한 Chromium, Firefox, Opera 와 같은 주요 브라우저의 설치 경로를 탐색하며 Extension 목록을 수집한다.

브라우저 확장 프로그램 정보 수집 코드
각 브라우저 확장 프로그램 저장 경로 코드

간단한 정보 수집 후 공격자 서버와 통신을 시작한다. 서버와 주고 받는 패킷 Action 은 다음과 같다.

Action 기능
register 호스트 이름, MAC 을 송신해 클라이언트 등록
client_message 브라우저 Extension 정보 송신
heartbeat 클라이언트, 서버가 살아있음을 전달
ack 서버 패킷에 응답

통신에 지정된 X-API-Key 헤더 값이 필요하다.

POST 패킷 생성 코드

최초 통신 시 호스트 이름과 MAC 을 포함한 register 패킷을 송신해 클라이언트를 등록한다.

클라이언트 등록 코드

클라이언트 등록 후 앞서 수집한 브라우저 Extension 정보를 공격자 서버로 송신한다.

클라이언트 정보 송신 코드

공격자 서버로부터 channel 값이 1인 메시지를 전달받으면 ZIP 파일을 다운로드한다.

ZIP 다운로드 코드

다운로드한 ZIP 파일을 압축 해제 후, 가장 먼저 발견되는 exe 파일을 실행한다.

ZIP 압축 해제 후 exe 파일 실행 코드

이후의 악성 동작은 다운로드된 exe 파일을 분석해야 하지만 이미 서버가 사망해 통신이 불가능한 상태다. 아마 핵심 악성 행위는 다운로드되는 exe 파일에 있을 것으로 추정된다.

2.3 WindowsCodecs.dll

Any.run 의 분석 보고서 중 공격 서버와 통신한 보고서가 있어 이를 참고하여 분석을 이어나갔다. 통신에 성공한 Beyond The Dark.exepdate_20260518_024820.zip 파일을 다운로드 후, 압축을 해제해 WinRAR.exe(53cf9bacc49c034e9e947d75ffab9224), WindowsCodecs.dll(dd6f25c9e750d96e26f4717f63a416f6) 파일을 드랍하고 WinRAR.exe 을 실행했다.

any.run 분석 내용

WinRAR.exe 자체는 정상적인 파일이지만, 해당 파일에 의해 DLL Side Loading 되는 WindowsCodecs.dll 은 악성 파일이다.

DLL Side Loading 으로 로딩되는 WindowsCodecs.dll 파일

악성 WindowsCodecs.dll 은 파일 내 암호화된 데이터를 복호화, RunPE DLL을 메모리에 로딩하고 해당 파일의 export 함수 중 하나인 GetGet 함수를 실행한다.

RunPE DLL 파일의 GetGet Export 함수

2.4 RunPE DLL

RunPE DLL 은 정상 시스템 실행 파일 RegAsm.exe 를 Suspend 상태로 실행, 악성 코드를 인젝션 후 Resume시킨다. 이 과정에서 NtUnmapViewOfSection, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtGetContextThread, NtSetContextThread, NtResumeThread, NtDelayExecution, NtClose 와 같이 Process Hollowing에 사용되는 API를 System Call 을 직접 이용하는 방식으로 호출해 분석가, 샌드박스의 탐지를 회피한다.

Direct Sysem Call 코드

페이로드 PE 파일을 RegAsm.exe 에 인젝션하면 스레드를 Resume 해 악성 행위를 시작한다.

2.5 mirar.exe

RegAsm.exe 에 인젝션된 멀웨어는 mirar.exe 라는 이름의 파일이었다. .NET Reactor 프로텍터로 난독화되어NETReactorSlayer 로 난독화 코드를 해제하고 분석을 진행했다.

난독화를 해제했음에도 불필요한 코드가 많아 분석이 쉽지 않다. EntryPoint 는 mirar.region1 폼을 실행 후, 다수의 숨김, 더미 WinForms 을 생성, 닫는 행위를 반복한 후 최종적으로 mirar.GForm2.GForm2_Load 를 실행한다.

mirar.GForm2.GForm2_Load 코드

mirar.exe 은 앞서 보았던 공격자 서버 435123332155.com 과 통신하며 백도어 역할을 수행한다. 공격자 서버 도메인의 주소를 찾기 위해 CloudFlare 의 DoH 기능을 이용한다.

CloudFlare 의 DoH 기능을 이용하는 코드

/llllmaw/api.php 주소에 접속해 공격자 서버로부터 action 명령을 전달받고 수행한다. 통신 데이터는 무작위로 생성한 IV 와 고정된 Key 값 MnBvCxZa0987654321QwErTy!@#$%^&* 을 사용해 AES 암호화 후, Base64 인코딩한다.

AES 암호화 + Base64 인코딩 코드

/llllmaw/api.php 와 주고받은 action 기능은 다음과 같다.

Action 기능
ping "ping", "pong" 데이터를 주고 받으며 공격자 서버와 연결이 정상임을 확인.
heartbeat 수신한 JSON 데이터에 "restart" 가 있으면 공격자 서버와 다시 통신 수립. "update" 가 있으면 지정된 URL 에서 ZIP 다운로드, 첫 번째 exe 파일 실행.
report 서버 명령 실행 결과 반환.

가장 주목할만한 부분은 heartbeat action에 "update" 가 포함된 경우다. 앞서 보았던 UnityPlayer.dll 과 마찬가지로 지정된 경로에 ZIP 파일을 다운로드, 압축 해제 후 첫 번째로 발견되는 exe 파일을 실행한다.

ZIP 파일 다운로드, exe 파일 실행 코드