이전에 기록되지 않은 OXLOADER라는 이름의 Windows 로더가 악성 Google 광고를 통해 CASTLESTEALER 정보 탈취 악성코드를 배포하고 있으며, 정적 검색 엔진 및 샌드박스 실행에서 탐지율이 낮습니다. 로더는 여러 난독화 계층(제어 흐름 평탄화, 불투명한 술어, 혼합 부울-산술)과 자체 수정 복호화 스텁을 사용하고 Windows .reloc 섹션을 악용하여 셸코드를 배치합니다.
Elastic Security Labs는 자사 고객 중 한 곳을 대상으로 하는 활발한 공격 캠페인에서 OXLOADER를 발견했습니다. CIS 지역 및 러시아어 제외 설정으로 미루어 보아 금전적 이득을 노리는 러시아어 사용 공격자가 활동하고 있는 것으로 추정됩니다. 우리는 이 가족에 대한 이전의 공개 보도를 찾지 못했습니다.
핵심 사항
- Elastic Security Labs에서 새로운 로더(OXLOADER)를 발견했습니다.
- OXLOADER는 악성 Google 광고를 통해 CASTLESTEALER를 배포하는 캠페인에서 발견되었습니다.
- CIS 지역 제외 및 러시아어 검사 결과는 러시아어를 사용하는 금전적 동기를 가진 위협 행위자임을 시사합니다.
- 정지 엔진 및 샌드박스 폭발 실험 전반에 걸쳐 낮은 탐지율
- Elastic Defend는 고급 방지 기능을 사용하여 공격 체인 전체를 차단합니다.
악성 광고가 어떻게 OXLOADER 피해자들에게 전달되었는지
OXLOADER는 Node.js를 사칭하는 악성 Google 광고를 통해 배포됩니다. 피해자는 중간 도메인을 통해 Storj에서 호스팅되는 배치 스크립트로 리디렉션되며, 이 스크립트는 OXLOADER를 다운로드하고 실행합니다.
사용자가 lts version of node.js 을 검색하고 node-js[.]prentiva99[.]info 로 연결되는 스폰서 결과를 클릭했을 때 감염이 시작되었는데, 이는 합법적인 Node.js 배포 플랫폼을 가장하도록 설계된 악성 랜딩 페이지입니다 . 위협 행위자는 미국에 기반을 둔 피해자를 대상으로 Google Ads 캠페인을 운영했습니다. 광고는 2026 4월 23 에 마지막으로 표시되었으며 사이트는 현재 오프라인 상태입니다. 광고주는 우크라이나에 기반을 둔 검증된 이름 ВОЛОДИМИР ТЕРЕЩЕНКО 으로 등록되었습니다. 이것이 실제 운영자를 나타내는 것인지, 위장 계정을 나타내는 것인지, 아니면 구매한 신분을 나타내는 것인지는 불분명합니다. 5월 14, 2026 에 광고주와 그와 관련된 광고 캠페인이 Google에서 완전히 삭제되었습니다.
상호 작용 시 사용자는 app[.]miloyannopoulos[.]com/download?subid1=download 통해 리디렉션되었고, 이는 페이로드 URL link[.]storjshare[.]io/raw/jux4e4ky5mruo4jkxsssp42sau4q/ruslan/BATPackageBuilderSetup.bat 에 대해 302 Found 로 응답했습니다. 이는 공격자가 도메인 기반 평판 필터링을 회피하기 위해 악용한 Storj의 합법적인 링크 공유 서비스에 호스팅된 Windows 배치 스크립트를 전달했습니다.
배치 스크립트는 가짜 소프트웨어 설치 마법사 UI를 표시하고 PowerShell을 통해 Storj URL link.storjshare[.]io/raw/jwwvr4oskkkjsgevt774ta62ehya/ruslan/aBsvwbdas.exe 에서 다음 단계 실행 파일을 즉시 다운로드하고 -Verb RunAs 사용하여 실행하여 UAC 권한 상승 프롬프트를 트리거합니다.
배치 스크립트 실행 후 Elastic Defend는 악의적인 동작을 감지했습니다(정책은 감지만 하도록 설정됨). 이로 인해 Microsoft Common Language Runtime Loaded from Suspicious Memory 포함한 여러 동작 규칙이 트리거되었으며, 이는 CASTLESTEALER 과 일치하는 .NET 기반 페이로드를 암시합니다.
다음은 페이로드 다운로드부터 CASTLESTEALER 배포까지의 공격 체인 실행 그래프입니다.
OXLOADER 멀웨어 로더: 기술적 분석
저희 팀이 분석한 첫 번째 OXLOADER 샘플은 rohitab.com 의 인기도구인 API Monitor 로 위장했습니다. 이 로더는 합법적인 코드와 코드 은닉 기법이 많이 사용되었기 때문에 정적 파일 분석기의 탐지를 피할 수 있습니다.
OXLOADER가 런타임에 압축을 푸는 방법
해당 악성코드는 사용자 코드가 실행되기 전인 CRT 초기화 단계에서 실행을 시작합니다. CRT 함수 cinit() C++ 초기화 테이블(__xc_a → __xc_z)을 순회하며 각 항목을 호출하는 initterm() 호출합니다. 악성코드 개발자는 이러한 항목 중 하나를 탈취하여 첫 번째 복호화 스텁으로 꼬리 점프하기 전에 RegisterClipboardFormatW() 호출을 수행하는 함수를 가리켰습니다.
로더는 여러 복호화 스텁을 사용하는 자체 수정 기술을 이용하여 자체적으로 펼쳐집니다. 아래는 복호화 스텁이 런타임 중에 패치된 후 해당 스텁으로 점프하는 예시입니다.
패치가 완료되면 로더는 28,233바이트 영역을 복호화합니다. 각 바이트는 매 반복마다 업데이트되는 단일 바이트 XOR 키를 사용하여 복호화됩니다. 방금 복호화된 평문 바이트가 키에 추가되고, 이 키는 다음 바이트를 복호화하는 데 사용됩니다. 이와 유사한 복호화 루틴은 총 세 번 실행되며, 각 실행은 서로 다른 영역에서 수행됩니다.
정적 탐지를 회피하기 위해 사용되는 난독화 기법
OXLOADER는 제어 흐름 평탄화(CFF), 혼합 부울-산술(MBA), 불투명한 술어, 비연속적인 코드 영역에 걸친 함수 청킹 등 4단계 난독화 기법을 사용하여 IDA Pro와 같은 바이너리 분석 도구의 자동 함수 경계 감지 기능을 무력화합니다. 함수들은 무조건 점프를 통해 연결되며, 일부 영역은 MBA 연산을 통해 런타임에 대상 주소가 계산되는 간접 점프를 통해 도달됩니다. 그 결과 IDA Pro는 함수의 경계를 안정적으로 재구성할 수 없으므로 수동으로 수정해야 합니다.
로더는 다음 문자열 복호화 알고리즘을 사용하여 런타임에 다양한 문자열을 복호화합니다.
uint32_t obf_xor_a1_with_a2_plus_33FDA(uint32_t a1, uint32_t a2) {
return a1 ^ (a2 + 0x33FDA);
}
코드가 완전히 압축 해제/복호화되면 악성 프로그램은 이 문자열 복호화 함수를 Adler-32 API 해싱 알고리즘 과 결합하여 가져오기(import)를 동적으로 해결합니다.
OXLOADER는 어떻게 샌드박스 및 VM 탐지를 회피합니까?
OXLOADER는 API를 해결한 후 다양한 검사를 수행하여 시스템이 깨끗한 환경에서 실행되도록 하고 샌드박스 환경에서의 실행을 방지합니다.
| 확인하기 | 메서드 | 한계점 |
|---|---|---|
| 에뮬레이션 | WNetAddConnection2W 잘못된 리소스가 포함되어 있습니다. | ERROR_BAD_NAME (0x43)을 예상합니다. |
| CPU 카운트 | 프로세스 환경 검사 | ≥ 3 CPU |
| RAM | GlobalMemoryStatusEx | ≥ 3 GB 물리적 메모리 |
| 디스플레이 새로 고침 빈도 | WMI Win32_VideoController 쿼리 | ≥ 20 Hz |
| 지리적 지역 | GetUserGeoID | CIS 지오이드 제외 |
첫 번째 검사는 mpr!WNetAddConnection2W 사용하여 의도적으로 잘못된 형식의 네트워크 리소스(*72s@1s)에 연결을 시도합니다. 이 기술은 연결을 가로채거나 무조건 성공적인 연결을 반환하는 에뮬레이션/샌드박스를 무력화하는 것으로 보입니다. 악성코드 개발자는 TEB에 직접 접근하여 LastErrorValue 를 검색함으로써 이 호출을 확인합니다. 로더는 이 오류 코드가 ERROR_BAD_NAME (0x43) 일 것으로 예상합니다. 오류 코드가 이 값 이외의 다른 값인 경우 악성 프로그램은 실패 분기를 실행하고 중지합니다.
두 번째 검사는 프로세서 수를 기반으로 하는 샌드박스 방지 테스트입니다. 로더는 계속하려면 호스트에 최소 3 CPU가 있어야 합니다. 많은 샌드박스와 분석용 가상 머신은 리소스를 절약하기 위해 CPU가 하나 또는 두 개로 프로비저닝되므로, 이 임계값은 이러한 자동화된 분석 환경을 걸러냅니다.
다음 검사에서는 GlobalMemoryStatusEx() 사용하여 호스트에 최소 3 GB의 사용 가능한 물리적 메모리가 있는지 확인합니다.
추가 검사에서는 WMI를 사용하여 시스템 디스플레이의 새로 고침률을 쿼리하고 WQL 문 SELECT CurrentRefreshRate FROM Win32_VideoController 을 실행하고 반환된 값(헤르츠)을 20의 임계값과 비교합니다. 물리적 모니터는 일반적으로 60 Hz 이상을 보고하는 반면 헤드리스 및 기본 가상화 구성은 일반적으로 0 또는 1을 보고하며 20 미만의 값은 로더를 중단시킵니다.
지리적 및 언어적 제한
마지막 두 가지 검사에서 호스트가 CIS 국가에 있거나 러시아어로 구성된 경우 실행이 중단됩니다. 이 범주의 첫 번째 검사는 GetUserGeoID 사용하여 시스템의 지리적 지역을 검색하고 이를 하드코딩된 CIS 국가 GEOID 목록과 비교합니다.
두 번째 검사는 GetUserDefaultUILanguage 사용하고 러시아어 Windows 설치의 표준 구성인 LANGID(0x419 - Russian, Russia)와 일치시킵니다.
.reloc을 통한 셸코드 스테이징 섹션 및 OCX 파일
모든 검사가 통과되면 악성 프로그램은 Windows DirectUI Engine DLL(C:\Windows\System32\dui70.dll)의 복사본을 만들고 .ocx 확장자(PFHemkxVk.ocx)를 사용하여 임의로 생성된 이름으로 임시 위치에 저장합니다. 이러한 확장 방식 선택이 옥슬로더(OXLOADER)라는 가족 이름의 유래가 되었습니다.
그런 다음 OXLOADER는 이 대상 DLL(PFHemkxVk.ocx)에 (.xtext)이라는 새 섹션을 생성합니다.
이 새로운 섹션(.xtext)은 악성 코드의 다음 단계를 저장하고 실행하기 위해 RWX(읽기/쓰기/실행) 보호로 구성됩니다.
업데이트된 DLL(PFHemkxVk.ocx)은 LoadLibraryA 통해 기존 로더 프로세스에 로드됩니다.
일반 Windows 실행 파일에서 .reloc 섹션에는 Windows 로더가 이미지가 기본 주소가 아닌 다른 주소에 로드될 때 절대 주소를 패치하기 위해 적용하는 IMAGE_BASE_RELOCATION 블록 테이블이 포함되어 있습니다. 이 예시에서 악성코드 개발자는
사용하고 있습니다. .reloc 섹션은 기본 재배치 항목 대신 악성 코드를 담는 데 사용됩니다. 이는 강력한 정적 분석 경고 신호입니다. 합법적인 툴체인은 .reloc 섹션에 코드를 생성하지 않습니다.
.reloc 섹션의 이 셸코드는 OCX 파일의 새로 생성된 섹션(.xtext)으로 복사되고 로더는 이 코드를 호출합니다.
앞서 언급했듯이, 다음 단계를 압축 해제하는 데 사용되는 또 다른 복호화 스텁이 있습니다.
DonutLoader와 .NET 어셈블리를 통한 메모리 내 정보 탈취 프로그램
이 다음 단계 셸코드는 오픈 소스 셸코드 생성기인 DonutLoader 에서 구성된 페이로드입니다. DonutLoader는 .NET 어셈블리, DLL 및 EXE를 메모리 내 실행을 위한 위치 독립형 셸코드(PIC)로 래핑하는 데 사용됩니다. 압축 해제 중에 셸코드는 키(6E0A1F8F77F7011561F6F9CA96B71B8F) 및 IV(956C6128E9362E075F8D006C93616A66)를 사용하여 CTR 모드에서 Chaskey-LTS 블록 암호를 이용해 로더의 내장 구성 및 실행 컨텍스트를 복호화합니다.
복호화 후 페이로드는 aPLib를 통해 압축 해제된 다음 DonutLoader의 RunPE() 함수 를 통해 부트스트랩됩니다. 최종 탑재물은 헌트리스 가 새롭게 발견한 정보 탈취 장치인 캐슬스티어러(CASTLESTEALER)입니다. 이 속성은 이전 샘플 의 0xDEADBEEF 마커 사이에서 발견된 C2 통신에 사용된 것과 동일한 AES 키를 기반으로 합니다.
두 번째 OXLOADER 변형: 동일한 로더를 사용하지만, 위장된 프로그램이 다릅니다.
두 번째 OXLOADER 변종은 API 모니터가 아닌 Node.js 설치 프로그램으로 위장하지만 동일한 로더 메커니즘을 사용합니다.
5월 13 일, 2026 에 우리는 리다이렉터 엔드포인트 app.miloyannopoulos[.]com/download 무작위로 선택된 두 개의 Location 헤더 필드 중 하나로 응답하는 것을 발견했습니다.
https://link.storjshare[.]io/raw/jv5uebuqwzfpmtahj34q753ptykq/node/BATPackageBulderSetup.bathttps://link.storjshare[.]io/raw/jvsmdybqmvwep2oawbobp6ub7aza/node/node-v24.15.0-x64-86.exe
배치 설치 스크립트(BATPackageBulderSetup.bat, "Builder"에 대한 오타 포함)는 대부분 동일하게 유지되었습니다. 유일한 차이점은 Storj 페이로드 링크가 이제 node-v24.15.0-x64-86.exe 이라는 다른 바이너리를 가리킨다는 것이었습니다.
해당 악성코드는 파일 이름에 "node"를 유지하면서도 무해한 CMake 코드인 것처럼 위장하려고 시도하는데, 이는 아마도 미끼 테마를 그대로 유지하기 위한 것으로 보입니다. 저희는 이전에 배포된 "API 모니터" 샘플이 운영자의 배포 오류였을 가능성이 높다고 생각합니다.
실행 후 우리는 동일한 패턴을 발견했습니다. 메모리 내 자체 복호화를 위해 간접 점프가 사용된 후 mpr.dll 이 로드되고 WNetAddConnection2W 이 호출되었습니다. 우리는 이것이 이전에 논의된 것과 동일한 로더 메커니즘임을 확인했으며 이 샘플도 CASTLESTEALER 를 로드합니다.
아래는 자체 복호화가 발생하는 부분의 일부입니다. CMake 관련 더미 문자열이 함수 호출의 인수로 전달되는 것으로 보이며, 이 함수는 호출 지점 바로 뒤의 메모리에 작은 복호화 스텁을 삽입합니다. 실행은 이후 명령을 복호화하기 위해 스텁으로 이동하며 이 과정은 메인 악성코드 본체가 복호화될 때까지 2 번 더 반복됩니다.
결론: 수비수들이 옥실로더를 추적해야 하는 이유
OXLOADER는 아직 초기 운영 단계에 있지만, 그 이면에 담긴 엔지니어링을 보면 이 제품군은 주목할 만한 가치가 있음을 알 수 있습니다. 코드 난독화, 가상 머신 방지 조치, 바이너리를 위장하기 위해 사용된 무해해 보이는 코드, 그리고 독특한 스테이징 기법은 분석을 회피하기 위한 의도적인 엔지니어링 선택을 반영합니다. 그 투자는 결실을 맺어 정지 엔진 및 폭발 시험 전반에 걸쳐 낮은 탐지율을 기록했으며, 이로 인해 OXLOADER는 추적당하기 전에 작전을 수행할 수 있는 기회를 얻었습니다.
MITRE ATT&CK를 통한 REF8372
Elastic은 위협이 엔터프라이즈 네트워크에 대해 사용하는 일반적인 전술, 기술 및 절차를 문서화하기 위해 MITRE ATT& CK 프레임워크를 사용합니다.
전술
전술은 기술 또는 하위 기술의 이유를 나타냅니다. 이는 적의 전술적 목표, 즉 행동을 수행하는 이유입니다.
기술
기술은 공격자가 행동을 수행하여 전술적 목표를 달성하는 방법을 나타냅니다.
- 인프라 확보: 악성 광고
- 스테이지 기능: 멀웨어 업로드
- User Execution: Malicious File
- 명령 및 스크립팅 인터프리터: PowerShell
- 고도 제어 메커니즘 남용: 사용자 계정 제어 우회
- 난독화된 파일 또는 정보: 암호화/인코딩된 파일
- 파일 또는 정보 암호 해독/해제
- 난독화된 파일 또는 정보: 내장 페이로드
- 가장: 합법적인 이름 또는 위치 일치
- 하이재킹 실행 흐름: DLL 사이드 로딩
- 가상화/샌드박스 회피: 시스템 검사
- System Location Discovery: System Language Discovery
- 반사 코드 로드
REF8372 수정
예방
- 잠재적 브라우저 정보 검색
- 하드웨어 중단점을 사용한 회피 가능성
- 의심스러운 스레드 맥락 조작
- 서명되지 않은 DLL에서 VirtualAlloc API 호출
- 의심스러운 원격 메모리 할당
- 의심스러운 스택 후행 바이트에서 실행
- Microsoft Common Language Runtime Loaded from Suspicious Memory
- 의심스러운 PowerShell 실행
- 복사된 라이브러리에서 모듈 스톰핑
YARA
Elastic Security는 이 활동을 식별하기 위해 YARA 규칙을 만들었습니다.
관찰
이 연구에서는 다음과 같은 관찰 가능성에 대해 논의했습니다.
| 관측 가능합니다. | 유형 | 이름 | 참조 |
|---|---|---|---|
node-js\[.\]prentiva99\[.\]info | 도메인 이름 | 악성 광고 랜딩 페이지 | |
app\[.\]miloyannopoulos\[.\]com | 도메인 이름 | 악성 광고 리다이렉터 | |
fdfc7831e5c24cfa80152860dfe8c056ba079f7df1393bf6bb7b18ed974eda37 | SHA-256 | BATPackageBuilderSetup.bat | OXLOADER 다운로더 및 런처 |
de4f51649ec1a33071854aefe93ffb3fc225e19f802d8dd914676dd5dfef2615 | SHA-256 | BATPackageBulderSetup.bat | OXLOADER 다운로더 및 런처 |
9a9939dff297997732aaade9b243d695632cbd64033c5fbcb9de3d09b7e6c28d | SHA-256 | apimonitor-x64.exe | 옥로더 |
c85f2765a6c3c3f3907c17e57df12f8f68826f74bff3bbfd272af50666d065fe | SHA-256 | node-v24.15.0-x64-86.exe | 옥로더 |
4ec9d9d4d10ad78fc6d7bda7cb17d52984878ccd2dd4302fd1cef152313b9741 | SHA-256 | 캐슬스틸러 | |
39019279686c820c3af5684012a0085a7e2109f612c9fab886dd0577ace5b5c6 | SHA-256 | 캐슬스틸러 | |
89.124.95\[.\]161 | ipv4 | 캐슬스틸러 C2 | |
89.124.115\[.\]82 | ipv4 | 캐슬스틸러 C2 |