【问题标题】:Executing an HTA Application via PSEXEC with command line arguments使用命令行参数通过 PSEXEC 执行 HTA 应用程序
【发布时间】:2019-09-17 16:21:19
【问题描述】:

我有一个.hta 应用程序,它接受两个命令行参数。通过命令行在远程机器上执行应用程序的工作方式如下

(命令行 - cmd)示例:

C:\Users\<user>\Desktop>MSI-BUILDER.hta "MSI_APP" "D:\APP\15.9.98"

但是当使用我的桌面尝试通过 PSEXEC 在远程计算机上执行相同的命令时,我看到应用程序在任务管理器中运行,但没有任何反应。

第一步是将命令行参数分配给 PowerShell 中的变量:

$arg1 = "MSI_APP"
$arg2 = "D:\APP\15.9.98"

在 PowerShell 中执行此命令失败(没有错误,只是挂起):

.\psexec -s -i \\Srv2012 cmd /c "start /i "MSI-BUILDER" "C:\Users\<user>\Desktop\MSI-BUILDER.hta" $arg1 $arg2"

应用程序仅在任务管理器中启动,我假设在后台,但我没有看到任何更改,所以它可能只是挂起......

我不是 100% 确定我在这件事上的语法对于通过带有命令行参数的 powershell 启动 HTA 是否正确。

还有一种方法或开关可以让我真正看到应用程序启动并在远程执行代码后执行它的操作,以进行测试?

【问题讨论】:

  • “有没有一种方法或开关,我可以在远程执行代码后实际看到应用程序启动并执行它的操作” - 不。远程执行的应用程序对交互式用户的 GUI 不可见一台远程机器。这是出于安全原因而设计的。
  • @Bill_Stewart:psexec 可以在本地登录用户的桌面会话中以可见方式远程启动应用程序,即通过-i 选项 - 请参阅the docs
  • 打开命令提示符窗口并输入start /?cmd /? 以了解这些特定命令的工作原理。你会注意到start 命令需要一个标题,一个空的就可以了,start "" ...,你还会在cmd /? 下看到一个部分,它解释了它如何使用/C 处理双引号。但是,您根本不需要通过 cmd.exe 运行 HTML 应用程序或使用其内部的 start 命令。
  • @mklement0 感谢您的通知。它可以这样做是因为它在远程机器上安装了一项服务,然后在控制台(或指定的)会话中调用可执行文件。

标签: powershell cmd hta psexec


【解决方案1】:

*.hta 文件的调用可以被简化,通过将其路径和参数直接传递给mshta.exe(这也可以防止控制台窗口短暂出现如果你通过cmd/ c启动):

# From PowerShell (-accepteula omitted for brevity)
# IMPORTANT: You must use the *.hta file's FULL PATH.
.\psexec \\SERVER -i -s mshta.exe "D:\path\toapp\app.hta" $arg1 $arg2

默认情况下,psexec同步运行,即直到远程进程退出才返回,如果您需要想知道进程的退出代码[1]

在你的情况下,进程不会退出 直到 HTA 应用程序窗口关闭,所以我假设你的 在使用命令行参数调用时自动关闭 - 如果它没有,psexec 不会返回,直到交互式用户在使用-i 调用时关闭窗口,或者没有-i 时根本不会返回。

如果您需要异步执行,请使用-d选项;这使得psexec 在成功启动目标进程后返回,而无需等待它退出。由于您因此无法知道启动进程的真正 exit 代码,因此psexec 将告诉您的只是该进程是否可以创建

警告:使用-s(即NT AUTHORITY\SYSTEM 帐户)以交互方式 (-i) 运行存在安全风险 - 见下一节。

但是,通过正确引用您的原始尝试也可以进行 - 请参阅底部部分。


至于:

还有什么方法或开关可以让我真正看到应用程序启动吗?

psexec-i 选项使指定的命令在远程目标机器上以可视方式、交互方式运行在任何用户碰巧以交互方式登录的会话中[2]

用户身份而言,psexec 通常允许您以如下方式启动命令:

  • 任一个:SYSTEM 帐户 (NT AUTHORITY\SYSTEM) 带有选项 -s建议使用 -i ,但是:

    • NT AUTHORITY\SYSTEM 是一个代表本地计算机的高度特权帐户,因此在用户可以交互控制的应用程序中使用它存在安全风险.
  • 或:一个给定的固定用户,带有选项-u(和-p;参见下面的示例)

请注意,不能使用-i 做的是自动以任何用户的身份运行登录到目标计算机上的交互式会话,因为从安全角度来看,这将是一个很大的问题。但是,显式使用-u 和当前交互用户(如果已知)的凭据相同。

