
1. 为什么内网横向移动绕不开PsExec先说个多数人都有过的困惑辛辛苦苦拿下一台服务器权限以为万事大吉结果发现这只是整个内网渗透的起点。真正的目标是域控、数据库、核心业务系统而这些目标通常不会老老实实等着你一个个去攻破你需要一种能在一批机器上快速执行命令、上传工具、维持权限的方法。这时候PsExec基本是绕不开的选择。PsExec本身是微软Sysinternals工具集里的一个命令行工具官方定位是远程执行进程原本是给系统管理员批量管理服务器用的。它不需要在目标主机上预先安装客户端而是通过把服务二进制文件写入目标机的ADMIN$共享再通过服务控制管理器SCM远程创建并启动一个Windows服务从而获得一个System权限的交互式/非交互式shell。听起来是不是很眼熟对的这个机制本质上就是一套合法工具的远程命令执行通道。因为它走的是Windows原生的服务管理协议所以在真实内网环境中识别难度相对较高这也是红队、攻防演练、授权渗透测试中Psexec模式被大量使用的原因同时也是企业EDR、流量审计设备盯防的重点。如果说横向移动是一个工具箱那么PsExec就是其中最趁手、最常见的一把螺丝刀。它不像永恒之蓝那种漏洞利用一样依赖系统漏洞也不像远程桌面那样容易被发现只需要满足几个基础条件目标机器的445端口可访问、管理员凭据可用、ADMIN$共享存在且可写。这三个条件在内网默认配置下经常是天然满足的尤其是域环境里域管账户跑一遍一批机器就都能连上去。我个人的体感是凡是做过授权红队评估或攻防演练的朋友迟早都会跟PsExec打交道。不是因为它最隐蔽而是因为它最简单、最稳、最符合Windows管理员的操作习惯。这篇文章就把我从环境准备、工具部署、命令执行到踩坑排错、防御检测的完整经验整理一遍希望对正在做内网安全测试的同行有所帮助。需要提醒的是以下内容仅限于你在有明确授权的测试环境、靶场、实验环境中使用任何未经授权的操作都是违法的。2. 动手之前先要把横向移动的前提条件摸清楚PsExec看起来简单但它不是凭空就能用的。很多新手上来就敲命令结果报错一箩筐最后还以为是工具问题其实大多是前置条件没满足。我把常见的硬性条件拆成了四块每一块都值得你在实际操作前想清楚。2.1 当前主机的权限级别决定你的通行半径首先要明确一点横向移动不是任何权限都能做的操作它对当前已控主机的权限层次非常敏感。假如你当前只是在一台普通终端上拿到了一个普通域用户的权限那就算你知道域管的密码也无法直接用PsExec连接目标服务器——因为目标服务器会拒绝没有本机管理员权限的账户访问ADMIN$共享。在实际攻防中常见的最小可用权限是目标机器的本机管理员组成员或者是域管理员组中的账户。尤其要注意的是本地管理员账户和域管理员账户的效力范围不同。本地管理员只能横向到本机所属的那一台机器而域管账户则可以横向到域内所有加入域的机器前提是能定位到目标IP或主机名。还有一个细节经常被忽略UAC远程限制。从Windows Vista开始微软默认启用了一个叫做LocalAccountTokenFilterPolicy的机制它会使内置本地管理员账户比如Administrator在远程连接时被降权为高完整性级别以下的令牌导致明明拿到的管理员账户却在远程共享写入时有权限但用不了。如果你遇到这种情况别急着怀疑凭据先去确认目标机器是否修改过这个注册表键值。很多企业环境为了方便运维会把这个值设为1但也有些严格的安全基线会把它保持默认这就需要你在实战中判断和绕过。2.2 凭据类型密码和哈希都能当钥匙用PsExec官方参数里支持-u和-p来指定用户名和密码但在实际内网测试中我们手里经常拿到的不是明文密码而是一个NTLM哈希。这在域环境下尤其常见因为哈希传递Pass-the-Hash几乎是横向移动的标配技术。如果要直接用哈希完成PsExec连接普通的Sysinternals PsExec是不支持的需要借助其他封装工具比如Impacket里的psexec.py它支持在命令行里直接把哈希作为参数传进去。在Windows平台上也可以配合Mimikatz获取哈希后再通过sekurlsa::pth生成一个持票进程再用常规PsExec去连接目标这也是很多红队常用的一条链路。这里特别想强调一下**你拿到的密码哈希是NTLM哈希还是Kerberos票据决定了你的横向移动能不能走通。**Kerberos票据只对特定服务有效NTLM哈希则可以直接用于SMB认证而PsExec依赖的正是SMB和SCM的远程调用。所以在内网里抓哈希、复用哈希是比拿明文密码更常见的路径。2.3 目标可达性445端口和ADMIN$共享缺一不可PsExec的工作原理决定了它必须能访问目标机器的以下资源135端口用于远程RPC是SCM建立连接的基础。139/445端口用于SMB会话和共享访问。ADMIN$共享Windows默认开启的隐式共享必须有写权限才能将服务二进制落地。这三个条件通常是一体的。只要目标机开启默认共享且防火墙没有阻断相关端口连接就能建立。但在实际内网中防火墙策略经常是分段的比如财务网段和办公网段之间只开放特定端口。这时候直接横向走不通就得考虑先通过已控主机做端口转发或代理把流量送到目标网络后再尝试PsExec。我一般习惯在横向前先做一个快速的端口探测比如用Telnet或PowerShell测试目标机的445端口是否通同时用net view \\目标IP看看共享是否可列举。如果共享可枚举那大概率ADMIN$可用如果共享枚举失败但445通那就要进一步确认凭据和权限级别。2.4 杀软和基线策略是最大的隐形变量很多人在实验环境里跑通了PsExec就认为内网其他机器也能直接跑通这个想法在真实网络中非常危险。现在主流的企业杀软和EDR对PsExec的行为已经做了专门监控尤其是对Psexesvc.exe落地、服务创建、通过SCM启动服务这三个动作基本都有完整的行为检测规则。如果你在没有测试过目标环境安全基线的情况下直接上PsExec很容易触发告警导致横向移动失败甚至暴露当前立足点。所以我的建议是在横向移动之前先摸清楚目标主机的杀软类型和策略开放度。比如通过WMI查询已安装的安全产品或者通过进程列表观察是否有EDR的Agent进程。如果目标环境确实装了比较严的EDR就需要考虑换用其他横向移动方式比如计划任务、WMI执行或WinRM而不要跟EDR硬碰硬。3. PsExec从部署到命令执行的完整操作链路前面聊了那么多前提条件现在进正题。我把PsExec的完整操作链路拆成部署、命令执行、特殊玩法三个环节尽量还原实际操作中的细节和判断逻辑。3.1 工具准备Sysinternals原版还是Impacket封装关于PsExec工具的选择社区里常见的有几个版本各有优劣整理如下工具版本平台特点适合场景Sysinternals PsExec官方版Windows必须输密码或用已经持有凭据的进程容易被杀软标记内网本地操作顺手有微软签名Impacket psexec.pyLinux/跨平台支持明文密码和NTLM哈希直接传参无需上传二进制直接在内存中创建服务并执行命令从攻击机直接横向红队标配Metasploit psexec模块Windows/Linux集成在MSF框架支持自动选择payload可派生Meterpreter会话结合漏洞利用链和后续提权第三方封装PsExec变种Windows部分改写了服务名、文件名尝试规避杀软实战中改造使用但有风险日常测试中我最常用的是Impacket的psexec.py因为它的兼容性最好而且不用单独再传一份二进制到目标机上。它创建的服务默认名较固定很容易被检测但由于服务是动态创建的用完后会自动删除所以从隐蔽性上比原版PsExec更可控一些。需要注意Impacket依赖Python环境使用前要保证机器上有对应的第三方库比如impacket和pycryptodome。如果你不熟悉Python环境安装建议直接用Kali自带的Impacket或者单独用pip安装到虚拟环境里。3.2 最常用命令的参数拆解不管用哪个版本你都绕不开几个核心参数。以原版PsExec为例最常用的组合如下PsExec.exe \\192.168.10.50 -u domain\admin -p Pssw0rd -s cmd.exe这条命令的含义是用domain\admin账户连接192.168.10.50以System权限启动一个cmd.exe。各参数的实际作用\\目标IP或主机名必填指定远程机器。-u指定用于认证的用户名格式可以是域名\用户名也可以是IP\用户名本地账户。-p指定该用户的密码。-s以System权限启动远程进程不加这个参数时默认和登录用户权限一致。-c把本地文件复制到远程机器上再执行。-i以交互式方式启动进程如果不加则是无界面后台执行。-h使用高完整性级别令牌启动进程绕过部分UAC限制。-d不等待进程执行完成立即返回适合执行不需要同步结果的命令。Impacet版本的命令略有不同但思路是一样的python3 psexec.py domain/admin:Pssw0rd192.168.10.50如果是哈希传递把密码位置替换成NTLM哈希即可python3 psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:3166d0c6e9e6d0b1d0f1d0c0a0b1c2d3 domain/admin192.168.10.50使用哈希传递的时候注意哈希前面的LM哈希部分一般填32个0或者不填也行Impacket会自动处理。3.3 实际操作时的典型流程我在授权环境下通常会分为四个步骤来做避免手忙脚乱先用当前控制权限收集内网IP段并批量探测445端口开放情况。命令可以用crackmapexec smb 192.168.10.0/24快速枚举这个工具会同时输出SMB签名、主机名等信息非常高效。确认目标主机可达后先做一次轻量级验证。用net use \\192.168.10.50\ADMIN$ /user:domain\admin Pssw0rd测试管理员凭据是否对ADMIN$有访问权限。如果这条命令成功说明PsExec大概率能直接连上。执行PsExec命令。先跑一个简单命令验证连通性比如whoami或ipconfig。确认无异常后再执行需要后续利用的复杂命令或上传工具。操作完成后清理痕迹。关闭命令行窗口、确认服务已被删除同时用net use \\目标IP\ADMIN$ /delete断开连接。不要小看这一步很多日志告警都是因为残留连接或服务未删除导致暴露的。3.4 在内存中执行命令不落地文件的PsExec变体常规PsExec需要在目标机上写入一个PSEXESVC.exe文件这个行为在防御视角里是非常突兀的。所以实战中一个更有价值的技巧是用服务控制管理器直接在内存态执行命令。具体思路是利用SCM的CreateService和StartService接口将命令字符串写入服务路径然后在远程主机上以服务方式启动。Impacket的psexec.py内部就是类似原理并没有真正往磁盘写PsExec的二进制而是创建了一个服务指向系统目录下的可执行文件然后通过标准输入输出去交互。如果你需要在Windows本机操作可以用sc命令配合远程注册表来实现一个不落地版本sc \\192.168.10.50 create TempService binPath cmd.exe /c whoami C:\Windows\Temp\result.txt type share start demand sc \\192.168.10.50 start TempService这种方式的优点是临时服务名可以自己定义不容易被特征匹配到PsExec缺点是不会自动清理服务需要手动删除。另外binPath参数里如果带空格或特殊符号需要特别注意引号和转义否则服务创建会失败。4. PsExec实践中最容易踩的坑我一个个说给你听这部分是我最想写的。网上教程千篇一律讲完命令就完事但真实环境中藏着大量实验环境跑不通的细节问题。我把自己和身边同事踩过的坑整理成几个典型场景供你参考。4.1 ADMIN$共享被手工关闭或权限被收紧很多安全基线会把默认共享关闭或者限制某个账户对ADMIN$的访问。这种情况下PsExec会报出Access is denied或找不到网络路径。解决办法不是硬刚共享而是改用WMI或计划任务来远程执行命令。WMI的Win32_Process.Create方法可以远程创建进程不需要ADMIN$共享只需保证135端口可达且账户有远程WMI权限。计划任务则通过schtasks /s 目标IP来创建远程任务同样不依赖ADMIN$。这两招可以在不改变PsExec原方案的前提下把你手上已有的管理员凭据转化为命令执行能力。我实际测试下来如果目标主机开启了Windows防火墙那么用计划任务的成功率会比WMI高一些因为计划任务组件在防火墙默认规则里通常是允许的。但这不代表WMI不可用只是需要额外放行相关端口。4.2 防火墙策略挡掉了SMB连接内网防火墙规则五花八门最常见的是阻断135、139、445端口但放行443和80。遇到这种环境强行启用PsExec没有意义应该先评估是不是有Web服务的机器是否可以利用IIS、Tomcat等应用漏洞进行横向。如果非得用PsExec可以考虑通过在已控主机上做端口转发来实现。比如用netsh的portproxy把目标机的445端口转发到当前已控主机的某个非标准端口再在攻击机上连接该端口。但这种方式要求已控主机的445端口本身没有被阻断否则转发链路建立不起来。所以遇到这种场景时我一般会直接用SMB over HTTP即通过WebDAV或者IIS虚拟目录来传递命令和工具而不是死磕445端口。4.3 目标机器的杀软把服务创建动作拦了杀软对PsExec的检测已经非常成熟尤其是在服务创建这个环节。即使你用的是Impacket版本很多EDR也能通过消费SCM的事件日志特征识别出异常服务启动行为。我遇到的一次实际场景是目标机器装了某国产终端管控软件PsExec命令一执行服务刚创建出来就被隔离远程连接的输入输出全部卡死。后来发现这台机器对创建服务并启动的动作有全局告警策略唯一能绕过的方式就是改用计划任务或WMI来执行命令虽然功能上比PsExec弱一些但胜在能落地。所以实战中不要把自己绑定在单一工具上。横向移动是一个工具箱思维的活PsExec是首选之一但不是唯一。多准备几套备用方案才是老手的习惯。4.4 UAC远程限制导致有管理员密码却连不上前面提过的本地账户远程UAC降权问题这里详细展开一下。默认情况下Windows对本地管理员账户的远程连接做了令牌过滤即使你输入的是Administrator密码远程端获得的令牌仍然是标准用户权限。这会直接导致PsExec在尝试访问ADMIN$时被拒绝。解决办法有两个在目标机器上修改注册表将HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System下的LocalAccountTokenFilterPolicy设为1然后重启或等待策略生效。这个办法在你有交互式会话或者能通过其他方式修改注册表时适用适合在测试环境中提前把靶机配好。使用域管理员账户连接而不是本地管理员。域管理员的令牌默认是完整管理员权限不经过UAC远程限制过滤。这也是为什么内网渗透中大家极力追求域管权限的原因之一——域管几乎可以在域内所有机器上直接横向不需要理会这些细碎的坑。4.5 PsExec执行后没有回显或命令卡死如果你用原版PsExec运行命令时出现长时间无回显最常见的原因是杀软拦截了PSEXESVC的进程注入或者目标机器的别名解析出现问题。可以尝试改用IP地址而不是主机名来连接同时检查本地hosts文件是否有残留解析条目。另一个常见情况是执行了带GUI的程序比如calc.exe、mspaint.exe在非交互式会话里这些程序不会弹窗看起来就像卡住了。此时进程其实是启动了只是没有界面。你只需要用任务列表确认进程存在即可不要在命令行上死等回显。4.6 凭据里有特殊字符导致命令解析错乱密码里带、:、!等特殊字符时Impacket的命令行解析经常出问题。比如密码是Pssw0rd:123在python3 psexec.py domain/admin:Pssw0rd:123192.168.10.50这种写法下Impacket会把冒号当作分隔符截断。遇到这种情况最简单的解决方法是把密码写进一个环境变量或者使用-hashes直接传哈希避免密码中的特殊字符影响解析。这个方法我用了很多次尤其在Windows本地运行的PsExec中密码带#等字符还会被PowerShell当作注释符号必须用单引号显式包裹才能正常传递。5. 从蓝队视角看PsExec横向移动检测、运维与防御实践一个工具如果能被红队用好那它也一定能被蓝队用来做检测和加固。我接触过不少安全运维的朋友他们对PsExec的认知停留在这是微软官方的运维工具这个层面完全不知道它已经是横向移动的经典套路。这一节我就站在检测和防御的角度聊聊如何发现PsExec横向移动行为以及如何提前堵住这个口子。5.1 服务创建与事件日志中的关键特征PsExec横向移动过程中最核心的行为是远程创建服务并在目标机器上启动。这个行为在Windows事件日志中会留下非常明显的痕迹System日志的7045事件当新服务被创建时系统会记录服务名称、服务二进制路径等信息。常见的PsExec服务名是PSEXESVC但实战中攻击者可能自定义服务名所以不能只看名字还要看二进制路径和创建行为是否异常。Security日志的4624事件登录类型3远程网络登录结合目标机器的管理员账户登录记录可以辅助判断是否存在异常的批量横向登录。Security日志的5140事件访问共享对象会记录访问的共享路径和账户。如果短时间内大量出现针对ADMIN$共享的访问记录基本可以判定是横向移动扫描或批量连接。Sysmon系统监视器能提供更细粒度的检测能力。重点关注Sysmon事件ID1进程创建和事件ID13注册表项变化。PsExec运行后目标机器上会出现PSEXESVC.exe的服务进程它的父进程是services.exe这个父进程关系本身就是异常信号。另外服务二进制通常存放在C:\Windows\PSEXESVC.exe这个路径也是高价值检测特征。5.2 流量侧的SMB行为检测提到流量检测很多人第一反应是看445端口的异常连接。实际上PsExec横向移动在不落地文件的情况下比如Impacket版本SMB流量中的命令执行模式依然有迹可循。正常的SMB管理操作一般是对文件进行读写而PsExec横向移动会在短时间内出现大量SMB2_CREATE和SMB2_WRITE请求目的是将服务二进制或命令写入ADMIN$共享随后会出现Svcctl远程调用。如果NTAF网络流量分析设备能看到SMB会话内容可以通过检测Pipe\svcctl管道名称来识别PsExec的特定通信。当然这些检测特征在复杂的网络环境中会有误报特别是企业里大量使用自动化运维工具时类似行为也是正常的。所以企业在建设检测规则时最好结合多个维度的数据日志流量进程行为来交叉验证而不是只靠单一特征就封禁。5.3 收窄防护面这些配置改动值得做从防御端来看我建议优先做以下几件事关闭不必要的ADMIN$默认共享。虽然很多运维场景需要管理共享但对于非域控的终端和服务器可以关闭并禁止默认共享。如果确实需要远程管理用WinRM或者RDP加堡垒机来处理。限制本地管理员组成员。很多横向移动的源头都是某台终端的管理员组被过度授权。定期审计Administrators组成员把不必要的账户移除能显著减少横向移动的攻击面。部署Sysmon并自定义告警规则。Sysmon的进程创建和服务创建事件对检测PsExec非常有效建议配合SIEM平台做告警。启用Windows Defender Credential Guard。这个功能可以把NTLM哈希和Kerberos票据保护在虚拟化安全域中即使攻击者拿到管理员权限抓取哈希的难度也会大幅提升。分段网络与访问控制。内网不要做成一马平川的扁平网络按业务和信任级别分段对445端口做精细化放行策略。横向移动本质上是建立在内网互信基础上的网络分段越细攻击者横向到关键目标需要跨越的信任层就越多。5.4 攻防视角下的猫鼠游戏最后聊点宏观的。PsExec本身是个老掉牙的技术为什么到现在还被频繁提及因为它打的不是漏洞而是信任链。管理员群体信任命令行工具、信任Windows服务机制、信任内网网络环境攻击者只是把这种信任转化成行动手段而已。从攻防对抗的角度来说防守方真正要防的不是某一个工具而是攻击者是否能在内网轻松获得多个机器的管理员权限并批量执行命令这个能力。当你把这个能力链条斩断——比如限制管理员权限、隔离网络、监控服务创建行为——就算攻击者继续用PsExec也会寸步难行。我自己在做攻防演练时经常能看到防守方只在边界防线上投入大量精力却对内网的服务创建、共享访问、计划任务这些安静的行为缺乏感知。等攻击者已经横向到三四台机器了才在日志里发现第一处异常。这种局面不是靠某一款产品能解决的而是要建立一套覆盖日志、流量、行为的纵深观测体系。6. 经验沉淀我在实战中反复用到的几个技巧内容快结束了再分享几个压箱底的小技巧都是实际操作中被验证过很多次的。第一尽量用IP直连而不是主机名。内网DNS经常有解析偏差或者宿主机名与实际IP不一致的问题用IP直连能省掉一批莫名其妙的找不到网络路径报错。如果必须用主机名先去DNS确认一遍解析结果。第二连接前先用net use做一次静默验证。这条命令能快速告诉你凭据是否有效、ADMIN$是否可访问而且不会产生服务创建等高危告警。如果net use通了PsExec本身基本不会有大问题。第三操作前想好清理方案。不管是原版PsExec还是Impacket命令执行完都可能有残留。服务会自动删除还好但底层SMB连接需要手动断开避免把后门暴露在目标的netstat或日志中。第四把PsExec和计划任务配合使用。当PsExec因杀软或权限问题失败时任务计划往往能补位。比如你可以先用PsExec创建服务再用计划任务启动另一个命令这样即使PsExec的服务被查杀计划任务里的命令也已经种下了。当然这种连环操作要在授权范围内谨慎使用。最后想说的是横向移动技术本身没有黑白之分关键看使用者的意图和边界。如果你是在做合法授权范围内的渗透测试、红队评估或安全研究那PsExec绝对值得反复研究如果你只是在网络上看了几篇文章就想对别人的系统试手那还是趁早打消这个念头。干安全这行技术可以慢慢练边界感必须一直在线。