首页
社区
课程
招聘
[翻译]PsExec的消亡
发表于: 2018-7-5 08:18 2961

[翻译]PsExec的消亡

2018-7-5 08:18
2961
原文: https://mkellerman.github.io/Death_to_psexec/

正如之前博客中提到的,我决定写一下让我决定放弃PsExec(https://docs.microsoft.com/en-us/sysinternals/downloads/psexe)的过程。

为什么...PsExec怎么了?

通常,我们在测试环境中使用PsExec执行远程NUnit测试。大多数时候它工作正常,但当出现网络中断或其它连接问题时,与测试机的连接会话会崩溃,但是测试进程仍然在远程机器上运行。这时,你就需要实现大量的错误处理来在离线时重连来继续工作或获得测试结果...这只是其中一个噩梦。

为什么不用PowerShel远程会话?

你听说过Double-Hop问题么?Ashley McGlone有一个很好的文章(https://blogs.technet.microsoft.com/ashleymcglone/2016/08/30/powershell-remoting-kerberos-double-hop-solved-securely/)解释这个问题并提供了很多解决办法。

为什么不采用其中的一个解决办法?

很简单,我想将脚本指向一个IP地址,使它神奇地运行起来。我不想安装AD环境或者在远程环境中配置任何东西。

Marc...你真事多

我想简单地通过多次使用Invoke-Command命令来实现,同时增加一个-As $Credential参数为在远程机器上执行的<ScriptBlock>提供<PSCredential>,并且还能享有PowerShell远程会话在连接方面的优点。
我希望的命令类似如下形式:
Invoke-CommandAs -Session <Session> -ScriptBlock <ScriptBlock> -As <PSCredential>
在执行该命令前,需要首先先做一些准备工作(与远程机器建立PowerShell远程会话,以不同证书执行一个进程,并获得一个powershell对象)?
应当更加简单。。。

需要以不同证书执行进程?小事一桩

我想通过多次使用RunAs.exe,实现在一个证书集合中以不同证书启动powershell进程。但是我无法远程启动RunAs.exe并提供证书。

Invoke-CmdAs

我的一个同事发现一个项目(Jetbrains/runAs,https://github.com/JetBrains/runAs),它多次使用RunAs,并且准许在命令行里指定证书。详细看我的封装:https://github.com/mkellerman/PSRunAs/blob/master/Invoke-CmdAs/Invoke-ExpressionAs.ps1。
直接复制代码非常不优雅。

Invoke-RunAs

之后我发现Ruben Boonen(@FuzzySec)的Invoke-RunAs,使用Add-Type加载DLL并调用'Advapi32::CreateProcessWithLogonW',这和RunAs.exe的做法一样。详情看我的封装:https://github.com/mkellerman/PSRunAs/tree/master/Invoke-RunAs

Start-ProcessAsUser

同样,Lee Christensen (@tifkin_)修改过的Matthew Graeber (@mattifestation)的Start-ProcessAsUser使用反射来加载DLL并调用‘Advapi32::CreateProcessWithLogonW’,和RunAs.exe的方法一样。详情见我的封装:
https://github.com/mkellerman/PSRunAs/tree/master/Start-ProcessAsUser
这些实现都需要其它代码返回一个PowerShell对象。

Invoke-ScheduledTask

此外,一个经常被讨论的方法是在远程机器创建一个任务调度,并以system权限(或者其它被支持的证书)执行你的进程。这很简单,深入研究发现它创建了一个Scheduled Job,并且你可以接收JOB的结果并作为一个PowerShell对象。
所以我创建了一个Invoke-ScheduleTask命令来简化这个过程,并创建了一个封装实现上面的过程:
https://github.com/mkellerman/PSRunAs/blob/master/Invoke-ScheduledJob/

越简单越好

尝试过所有这些方法之后,我决定引入Invoke-ScheduleJob到我最后的解决方案中,它返回原生的PowerShell对象且不破坏任何输出流。详情看:https://github.com/mkellerman/Invoke-CommandAs

它也在PowerShell Gallery中。
# Install Module
Install-Module -Name Invoke-CommandAs

# Execute Locally.
Invoke-CommandAs -ScriptBlock { Get-Process }

# Execute As different Credentials.
Invoke-CommandAs -ScriptBlock { Get-Process } -As $Credential

# Execute Remotely using ComputerName/Credential.
Invoke-CommandAs -ComputerName 'VM01' -Credential $Credential -ScriptBlock { Get-Process }

# Execute Remotely using PSSession.
Invoke-CommandAs -Session $PSSession -ScriptBlock { Get-Process }

# Execute Remotely on multiple Computers at the same time.
Invoke-CommandAs -ComputerName 'VM01', 'VM02' -Credential $Credential -ScriptBlock { Get-Process }

# Execute Remotely as Job.
Invoke-CommandAs -Session $PSSession -ScriptBlock { Get-Process } -AsJob
我确定有很多其它方法实现这个,或者在某些情况下一个解决方案会比其它的都好,我很期望知道它们。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//