엘라스틱 보안 연구소에서 추적 중인 새로운 브라질 뱅킹 트로이 목마는 TCLBANKER로,MAVERICK/SORVEPOTEL계열의 주요 업데이트로 평가되는 멀웨어 패밀리로 확인되었습니다. REF3076으로 추적되는 이 캠페인은 강력한 분석 방지 기능을 갖춘 로더를 통해 모든 기능을 갖춘 뱅킹 트로이 목마와 자체 전파를 위한 웜 모듈 등 두 개의 내장된 .NET Reactor 보호 모듈을 배포하는 것이 특징입니다.
이 뱅킹 트로이 목마는 UI 자동화를 통해 피해자의 브라우저 주소 표시줄을 모니터링하여 59 브라질 뱅킹, 핀테크 및 암호화폐 도메인을 표적으로 삼습니다. 일반적인 원격 액세스 명령 외에도 가장 주목할 만한 기능은 운영자 주도의 소셜 엔지니어링을 위해 설계된 WPF 기반 전체 화면 오버레이 프레임워크입니다.
두 번째 모듈은 스팸 에이전트를 통한 배포를 처리하며, 이 중 인증된 브라우저 세션을 탈취하여 피해자의 연락처에 메시지를 보내는 WhatsApp 웜과 COM 자동화를 통해 피해자의 계정을 통해 피싱 이메일을 보내는 Outlook 이메일 봇의 두 가지 변종을 복구했습니다.
이 보고서를 통해 각 단계에 대한 자세한 기술적 분석을 제공합니다.
핵심 사항
- TCLBANKER는 환경 기반 페이로드 복호화를 사용하며, 샌드박스와 같은 잘못된 환경에서는 자동으로 페이로드 복호화에 실패합니다.
- 포괄적인 워치독 하위 시스템이 실행 전반에 걸쳐 분석 도구, 디버거, 계측 프레임워크 및 무결성 위반을 지속적으로 모니터링합니다.
- 이 뱅킹 트로이 목마는 59 브라질 뱅킹, 핀테크 및 암호화폐 도메인을 표적으로 삼아 피해자가 모니터링되는 사이트로 이동하면 웹소켓 C2 세션을 활성화합니다.
- WPF 기반 전체 화면 오버레이 프레임워크는 화면 캡처 도구에서 오버레이를 숨기면서 자격 증명 수집, 비싱 대기 화면, 가짜 Windows 업데이트 중단 등 공격자 주도의 소셜 엔지니어링을 가능하게 합니다.
- 웜 모듈이 멀웨어를 전파하는 방식: WhatsApp 봇과 Outlook 이메일 봇
- 모든 C2 및 배포 인프라는 단일 계정으로 Cloudflare Workers에서 호스팅되며, 개발자 아티팩트(디버그 로깅 경로, 테스트 프로세스 이름)와 불완전한 피싱 페이지가 있어 캠페인이 초기 운영 단계에서 식별되었음을 시사합니다.
배달
TCLBANKER는 두 개의 임베디드 페이로드(웜, 뱅커)를 배포할 수 있는 무거운 분석 방지 로딩 구성 요소가 있는 동적 감염 체인을 포함하는 브라질 뱅킹 트로이 목마입니다. 관찰된 감염 체인은 악성 MSI 설치 프로그램을 ZIP 파일 안에 번들로 제공합니다. 이러한 MSI 설치 프로그램 패키지는 Logi AI 프롬프트 빌더라는 서명된 로지텍 프로그램을 악용하고 있습니다.
TCLBANKER는 Flutter 프레임워크에 구축된 합법적인 로지텍 애플리케이션인 LogiAiPromptBuilder.exe 에 대한 DLL 사이드 로딩을 악용합니다. 악성 DLL screen_retriever_plugin.dll 은 같은 이름의 합법적인 Flutter 플러그인으로 가장하며 호스트 애플리케이션이 시작될 때 자동으로 로드됩니다.
MSI가 설치되면 악성 DLL이 즉시 로드되고 DllMain 진입 지점에서 시작됩니다.
로더
TCLBANKER용 로더 컴포넌트에는 디버깅 방지 기능, 분석 방지 검사, 문자열 암호화, 시스템 언어 검사, ETW 패치, 감시 기능 등의 기능이 포함되어 있습니다. 많은 기능을 갖추고 있지만 깊이가 부족하고 오래된 멀웨어 분석 도구에 대한 참조가 있습니다. 개발자가 LLM 지원 워크플로우를 사용했는지 여부는 확실하지 않지만, 저희 팀은 그것이 사실이라고 해도 놀라지 않을 것입니다.
실행이 시작될 때 TCLBANKER는 명령줄에 문자열(--renderer=sw)이 사용되었는지 여부에 따라 해당 .NET 어셈블리 페이로드를 정렬합니다. 기본 로더 기능 내에서 먼저 DLL이 로드된 방식에 따라 허용 목록/차단 목록 작업을 수행합니다. 악성 DLL은 호스트 프로세스가 다음 두 프로세스에서 나온 경우에만 실행됩니다:
logiaipromptbuilder.exetclloader.exe(테스트 중 개발자 문자열 참조 가능)
DLL이 다음 프로세스에 의해 로드된 경우 실행이 거부됩니다. 이러한 프로세스는 전통적으로 분석가가 DLL을 로드하고 디버깅하는 데 사용됩니다.
rundll32.exeregsvr32.exedllhost.exesvchost.exe
다음으로 TCLBBANKER는 디스크에서 ntdll.dll 를 대체하여 모든 사용자 모드 후킹을 제거합니다. 더 많은 회피를 위해 멀웨어는 나중에 사용되는 다음과 같은 시스템 호출 트램폴린을 생성합니다:
NtQueryInformationProcessNtSetInformationThreadNtSetInformationProcessNtTerminateProcessNtAllocateVirtualMemoryNtProtectVirtualMemory
시스템 호출 스텁을 설치한 후, 악성 코드는 EtwEventWrite 을 ntdll.dll 에 패치하여 사용자 모드 ETW 원격 측정을 비활성화합니다(기존 xor eax, eax; ret ).
TCLBANKER는 GetTickCount64() 를 사용하여 시작 틱을 캡처하고 500 ms 동안 슬립한 후 경과 시간을 측정하여 초기 샌드박스 검사를 수행합니다. 실제로 450 ms 미만이 지나면 멀웨어는 즉시 복귀하도록 슬립을 연결하는 샌드박스 또는 에뮬레이션 프레임워크를 탐지합니다.
TCLBANKER의 흥미로운 기능 중 하나는 다음 기준에 따라 세 가지 지문을 생성하는 열거 기능입니다:
- 디버깅 방지 검사
- 시스템 디스크 정보 및 메모리 검사
- 언어 확인
개발자는 각 카테고리의 "깨끗한" 경로에 할당된 매직 상수를 사용한 다음 각 경로에 대해 XOR을 수행하여 환경 해시를 생성합니다. 이 환경 해시 값은 임베디드 페이로드의 다운스트림 복호화에 영향을 미치기 때문에 중요합니다.
예를 들어 디버거가 존재하면 잘못된 해시를 생성하므로 악성코드가 해시에서 복호화 키를 도출하려고 시도하면 페이로드가 올바르게 복호화되지 않고 TCLBANKER가 실행을 중지합니다.
디버깅 방지 검사
TCLBANKER는 6가지 디버깅 방지 검사를 구현합니다:
Peb->BeingDebugged플래그를 통해 디버거를 식별합니다.- 디버거에서 프로세스가 시작될 때 설정된 힙-테일/힙-프리/체크-힙 플래그를 확인합니다.
- 다음을 사용하여
NtQueryInformationProcess()활용ProcessDebugPort NtQueryInformationProcess()사용ProcessDebugObjectHandle- 디버그 레지스터를 통한 하드웨어 중단점 감지 (
DR0-DR3) QueryPerformanceCounter()델타 및RDTSC사이클 카운트를 사용하여 경과 시간을 측정합니다.
시스템 정보 확인
TCLBANKER는 가상화, 시스템 및 사용자 정보에 따라 다음과 같은 5가지 검사를 수행합니다:
- 공급업체 서명을 사용하여 가상화 소프트웨어 확인
| 하이퍼바이저 | 공급업체 서명 |
|---|---|
| VMware | VMwareVMware |
| VirtualBox | V박스V박스V박스 |
| KVM | KVMKVMKVM |
| Xen | XenVMMXenVMM |
| Parallels | PRL 하이퍼바이저 |
| QEMU/TCG | TCGTCGTCGTCG |
GetDiskFreeSpaceExW()을 통해 루트 시스템 드라이브(C:\\)의 용량이 64 GB 이상인지 확인합니다.GlobalMemoryStatusEx()으로 전화하여 시스템에 2 GB 이상의 RAM이 있는지 확인합니다.- 다음을 통해 2 또는 CPU 프로세서를 확인합니다.
GetSystemInfo() - 일반 샌드박스/멀웨어 사용자 이름 확인
sandbox,malware,virus,sample,john doe,currentuser
언어 확인
마지막 환경 지문 검사를 위해 TCLBANKER는 GetUserGeoID() 를 사용하여 감염된 컴퓨터의 지리적 정보를 검색하고, 지리적 ID(0x20)를 기반으로 브라질 사용자를 대상으로 합니다. GetUserDefaultLCID() 을 통해 두 번째로 로캘을 확인하면 사용자의 기본 언어가 브라질 포르투갈어(pt-BR, LANGID 0x0416)인지 확인할 수 있습니다.
이러한 일련의 검사 후 TCLBANKER는 어떤 것이 감지되면 실행을 중단하거나 그렇지 않은 경우 DbgUiRemoteBreakin() 을 패치하여 또 다른 디버깅 방지 검사를 생성합니다. 이 멀웨어는 첫 바이트를 a ret 명령어로 패치하여 원격으로 프로세스에 침입하려는 시도가 실패하면 주입된 스레드가 즉시 반환되고 표적은 일시 중단되지 않고 계속 실행되도록 합니다.
그 후, 멀웨어는 앞서 계산한 환경 해시와 함께 .rdata 섹션에서 하드코딩된 상수를 사용하여 AES-256 CBC 키와 IV를 도출합니다. TCLBanker는 BCryptDecrypt() 을 사용하여 임베디드 페이로드를 해독한 다음, RtlDecompressBuffer 을 통해 LZNT1 압축 알고리즘을 사용하여 압축을 해제합니다.
각 페이로드가 복호화되면 TCLBANKER는 CoInitializeEx() 을 통해 COM 을 초기화하고 CLR 호스팅 API를 사용하여 .NET 런타임을 로드합니다. 페이로드 진입점을 시작하기 전에 TCLBanker는 두 개의 새 스레드를 생성합니다. 하나는 워치독 역할을 하고, 다른 하나는 하트비트 검사로 워치독 스레드를 모니터링합니다.
감시견
TCLBANKER에는 디스어셈블러, 디버거, 계측 제품, 안티바이러스 제품, 샌드박스 제품 등 다양한 분석 도구를 대상으로 하는 포괄적인 감시 기능이 있습니다. 이 섹션에서는 이 기능에서 사용하는 다양한 기법에 대해 간략하게 설명합니다:
- 다음을 통해 디버거 확인
PEB→BeingDebugged - 하드웨어 중단점 시계
DR0/DR1/DR2/DR3 - 각 함수의 첫 12 바이트를 스캔하여 인라인 훅이 있는지 Windows 함수(
BCryptDecrypt(),BCryptOpenAlgorithmProvider())를 확인합니다. - 계측 도구 및 관련 스트링용 모니터 (
frida,cydia,user-path injection,hook framework) frida또는 다음을 검색하는 모든 커널 이름의 파이프를 검토합니다.linjector- 다음 프로세스 이름을 대상으로
CreateToolhelp32Snapshot()을 통해 프로세스 열거를 수행합니다:frida,de4dot,dnspy,megadumper,extremedumper,processhacker,x64dbg,x32dbg,pe-sieve,scylla,Ilspy,dotpeek,netreactorslayer,cheatengine
- 이러한 제목에
GetWindowTextW()을 통해 Windows 제목 감지를 사용합니다:x64dbg,x32dbg,ida -,ida pro,ghidra,dnspy,megadumper,extremedumper,processhacker,ollydbg,windbg)_,pe_sieve,scylla
FindWindowW()을 통해 다음 창 클래스 이름을 기반으로 분석가 도구를 식별합니다:IDATopLevelWindow,idaabortwndclass,TIdaWindow,x64dbg,x32dbg,OLLYDBG,WinDbgFrameClass,ProcessHacker,SystemInformer,CheatEngine,HxdClass
- 로드된 다음 모듈을 확인합니다.
dbeng.dll,dbgcore.dll,SbieDll.dll,snxhk.dll,cmdvrt32.dll,cmdvrt64.dll,cuckoomon.dll,pstorec.dll,vmcheck.dll,wpespy.dll
- 다음 뮤텍스와 이벤트를 대상으로 합니다:
Ida_trusted_idbs,IDA_COMM_PIPE_,Local\\x64dbg,Local\\x32dbg,Frida,YOURAPPNAMEHERE
.text섹션에서CRC32무결성 검사를 수행하여 변조를 방지합니다.
뱅킹 트로이 목마 모듈
Tcl.Agent 체인의 주요 구성 요소인 뱅킹 트로이 목마입니다. .NET Reactor로 보호되며, de4dot 및 NETReactorSlayer와 같은 사용 가능한 오픈 소스 도구를 사용하여 난독 해독하는 데는 실패했지만, 사용자 지정 난독 해제 파이프라인을 사용하여 이 단계를 만족스러운 상태까지 정적으로 난독 해제하여 .NET Reactor의 문자열 암호화, 제어 흐름 플랫화, IL 변이, 대리자 프록시 및 암호화된 메서드 본문(Necrobit)을 처리할 수 있었죠. 새로운 멀웨어이긴 하지만 코드 구조의 대부분은 2020년에 발표된 ESET의 LATAM 뱅킹 트로이 목마 구현 청사진을 여전히 따르고 있습니다.
처음에 멀웨어는 지오펜싱을 수행하여 다음 지표 중 >= 2 이 브라질과 일치해야 하며, 그렇지 않으면 브라질 컴퓨터가 아닌 경우 즉시 종료됩니다:
| 확인하기 | 구현 |
|---|---|
| 지역 코드 | new RegionInfo(CultureInfo.CurrentCulture.LCID).TwoLetterISORegionName == "BR" |
| 시간대 | >= -5.0이면, == -2.0인지 확인합니다. |
| LCID | CultureInfo.CurrentCulture.LCID == 1046 (포르투갈어-브라질어) |
| 키보드 | GetKeyboardLayoutList() - 각 레이아웃을 확인합니다: (ToInt32() & 0xFFFF) == 1046 |
설치 및 지속성
첫 번째 실행 시 멀웨어는 전체 애플리케이션 디렉터리를 %LocalAppData%\LogiAI 에 복사합니다. 소스 디렉터리의 모든 .dll 및 .exe 파일에 대해 SHA-256 해시를 계산하여 .version 마커 파일에 기록합니다. 이후 실행 시에는 해시를 비교하여 중복 복사본을 건너뜁니다. 복사 후 설치 경로에서 새 인스턴스를 시작하고 종료합니다.
작업 스케줄러(CLSID 0F87369F-A4E5-4CFC-BD3E-73E6154572DD)와 COM 인터롭을 사용하여 RuntimeOptimizeService 이라는 이름의 예약된 작업을 만듭니다. 작업은 숨김, 사용, 실행 시간 제한 없음, 배터리 사용 시 허용, 사용 가능할 때 시작, 현재 사용자로 범위가 지정된 로그온 트리거(type 9)에서 실행되도록 구성됩니다. TASK_CREATE_OR_UPDATE 및 TASK_LOGON_SERVICE_ACCOUNT 에 등록합니다.
지속성이 설정되면 에이전트는 에이전트Id(MachineName-UserName), 머신 이름, 사용자 이름(중복) 및 OS 버전이 포함된 첫 번째 실행 POST 비콘을 https://campanha1-api.ef971a42.workers[.]dev/api/installs 으로 보냅니다. 요청은 하드코딩된 캠페인 인증 토큰 0d21613a-2609-45fc-83ff-d0feaa0c891f 으로 인증됩니다. 최신 버전은 이 호출(C:\temp\tcl-debug.txt)에 대한 디버그 로깅을 추가하여 실수로 디스크에 에이전트의 존재를 노출시키는 개발자 아티팩트를 추가합니다.
자체 업데이트
에이전트는 시작 파이프라인 초기에 실행되는 해시 기반 자체 업데이트 게이트를 구현합니다. 설치 디렉터리의 flutter_engine.cfg 에서 로컬 버전 해시를 읽은 다음(레거시 version.hash 파일 이름이 있는 경우 마이그레이션) 잘린 사용자 에이전트 문자열 (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 을 사용하여 파일 서버 엔드포인트 documents.ef971a42.workers[.]dev/api/version 에서 현재 해시를 가져옵니다.
응답은 "해시" 키에 대해 구문 분석됩니다. 원격 해시가 로컬 해시와 일치하면 실행이 정상적으로 계속됩니다. 처음 설치하면 원격 해시가 디스크에 기록되고 업데이트 없이 실행이 진행됩니다.
해시 불일치가 감지되면 에이전트는 업데이트 페이로드를 documents.ef971a42.workers[.]dev/api/update 에서 %TEMP%\update_{8hexchars}.msi 으로 다운로드하고 무기명 토큰 b7ba9e80-0d04-4d9e-b217-c8b3cce335a2 으로 인증합니다.
다운로드는 건전성 검사로 최소 100KB의 크기를 기준으로 유효성을 검사합니다. 그런 다음 에이전트는 현재 프로세스가 종료될 때까지 작업 목록을 폴링하고 자동 설치를 위해 msiexec /i /qn REINSTALLMODE=amus 을 실행한 다음 스스로 삭제하는 자동 삭제 배치 스크립트를 %TEMP% 에 작성합니다. 배치 파일은 에이전트가 종료되기 전에 숨겨진 cmd.exe 프로세스를 통해 실행되어 업데이트된 페이로드에 실행을 넘깁니다.
브라우저 URL 모니터 및 C2 세션 초기화
멀웨어 에이전트는 매초마다 UI 자동화를 통해 포그라운드 브라우저의 주소 표시줄을 읽는 브라우저 URL 모니터 기능을 호출합니다. GetForegroundWindow 를 호출하여 소유 프로세스를 확인한 다음, 이 스택 오버플로 구현과 유사하게 프로세스 이름을 Chrome, Firefox, Microsoft Edge, Brave, Opera 및 Vivaldi에서 확인한 다음 AutomationElement.FromHandle -> FindFirst(Descendants, ControlType.Edit) -> ValuePattern.Current.Value 을 사용하여 URL을 추출합니다.
추출된 URL은 바이너리에 포함된 고정된 타겟 뱅크 목록과 16바이트 키와 base64 인코딩으로 XOR을 통해 인코딩된 고정된 뱅크 목록과 일치합니다.
이 GitHub 요점에는 브라질 은행, 핀테크 플랫폼, 암호화폐 거래소 등 59 대상 도메인 목록이 포함되어 있으며, 각 복호화된 도메인에 추가된 대상 ID별로 그룹화되어 있습니다.
일치하는 항목이 발견되면 도메인 대상 ID가 다음 상태로 전달되고, wss://mxtestacionamentos[.]com/ws 에 웹소켓 연결을 설정하여 공식 C2 통신을 초기화합니다. OnConnect 핸들러가 실행되어 에이전트 ID(런타임에 임의의 GUID), 머신 이름, 사용자 이름, 머신 정보, 타임스탬프, 도메인 대상 ID(C2가 피해자가 어떤 웹사이트를 열었는지 알 수 있도록) 및 서명이 포함된 등록 패킷을 보냅니다.
핸드셰이크 서명을 생성하기 위해 캠페인 GUID 70e4f943-e323-4484-97d7-35401bf6812c 를 키로 사용하여 피해자 식별자(에이전트 ID, 머신 이름, 사용자 이름, OS 버전, 타임스탬프)에 서명하는 데 HMAC-SHA256이 사용됩니다.
그러면 서버가 등록 승인으로 응답하여 세션을 공식적으로 시작하고 명령 디스패치 루프에 들어갑니다. 세션이 시작되면 500밀리초마다 작업 관리자 킬러가 실행되어 피해자가 상담원의 프로세스를 검사하거나 종료하지 못하도록 합니다.
C2 명령 테이블
기능 요약은 아래의 옵코드 표를 통해 설명합니다:
| Opcode | 목적 |
|---|---|
| 2 | 등록 확인, 작업 관리자 킬러 시작 |
| 4 | 우아한 웹소켓 연결 해제 |
| 5 | 자살: 모든 형제 프로세스를 종료하고 종료 |
| 6 | 강제 재부팅 (shutdown.exe /r /t 0 /f) |
| 7 | 자살 후 제거: 자신을 제외한 동일한 호스트 바이너리 이름을 가진 모든 프로세스(형제) 죽이기 → 제거 → 종료 |
| 16 | 스크린샷 |
| 17 | 화면 스트리밍 시작 |
| 18 | 화면 스트리밍 중지 |
| 19 | 화면 캡처 품질 설정(1~100) |
| 20 | 모니터 열거 |
| 32 | 마우스 이동(X, Y, 모니터 인덱스) |
| 33 | 마우스 클릭 오버레이: {X,Y,Button,MonitorIndex} 파싱 → 절대 데스크톱 좌표로 변환 → 해당 지점을 덮는 임플란트 자체 오버레이 창 찾기 → 해당 픽셀에서 오버레이에 2x2 영역 구멍 뚫기 → SetCursorPos + SendInput 마우스 다운/업(오버레이 아래에 있는 실제 데스크톱 콘텐츠에 착지). |
| 34 | 마우스 스크롤(델타, SendInput) |
| 35 | 키 탭(키코드, SendInput) |
| 37 | 키 다운 (키코드, SendInput) |
| 38 | 키업(키코드, SendInput) |
| 39 | 키로거 시작(WH_KEYBOARD_LL 후크) |
| 40 | 키로거 플러시, C2로 내보내기 |
| 41 | 클립보드 하이재킹 (Clipboard.SetText) |
| 48 | 파일 시스템 디렉터리 목록 |
| 65 | 실행 중인 프로세스 정보 얻기 |
| 67 | 셸 명령 실행 (cmd.exe /c) |
| 80 | 보이는 모든 창을 열거합니다. |
| 81 | 창 관리자: 창 프로세스 종료 / 창 최소화 / 창 복원 / 창을 전경으로 가져 오기 / 창 닫기 / 다른 모니터로 창 이동 |
| 83 | 스톨 오버레이 표시: 진행 단계 또는 가짜 Windows 업데이트 화면 표시 |
| 84 | 해체 오버레이 |
| 85 | 화면 캡처 면역을 전환합니다. 모든 오버레이 창에서 WDA_EXCLUDEFROMCAPTURE 을 활성화/비활성화하여 화면 공유/스크린샷에서 해당 창을 숨깁니다. |
| 86 | 오버레이 콘텐츠 새로 고침 |
| 87 | 컷아웃 오버레이 표시: 보이는 영역 컷아웃으로 오버레이 내부에 외부 창을 고정합니다. |
| 96 | 자격 증명 프롬프트 오버레이 표시 |
소셜 엔지니어링 UI 프레임워크
뱅킹 트로이 목마의 더 흥미로운 기능은 활성 C2 세션 중에 은행 테마 사기 흐름을 조율하는 WPF 기반 전체 화면 오버레이 하위 시스템입니다.
오버레이 수명 주기
오버레이 관리자는 모니터당 하나의 전체 화면 WPF 창을 생성합니다. 창은 작업 표시줄(WindowStyle.None, Topmost = true, ShowInTaskbar = false)에서 테두리가 없는 맨 위에 숨겨져 있고, 오버레이 해체 명령을 통해 운영자가 내부 플래그를 뒤집을 때까지 해제를 거부하는 사용자 지정 Closing 핸들을 사용하여 창이 닫히지 않도록 구성됩니다.
시작 시 관리자는 오버레이 배경으로 CopyFromScreen 을 통해 모든 디스플레이의 PNG 스크린샷을 캡처하여 '정지된 데스크톱' 모양을 만듭니다. 현재 활성화된 오버레이에 따라 피해자는 그 뒤에 있는 실제 데스크톱 환경을 인식하게 됩니다.
500ms 타이머는 SetWindowPos 을 통해 HWND_TOPMOST 을 지속적으로 다시 적용하여 오버레이 위에 나타나려는 모든 창을 무효화합니다.
또한 캡쳐 방지 기능은 WDA_EXCLUDEFROMCAPTURE 으로 SetWindowDisplayAffinity 을 호출하여 오버레이를 화면 캡처 도구에 보이지 않게 하여 운영자가 스크린샷 및 화면 스트리밍 명령을 통해 자신의 오버레이를 볼 수 있도록 합니다.
입력 차단기
기본 모니터에는 WH_KEYBOARD_LL 와 WH_MOUSE_LL 두 개의 후크가 설치됩니다. 두 후크 모두 각각의 주입된 플래그(키보드의 경우LLKHF_INJECTED, 마우스의 경우 LLMHF_INJECTED )를 확인하여 운영자의 원격 명령으로 SendInput 을 통해 주입된 입력이 그대로 통과되도록 합니다. 키보드 후크는 탭, 이스케이프, Alt+F4, Win 키, 프린트스크린, Ctrl, Alt 및 모든 탐색 키를 삼키고, 마우스 후크는 오른쪽 클릭, 가운데 클릭, 스크롤을 차단하지만 왼쪽 클릭과 이동은 허용하므로 피해자는 여전히 오버레이 프롬프트와 상호작용할 수 있습니다.
소셜 엔지니어링 UI 빌더
5개의 교체 가능한 콘텐츠 렌더러가 오버레이 프레임워크에 연결됩니다:
자격증명 프롬프트: 운영자의 요청 매개변수에 따라 선택되는 세 가지 입력 모드를 지원합니다.
- 전화 모드는 실시간 브라질 형식 마스킹((##) ####-#### 10자리 유선 전화의 경우, (##) #####-#### 11자리 휴대폰의 경우)을 최대 11 자리까지 적용합니다.
- 가상 키패드 모드는 화면에 숫자 키패드(0~9번 버튼과 "limpar"/clear)를 렌더링하여 입력을 글머리 기호로 표시하여 PIN 입력을 모방합니다.
- 기본 모드는 최대 길이를 구성할 수 있는 일반 텍스트를 허용합니다.
모든 모드는 같은 숫자 시퀀스(000000) 및 오름차순/내림차순 실행(123456, 654321)을 알고리즘적으로 거부하는 품질 검증기를 통해 입력을 실행하여 버려지는 값을 입력하지 못하도록 합니다.
제출 작업은 캡처된 값을 C2로 실행합니다.
비싱 대기 화면: 피해자가 인증 정보 프롬프트에 전화번호를 제출한 후 트리거됩니다. "" 중앙 이미지 '호흡' 애니메이션과 엇갈린 불투명도 애니메이션(300ms 점당 오프셋)이 있는 세 개의 점("연락 중")을 표시하여" 비주얼을 연결하는 "을 생성합니다. 그런 다음 운영자 또는 공범이 은행 보안 직원을 사칭하여 피해자의 실제 전화로 전화를 걸 수 있습니다.
진행 단계: 무작위 애니메이션과 함께 가짜 처리 단계 목록을 표시하는 작업자 테마의 스톨 화면입니다. 단계별 소요 시간은 약 15 분으로 무작위로 지정됩니다. 타이머는 각 단계를 순차적으로 진행하면서 완료된 단계를 시각적으로 표시하고 현재 단계를 강조 표시하며 나머지 단계는 어둡게 표시합니다. 모든 단계가 완료되면 시퀀스는 새로운 무작위 타이밍으로 이전 위치로 초기화되고 계속 진행됩니다.
가짜 Windows 업데이트: Windows 10/11 업데이트-재시작 화면을 모방한 대체 중단 화면입니다. 원으로 배열된 5개의 타원 회전 표시기가 있는 단색 #0078D7 (Windows 강조 파란색) 배경을 렌더링합니다. 백분율 판독값은 실제 Windows 업데이트의 불규칙한 진행 동작을 모방하기 위해 무작위로 선택한 50~81초 간격으로 25~35%(% )씩 점프합니다. 기본 자막입니다: "업데이트 작업 중" ("업데이트 작업 중").
컷아웃 오버레이: 전체 화면 오버레이에서 직사각형 구멍을 잘라내어 기본 애플리케이션 창을 노출합니다. 운영자는 옵코드 87을 통해 구멍 치수를 지정하면 오버레이 관리자가 투명 테두리 플레이스홀더가 있는 테마 카드를 만들고 레이아웃 후 화면 좌표를 계산한 다음 CreateRectRgn + CombineRgn(RGN_DIFF) + SetWindowRgn 을 사용하여 일치하는 영역 구멍을 잘라냅니다. 대상 창이 구멍 아래로 재배치됩니다. 그 결과 오버레이 내에 실제 애플리케이션 창이 표시되고 피해자는 실제 애플리케이션과 상호 작용하는 반면 주변 오버레이는 기만적인 컨텍스트를 제공합니다.
웜 모듈
로더가 호출하는 두 번째 모듈은 Tcl.WppBot 으로, 스팸 및 피싱 메시지를 대규모로 전파하여 TCLBANKER를 배포하도록 설계되었습니다. 두 개의 서로 다른 로더에서 두 가지 다른 에이전트 유형을 복구하여 분석했습니다:
- 브라우저 세션을 가로채는 WhatsApp 웜
- COM 인터롭을 통해 Microsoft Outlook을 악용하는 Outlook 이메일 봇
Tcl.WppBot 도 Tcl.Agent 을 보호하는 데 사용되는 것과 동일한 버전으로 .NET Reactor로 보호되므로 이 단계에서도 페이로드를 정적으로 난독 해제할 수 있었습니다.
두 에이전트 모두 동일한 C2 백엔드, 인증 자격 증명 및 운영 인프라를 공유합니다. C2 URL과 API 키는 시작 시 하드코딩된 키로 XOR 복호화를 사용하여 해독됩니다.
- C2 URL:
campanha1-api.ef971a42.workers[.]dev(Cloudflare Workers 앱) - API 키/무기명 토큰:
0d21613a-2609-45fc-83ff-d0feaa0c891f
C2는 https://campanha1-api.ef971a42.workers[.]dev/api/campaign 엔드포인트를 통해 단일 슈퍼셋 캠페인 구성 개체를 제공합니다. 각 에이전트 변형은 전체 개체를 역직렬화하지만 해당 채널과 관련된 필드만 읽습니다.
캡처한 구성:
message : Ola tudo bem?
Preciso de um orçamento, estarei encaminhado caso tenha os produtos por favor me retorne para
darmos continuidade no atendimento.
https://arquivos-omie[.]com ð
âï¸*IMPORTANTE*: Este orçamento foi otimizado para visualização em Computadores Desktop,
pois o mesmo necessita de visualizador de excel, word ou pdf.
fileUrl : https://documents.ef971a42.workers[.]dev/file
delayMin : 1
delayMax : 3
maxPerSession : 3000
updatedAt : 2026-04-17T15:54:07.003Z
type : gmail
subject : Prezado(a), NFe disponÃvel para impressão
emailMessage : <!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Nota Fiscal DisponÃvel</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
padding: 0;
text-align: center;
background-color: #f4f4f4; /* Cor de fundo mais clara */
color: #333; /* Cor do texto ajustada para ser visÃvel */
}
h1 {
font-size: 24px;
margin-bottom: 20px;
font-weight: normal; /* TÃtulo sem negrito */
}
p {
font-size: 16px;
margin-bottom: 20px;
line-height: 1.6;
color: #333; /* Garantir que o texto esteja visÃvel */
}
.btn {
background-color: #007BFF;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>Prezado(a)</h1>
<p>
Sua Nota Fiscal Eletrônica (NFe) está disponÃvel e pronta para ser acessada.
Para facilitar, basta clicar no botão abaixo para abrir o documento.
</p>
<p>
Caso tenha alguma dúvida sobre os detalhes da nota ou precise de alguma alteração, por
favor, entre em contato conosco.
</p>
<a href="https://arquivos-omie[.]com" target="_blank">
<button class="btn">Abrir Nota Fiscal</button>
</a>
<p>
Agradecemos pela confiança e ficamos à disposição para qualquer outra necessidade.
</p>
</body>
</html>
emailDelayMin : 30
emailDelayMax : 90
emailMaxPerSession : 100
동일한 Cloudflare 계정 ef971a42 은 documents.ef971a42.workers[.]dev 에서 페이로드 전송 CDN(구성 개체의 fileUrl 용 도메인)도 호스팅합니다. /file 엔드포인트를 통해 액세스할 수 있으며, 현재 TCLBANKER 트로이 목마에 감염된 LogiAI 프롬프트 빌더 MSI가 포함된 zip 파일을 제공합니다. 이 인프라 결정을 통해 운영자는 전용 서버를 유지 관리하지 않고도 인프라를 신속하게 재배치할 수 있습니다.
작성 시점을 기준으로 위 구성에서 식별된 피싱 도메인 arquivos-omie[.]com (2026-04-15에 생성됨)은 운영 가능한 상태가 아닙니다(Welcome! 이 포털은 현재 정기 점검 중입니다. 나중에 다시 시도하세요.) 캠페인은 초기 운영 단계에 있거나 작업을 위한 단계에 있을 수 있습니다. 이 도메인은 브라질의 유명한 ERP(전사적 자원 관리) 제품군을 사칭하도록 이름도 지정되었습니다.
에이전트 1: WhatsApp 봇
WhatsApp 에이전트는 피해자의 인증된 WhatsApp 웹 세션을 조용히 장악하여 스팸 메시지를 전송하고 브라질 연락처에 TCLBANKER를 배포합니다.
세션 하이재킹
이 멀웨어는 대상 시스템에서 Chromium 기반 브라우저를 검색하는 것으로 시작하여 App Paths 레지스트리 항목과 Chrome, Edge, Brave, Opera 및 Vivaldi의 일반 설치 디렉터리를 모두 검사합니다. 그런 다음 각 브라우저의 사용자 프로필(예: "기본값," " 프로필 1," 등)을 탐색하여 활성 WhatsApp 웹 세션의 증거를 찾습니다. 프로필의 인덱싱된DB 저장소에 <profile_dir>/IndexedDB/https_web.whatsapp[.]com_0.indexeddb.leveldb/ 에 있는 WhatsApp 웹 레벨DB 디렉토리가 포함되어 있으면 프로필에 인증된 세션이 있는 것으로 플래그가 지정됩니다.
그런 다음 각 프로필은 프로필 복제 및 세션 하이재킹 기능으로 전송됩니다.
각 적격 프로필에 대해 이 악성 코드는 임시 디렉터리( %TEMP%\<GUID>\)에 복제하여 WhatsApp 웹 세션을 재개하는 데 필요한 파일만 복사합니다: IndexedDB, Local Storage, Session Storage, databases, Web Data, Login Data, Cookies 입니다. 그런 다음 셀레늄 웹드라이버를 통해 헤드리스 크롬 인스턴스를 시작하고 --user-data-dir 이 복제된 프로필을 가리킵니다.
일치하는 chromedriver.exe 은 %TEMP%\msvc-rt14\bin\hostfxr.exe 에 드롭된 위장한 Selenium Manager 바이너리에 의해 런타임에 확인되며, --browser chrome --output json 로 호출되어 피해자가 설치한 Chrome 버전과 호환되는 크롬 드라이버의 경로를 반환합니다.
이 멀웨어는 실행 직후에 JavaScript를 삽입하여 navigator.webdriver 을 숨기고 chrome.runtime 을 채우고 Notification.permission / permissions.query 상태 불일치를 조정하고 비어 있지 않은 navigator.plugins 배열을 가짜로 만들고 navigator.languages 을 ['pt-BR', 'pt', 'en-US', 'en'] 으로 설정하여 표적 인구 통계와 일치하도록 합니다.
Object.defineProperty(navigator, 'webdriver', {
get: () = > undefined
}
);
delete navigator.__proto__.webdriver;
if (window.chrome) {
window.chrome.runtime = window.chrome.runtime || {};
}
const origQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (p) = > (
p.name == = 'notifications' ?
Promise.resolve( {
state: Notification.permission
}
) :
origQuery(p)
);
Object.defineProperty(navigator, 'plugins', {
get: () = > [1, 2, 3, 4, 5], }
);
Object.defineProperty(navigator, 'languages', {
get: () = > ['pt-BR', 'pt', 'en-US', 'en'], }
);
window.navigator.chrome = {
runtime: {}
};
복제된 프로필이 로드되면 브라우저는 web.whatsapp[.]com 로 이동하고 멀웨어는 최대 45 초 동안 기다렸다가 결과 페이지 상태를 관찰합니다. 채팅 인터페이스가 나타나면(복제된 인덱싱된 DB가 유효하고 QR 스캔 없이 세션이 재개됨) 임베디드 WA-JS(WPPConnect) 라이브러리를 삽입하고 WPP.contact.list 및 WPP.chat.sendTextMessage 이 호출 가능해질 때까지 기다렸다가 캠페인 디스패치 루프를 시작합니다. 대신 QR코드 프롬프트가 표시되면 엔진은 주입을 시도하지 않고 "qr_code" 을 반환한 다음 다음 후보 프로필을 시도합니다.
스팸 기능
인젝션이 성공하면 멀웨어는 C2 엔드포인트 https://campanha1-api.ef971a42.workers[.]dev/api/campaign 에서 활성 캠페인을 검색하여 메시지 본문, 선택적 첨부 URL, 캡션 및 타이밍 매개변수를 제공합니다. 그런 다음 파일 서버( https://documents.ef971a42.workers[.]dev/file )에서 TCLBANKER를 다운로드하고 브라우저 컨텍스트에서 디스크에 드롭하지 않고 파일 개체로 재구성합니다.
그런 다음 악성 코드는 WPP.contact.list 으로 전화하여 피해자의 주소록을 수집하고 그룹, 방송 및 비브라질 번호를 필터링한 다음 WPP.chat.sendTextMessage 및 sendFileMessage 을 통해 메시지를 발송하기 시작합니다. 이 멀웨어는 각 배치 후 C2 엔드포인트 /api/progress 에 진행 상황을 보고하고 /api/control 에 운영자의 원격 일시 중지 또는 재전송 명령을 폴링합니다.
에이전트 2: Outlook 이메일 봇
Outlook 에이전트는 피해자가 설치한 Microsoft Outlook 애플리케이션을 악용하여 피해자의 이메일 주소에서 피싱 이메일을 보내는 이메일 스팸봇으로, 공격자가 제어하는 인프라에서 보낸 이메일보다 스팸으로 탐지하기가 더 어렵습니다.
Outlook Discovery & COM 첨부 파일
OUTLOOK.EXE 이 아직 실행 중이 아니라면 App Paths 레지스트리 항목과 알려진 설치 디렉터리에서 설치를 찾아 새 프로세스에서 실행하려고 시도합니다. 그런 다음 멀웨어는 COM 인터롭을 통해 프로세스에 연결합니다: Marshal.GetActiveObject("Outlook.Application")를 통해 프로세스에 연결하고 이메일 계정이 하나 이상 구성되어 있는지 확인합니다.
수확에 문의
그런 다음 멀웨어는 별도의 프로세스에서 Outlook COM을 통해 연락처를 수집하는 PowerShell 스크립트( %TEMP%\oc<guid>.ps1, )를 드롭합니다. 먼저, 모든 연락처 항목의 기본 연락처 폴더를 읽어 각 연락처 항목에서 이메일 주소와 전체 이름을 추출합니다. 둘째, 모든 스토어의 루트 폴더를 반복하여 받은 편지함과 유사한 폴더를 찾고, 받은 편지함 메시지를 최신순으로 정렬하고, 발신자 이메일 주소와 이름을 추출하여 email|name 형식의 .txt 파일에 기록합니다.
각 후보 이메일에 대해 추가 필터링을 수행하여 전달 가능성을 극대화합니다.
스팸 기능
WhatsApp 봇과 마찬가지로 이 멀웨어는 https://campanha1-api.ef971a42.workers[.]dev/api/campaign 에서 활성 캠페인을 검색한 다음 COM 자동화를 통해 피해자의 Outlook 계정을 통해 이메일을 보냅니다. 각 이메일은 outlookApp.CreateItem(0) (MailItem)을 통해 수신자를 To, 캠페인 제목은 emailMessage, 캠페인 내용은 SendUsingAccount 를 통해 피해자의 실제 계정을 사용하여 전송됩니다 .
에이전트는 전송 사이에 무작위 지연을 적용하고 주기적으로 C2 제어 엔드포인트 /api/control 에서 일시 중지 또는 재전송 명령을 확인하고 진행 상황을 /api/progress 에 보고합니다.
인프라
REF3076 액터들은 C2 및 파일 호스팅을 위해 worker[.]dev Cloudflare 서버리스 인프라를 활용했습니다. 이 결정을 통해 피해자가 이미 Cloudflare에 가지고 있을 수 있는 모든 신뢰를 승계하고 필요에 따라 인프라를 신속하게 순환할 수 있습니다.
위 피싱 사이트(arquivos-omie[.]com)의 바디 해시(91fafaa1240676afe5c55d931261e3798797c408)를 중심으로 무기화를 위해 준비 중인 것으로 보이는 추가 도메인을 확인할 수 있었습니다:
| 도메인 | First Seen | 정보 | ASN(공급자) |
|---|---|---|---|
| arquivos-omie[.]com | 2026-04-17 | 스쿼팅 - 중소기업을 위한 브라질 SaaS | AS 13335 (클라우드플레어) |
| documentos-online[.]com | 2026-04-11 | Generic | AS 13335 (클라우드플레어) |
| afonsoferragista[.]com | 2026-04-22 | 하드웨어 스토어 - B2B 미끼로 사용될 가능성이 높음 | AS 13335 (클라우드플레어) |
| doccompartilhe[.]com | 2026-04-15 | 일반 - "문서 공유" | AS 13335 (클라우드플레어) |
| recebamais[.]com | 2026-04-20 | 스쿼팅 - 브라질 신용/대출 중개 | AS 13335 (클라우드플레어) |
더 많은 브라질 피싱 인프라가 배너 제목(Portal Corporativo) 이후 발견되었지만, 이것이 REF3076과 직접 관련이 있는지 아니면 라틴 아메리카 뱅킹 트로이 목마 생태계의 다른 행위자들과 관련이 있는지는 확실하지 않습니다. 특히 한 클러스터는 Cloudflare pages[.]dev 무료 정적 사이트 호스팅 제품을 활용했습니다.
C2 도메인 mxtestacionamentos[.]com 은 이전에 브라질에서 호스팅되는 IP 191.96.224[.]96 를 가리켰습니다.
작년에 이 IP는 REF3076 C2 도메인, REF3076 피싱 도메인, 그리고 이전에 트렌드마이크로()의 워터 사시 캠페인 및 SORVEPOTEL/MAVERICK 멀웨어와 연관된 도메인을 동시에 saogeraldoshiping[.]com 호스팅했습니다.
결론
TCLBANKER는 브라질 뱅킹 트로이목마 생태계 전반에서 일어나고 있는 광범위한 성숙을 반영합니다. 환경 기반 페이로드 복호화, 직접 시스콜 생성, 웹소켓을 통한 실시간 소셜 엔지니어링 오케스트레이션 등 한때 더 정교한 위협 행위자들의 특징이었던 기술들이 이제 일반 크라임웨어로 패키지화되고 있습니다. 특히 코드 생성을 위해 강력한 LLM에 쉽게 액세스할 수 있게 되면서 진입 장벽이 계속 낮아지고 있습니다.
자체 전파 웜 모듈이 포함된 것은 이 분야에서 주목할 만한 변화입니다. 이 캠페인은 피해자의 WhatsApp 세션과 Outlook 계정을 탈취하여 합법적인 커뮤니케이션의 신뢰와 전달력을 이어받습니다. 이는 기존의 이메일 게이트웨이와 평판 기반 방어 시스템으로는 포착할 수 없는 배포 모델입니다. 라틴 아메리카 뱅킹 트로이목마가 이러한 자체 확산 메커니즘을 계속 채택함에 따라 조직은 이러한 캠페인의 규모와 범위가 그에 따라 확장될 것으로 예상해야 합니다.
디버그 로깅 경로, 테스트 프로세스 이름, 아직 구축 중인 피싱 사이트 등 체인 전반에 걸친 개발자 아티팩트를 통해 REF3076이 초기 운영 단계에 있음을 알 수 있습니다. 이 캠페인은 종료된 것이 아니라 여전히 진행 중인 캠페인입니다.
REF3076을 통해 MITRE ATT&CK
Elastic은 위협이 엔터프라이즈 네트워크에 대해 사용하는 일반적인 전술, 기술 및 절차를 문서화하기 위해 MITRE ATT& CK 프레임워크를 사용합니다.
전술
전술은 기술 또는 하위 기술의 이유를 나타냅니다. 이는 적의 전술적 목표, 즉 행동을 수행하는 이유입니다.
기술
기술은 공격자가 행동을 수행하여 전술적 목표를 달성하는 방법을 나타냅니다.
- Phishing: Spearphishing Attachment
- 시스템 바이너리 프록시 실행: Msiexec
- 하이재킹 실행 흐름: DLL 사이드 로딩
- 명령 및 스크립팅 인터프리터: PowerShell
- 명령 및 스크립팅 인터프리터: Windows 명령 셸
- 예약된 작업/작업: 예약된 작업
- Deobfuscate/Decode Files or Information
- 난독화된 파일 또는 정보
- 디버거 회피
- 가상화/샌드박스 회피: 시스템 검사
- 가상화/샌드박스 회피: 시간 기반 회피
- 방어력 약화: 도구 비활성화 또는 수정
- Native API
- 프로세스 인젝션
- 프로세스 검색
- 애플리케이션 창 검색
- 시스템 정보 검색
- System Location Discovery: System Language Discovery
- 화면 캡처
- 입력 캡처: 키 로깅
- 클립보드 데이터
- 입력 캡처: 웹 포털 캡처
- 브라우저 세션 하이재킹
- 애플리케이션 계층 프로토콜: 웹 프로토콜
- 웹 서비스
- 인그레스 도구 전송
- 이메일 수집: 로컬 이메일 수집
- 시스템 종료/재부팅
REF3076 수정
예방
- 서명되지 않은 DLL을 통한 NTDLL 메모리 보호 변경
- 두 번째로 로드된 NTDLL 라이브러리
- 잠재적 NTDLL 메모리 언훅 가능성
- Parallel NTDLL Loaded from Unbacked Memory
- 의심스러운 Windows 코어 모듈 변경
- 백업되지 않은 메모리를 통한 AMSI 바이패스
- SetThreadContext를 통한 잠재적 AMSI 바이패스
YARA
Elastic Security는 이 활동을 식별하기 위해 YARA 규칙을 만들었습니다.
관찰
이 연구에서는 다음과 같은 관찰 가능성에 대해 논의했습니다.
| 관측 가능합니다. | 유형 | 이름 | 참조 |
|---|---|---|---|
| 701d51b7be8b034c860bf97847bd59a87dca8481c4625328813746964995b626 | SHA-256 | screen_retriever_plugin.dll | TCLBanker 로더 컴포넌트 |
| 8a174aa70a4396547045aef6c69eb0259bae1706880f4375af71085eeb537059 | SHA-256 | screen_retriever_plugin.dll | TCLBanker 로더 컴포넌트 |
| 668f932433a24bbae89d60b24eee4a24808fc741f62c5a3043bb7c9152342f40 | SHA-256 | screen_retriever_plugin.dll | TCLBanker 로더 컴포넌트 |
| 63beb7372098c03baab77e0dfc8e5dca5e0a7420f382708a4df79bed2d900394 | SHA-256 | XXL_21042026-181516.zip | TCLBanker 초기 ZIP 파일 |
| campanha1-api.ef971a42[.]workers.dev | 도메인 이름 | TCLBanker C2 | |
| mxtestacionamentos[.]com | 도메인 이름 | TCLBanker C2 | |
| documents.ef971a42.workers[.]dev | 도메인 이름 | TCLBanker 파일 서버 | |
| arquivos-omie[.]com | 도메인 이름 | TCLBanker 피싱 페이지(개발 중) | |
| documentos-online[.]com | 도메인 이름 | TCLBanker 피싱 페이지(개발 중) | |
| afonsoferragista[.]com | 도메인 이름 | TCLBanker 피싱 페이지(개발 중) | |
| doccompartilhe[.]com | 도메인 이름 | TCLBanker 피싱 페이지(개발 중) | |
| recebamais[.]com | 도메인 이름 | TCLBanker 피싱 페이지(개발 중) |