PsExec分析
在完成外网打点进入内网环境后,PsExec必定是我们最常用的横向移动工具之一。本文将对impacket中实现的PsExec原理进行分析。
我们在使用PsExec的过程中,通过打印的日志,可以看到会首先访问目标主机的远程管理共享“ADMIN$”,随后上传了一个随机文件名可执行程序,在这之后创建了随机名的服务并启动,然后我们就获得了一个交互式的shell,因为PsExec是服务启动的所以我们获得的都是高权限的shell。
那么它是如何实现上传文件并且远程创建服务的呢???
实际上微软为了用户方便远程管理计算机,默认会开启Windows以下远程共享。
1. 磁盘盘符
2. IPC$-远程IPC(用于命名管道)
3. ADMIN$-远程管理(映射为C:/windows/目录)
这里我们再通过抓取数据包来了解下具体的实现过程。可以看到整个与远程主机交互的过程都是基于SMB协议的,在完成协商身份认证后,会去连接远程主机的IPC$管道。
在这之后会操作“svcctl”和“svrsvc”句柄;svcctl用于远程服务控制管理(Service Control Manager)接口进行通讯,通过RPC调用可以让我们实现远程管理目标主机中的服务。
svrsvc与远程服务器服务(Server Service Remote)进行通讯,用来枚举目标主机开放的共享。
在找到可写入的共享后调用NT_CREATE_ANDX写入文件。
impacket中nt_create_andx实现。
这里上传的exe文件实际上是https://github.com/kavika13/RemCom。它被硬编码到了remcomsvc.py里。
在完成文件上传之后依次使用OpenSCManagerW、OpenServicceW、StartServiceW方法来创建启动服务。
随后通过对RemCom_stdout、RemCom_stdin、RemCom_stderr管道的读写来实现交互式命令执行。这里的管道名虽然会被拼接随机数但仍然是写死的,可以作为特征监测。
服务端的工作原理通过前面的描述大概也能猜个八九不离十,既然是通过命名管道进行交互,那么服务端启动后必定会创建管道。
这里会首先创建RemCom_communication管道并进行阻塞,等待客户端连接下发命令。
在接收到命令后,调用CreateProcess 创建进程同时创建管道并进行重定向。
这样一来就可以实现命令行交互了。
由于PsExec.py使用的是硬编码的RemComSvc因此在默认情况下必定会被杀软拦截。
PsExec.py中也提供了-file参数,用来指定一个RemComSvc客户端,
我们对程序源码以及py中涉及的管道名进行修改,重新编译后可以成功绕过某数字和Defender。
PsExec在执行过程中除了会产生用户登录成功的日志外,会产生7045(服务安装)、7036(服务启动)的日志ID,可以很明显的看到所涉及的服务名称以及对应的服务程序。
当然也可检查默认的管道名来确认是否正在被X。
https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SCMR/%5bMS-SCMR%5d.pdf
https://github.com/kavika13/RemCom
https://github.com/SecureAuthCorp/impacket
原文始发于微信公众号(云黑客):PsExec分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论