更多信息请参见the documentation

使用-i,最好使用只有所需的最低权限集应用程序才能运行的帐户;然后,您将使用-u(用户名)和-p(密码)参数,而不是-s;例如:

# From PowerShell
.\psexec \\SERVER -i -u user1 -p passwd1 mshta.exe "D:\path\toapp\app.hta" $arg1 $arg2

至于你尝试了什么(在你的问题中):

如果您解决了引用问题,您的原始命令可能会起作用:

.\psexec \\Srv2012 -s -i cmd /c start /i `"MSI-BUILDER`" "C:\Users\<user>\Desktop\MSI-BUILDER.hta" $arg1 $arg2

为避免 嵌套 引用出现问题,已省略传递给 cmd /c 的命令周围的外部引用。

注意" 字符的方式。包含MSI-BUILDER 必须(不幸的是)转义为`",以便确保 PowerShell 将它们传递给psexec,最终传递给cmd /c

  • PowerShell 在后台使用按需双引号 策略,因此即使您最初指定 带有引号的参数也以not 双引号,如果参数值不包含空格[3] - 因此,您的 "MSI-BUILDER" 参数最终会被传递为 MSI-BUILDER - 没有双引号 - 到psexec

  • 不幸的是,cmd-internal start 命令有一个笨拙的语法:它总是需要将作为 窗口标题的参数括起来在命令行上的"..." 中,即使标题是一个单词(例如您的情况下的MSI-BUILDER)。

  • 因此,在这种特殊的边缘情况下,start 的 window-title 参数周围的 " 必须转义为 `" 以确保它们被保留。

不过,如上所示,有一种更简单的方法可以调用您的 *.hta(不需要中间的 cmd.exe 进程)。

顺便说一句:start 命令是多余的,为启动*.hta GUI 的临时窗口设置一个标题 是没有意义的,因为该窗口只会闪烁一瞬间。


[1] 请注意,HTA 应用程序不支持显式设置退出代码,除非您使用 an elaborate workaround。没有它,退出代码将始终为0 - 除非mshta.exe 进程崩溃

[2] psexec 能够做到这一点可能令人惊讶;它可能是通过以下巧妙的技术实现的:psexec 连接到目标机器的$ADMIN 共享(通常为C:\Windows),暂时在其自己的可执行映像中提取服务可执行文件(@987654382 @) 到该位置,并在目标计算机上将该可执行文件作为本地服务 (PSEXESVC) 启动。正是此服务在调用时启动传递给psexec 的命令,在当前用户的会话(可见窗口站)中可选(-i)。源机器上的调用 psexec 实例通过命名管道 (psexecsvc) 与服务通信,这使调用机器能够接收远程进程的 控制台输出 如果 -i 指定;在命令完成时(或者,使用-d(不要等待)选项,在成功启动命令时),服务停止并且服务可执行文件被删除 em> - 请参阅this article 了解更多信息。

[3] 还有其他与" 字符相关的复杂标准。 嵌入值中。

【讨论】:

    【解决方案2】:

    好吧,经过几个小时的尝试不同的事情,这是对我有用的命令

    编辑命令:

    .\PSEXEC -accepteula -s -i 2 \\SERVER cmd /c "D:\path\toapp\app.hta" $arg1 $arg2 -u username -p password
    
    

    【讨论】:

    • 我认为您的意思是-i 而不是-h-s 基本上暗示了这一点);请注意使用-s 运行interactive 程序的安全隐患;通过使用cmd /c,首先会在目标机器上短暂出现一个控制台窗口。
    • 感谢更新。 -i 没有会话 ID 参数 很聪明,会自动选择目标机器上当前的交互式会话(名为 console 的会话)。使用诸如2 之类的会话ID 可能会根据情况起作用,但ID 会根据谁先登录而有所不同。
    • 另外,使用 both -s-u + -p 是矛盾的;虽然psexec 悄悄地接受了这个组合,但不管参数顺序如何,都是-s 生效。
    • @mklement0 不幸的是,这是我使用mshta.exe 的原始方向,但应用程序会挂起并且永远不会从PowerShell 返回代码,我需要继续使用cmd 处理我的函数我得到一个cmd exited on Srv2012 with error code 0.我可以返回到我的 php 脚本。这绰绰有余
    • -d 只是启动应用程序并成功返回,而不管最终结果如何,至于 cmd /c 它启动一个窗口,等待应用程序关闭然后关闭自身返回真正的成功响应。
    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    相关资源
    最近更新 更多