☰
Windows服务器安全排查实战:从进程到日志的入侵溯源链路
2026/9/30 4:36:57 网站建设 项目流程

前几课讲了网络基础,这课把Windows系统安全排查单独拎出来说。很多同学遇到Windows服务器疑似中毒,第一反应是装个杀毒软件全盘扫描,或者干脆直接重装系统。但真实场景里,客户不会给你重装的机会——数据、业务连续性、合规审计全绑在同一台机器上,你多待的每一分钟都可能决定这个隐患是被彻底拔掉,还是仅仅被掩盖。

这课我会按照一套可复现的排查链路来讲:从思路准备、账户层、运行态(进程/网络/服务)、安全日志、持久化机制到文件痕迹,最后用一个完整场景把整个流程串起来。内容偏向Windows Server和Win10/11,所有命令都在原生命令行或PowerShell里执行,不需要额外装工具,保证你在现场也能用。

1. 排查前的思路准备:先假设被入侵,再寻找证据

1.1 为什么不能一上来就杀毒

我见过太多“排查”变“破坏”的案例:管理员发现服务器异常,直接打开杀毒软件一键清毒,病毒确实删了,但攻击者用来建立持久化的计划任务、注册表项、账户还在,第二天病毒又被下载回来,或者核心业务因为杀毒误删直接宕机。

安全排查的本质是取证,不是清理。你首先要回答三个问题:攻击者是怎么进来的?他做了什么?现在还在不在?第三个问题答案决定你能不能重启、能不能动文件、能不能删进程。如果连“还在不在”都没搞清楚就动手,那你只是在帮攻击者清理痕迹。

正确的做法是先把机器隔离——拔网线、在云控制台配置安全组只允许管理IP访问,然后保持系统当前运行状态,开始逐层收集证据。整个过程里任何修改系统的操作都要先记录下来,包括你执行过的命令、改过的东西、看到的时间点。

1.2 攻击者动作链与逆向排查法

Windows服务器被攻破,绝大多数遵循一个固定链路:

  1. 获取初始访问权:弱口令、RDP爆破、Web漏洞、未修复的漏洞。
  2. 建立持久化:计划任务、注册表Run键、服务、WMI事件订阅,保证你重启后他还能回来。
  3. 提权与横向:拿到System权限,或者通过内网跳板机打其他机器。
  4. 窃取或破坏:传回重要文件、加密勒索、部署挖矿程序。

我们要做的排查,就是沿着这条链路逆向走:先找持久化(因为攻击者一定会留后门,这是最清晰的线索),再找当前还在运行的异常进程和网络连接,然后翻日志还原入口,最后回到文件系统找证据。

所以本节先定了整个排查顺序:隔离 -> 账户 -> 运行态(进程/网络/服务) -> 安全日志 -> 自启动与计划任务 -> 文件痕迹。后面全部章节按这个顺序展开。

1.3 证据保全的几个习惯

开始动手之前,先花5分钟做三件事:

# 记录当前时间和系统运行时长 systeminfo | findstr /i "系统启动时间 系统时间" # 导出进程、服务、网络连接全量快照 tasklist /v /fo csv > C:\evidence\tasklist_before.csv sc query type= service state= all > C:\evidence\services_before.txt netstat -ano > C:\evidence\netstat_before.txt

然后把这个C:\evidence目录告诉任何人都别乱动。这份快照是后续对比的基线,尤其是对比“现在”和“你排查后”的状态——如果排查过程中某个进程突然消失或者某个端口突然关闭,那本身就是重要信号。

2. 账户层排查:入口和隐藏后门的第一站

2.1 先看一眼系统里有哪些账户

账户是Windows认证体系的基石,攻击者拿到初始访问权之后,最直接的动作就是创建一个新账户留后门,或者把已有账户加入管理员组。所以排查第一站永远是账户列表。

# 普通用户列表(兼容Win7/Win10/Win11/Server) net user # 更详细的账户属性、SID、状态 wmic useraccount get name,fullname,sid,disabled,localaccount # 新版PowerShell推荐用这个 Get-LocalUser | Select-Object Name, Enabled, LastLogon, SID

第一眼先看有没有不认识的账户,尤其是名字带$结尾的(如backdoor$)、用户名看起来像是手滑打出来的、或者你根本不知道谁创建的。注意系统自身有一些带$的账户(如WDAGUtilityAccount),不要误杀,但凡是出现在管理员组里的陌生账户,基本可以判定有问题。

2.2 隐藏账户和克隆账户的识别

Windows有个经典隐藏手段net user hacker$ /add。net user不显示以$结尾的账户,但系统确实创建了。用上面的wmic useraccount get name就能看到它。如果图形界面和net user都看不到,就得直接查注册表SAM:

reg query HKLM\SAM\SAM\Domains\Account\Users\Names /s

需要管理员权限且要在注册表编辑器的权限设置里给Administrators完全控制才能展开SAM,这一步在取证时可以直接用管理员命令行执行,能列出所有账户名,包括隐藏账户。

比隐藏账户更阴险的是“克隆账户”:把admin账户注册表里F值的二进制数据,覆盖到目标账户的F值上,实现net user显示为普通用户、但实际权限是管理员的畸形状态。识别方法也简单,看所有管理员权限账户的SID是否异常,或者用wmic useraccount get name,sid暴力对比,正常账户的SID必然唯一。发现有两个账户SID完全相同,不管用户名是什么,先按后门处理。Windows 10/11上这种老技术利用难度变高了,但Windows Server 2008/2012的老系统还大量存在,值得检查。

2.3 管理员组成员与登录事件初步筛选

net localgroup administrators wmic group where name='administrators' get name,members

确认管理员组成员列表,对比你心里“应该有哪些人”的基线。多出来的陌生账户直接记下名字和SID,下一步去安全日志里反查这个账户的登录痕迹。

同一时间,在事件查看器(eventvwr.msc)里快速过滤近7天的登录成功事件(事件ID 4624),重点看来源IP。RDP爆破特征非常明显:同一IP短时间几十上百次4625失败记录后,突然出现一条4624成功,那基本就是爆破进来了。登录类型相关内容留到第4章详细展开。

3. 运行态排查:进程、网络与服务

3.1 可疑进程的甄别思路

账户层查完,接着看当前系统上正在跑什么。这一步很多人只会tasklist看一眼就过了,但我建议至少做两个动作:看进程路径、看父子关系。

# 查看所有进程的PID、名称、可执行路径、父进程PID wmic process get processid,name,executablepath,parentprocessid # 新版PowerShell推荐 Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath, ParentProcessId

拿到结果后按以下规则筛选,命中越多越可疑:

  • 路径可疑:exe/dll位于C:\Windows\Temp、C:\Users\Public\Documents、C:\ProgramData、用户AppData的Temp目录,或者干脆路径写的是“奇怪的组合字符”。
  • 伪装系统进程:进程名为svchost.exe,但路径不是C:\Windows\System32\svchost.exe——这是最常见的一眼假。
  • 父进程异常:cmd.exe的父进程应该是用户会话或者另一个程序启动它;如果看到powershell.exe的父进程是w3wp.exe或某个Web服务,说明可能是Web漏洞传递过来的命令执行。正常业务系统里,一个Word文件的父进程不可能是Windows资源管理器之外的玩意。

查签名能进一步确认:Get-AuthenticodeSignature C:\可疑文件路径。微软签名的进程有大半是正常的,但注意一种“白加黑”利用——攻击者用合法的签名exe去加载同级目录下恶意的DLL,签名合法但行为非法,所以签名校验只能作为辅助,不能作为排除依据。

3.2 网络连接排查:谁在偷偷外联

Windows服务器被入侵后最大的特征是出现异常外联——挖矿连接矿池、木马连接C2服务器。所以netstat是必查项:

netstat -ano | findstr "ESTABLISHED"

逐条看目标地址和端口,重点标记:

  • 外部IP的高端口(如 4444、5555、8080 之外的高位端口,以及常见的挖矿端口 3333、4444、5555、6666、7777、8888)。
  • 连向你业务根本不需要访问的外部IP的连接,例如数据库服务器不应该连外部陌生IP。
  • 监听的0.0.0.0端口——如果你的服务根本没有对外需求,却在0.0.0.0监听,多半是后门开着等连接。

找到PID后用tasklist /fi "pid eq 1234"回查进程,然后顺着进程路径继续查文件、查启动项。

网络连接排查常见误区:只查“当前建立的连接”,忽略了监听端口和TIME_WAIT状态的残留连接。木马可能连一下就跑,TIME_WAIT状态的连接一样能指向外部C2地址,建议把netstat -ano完整结果保存下来,再针对ESTABLISHED + TIME_WAIT + LISTENING三种状态分别筛查一遍。

3.3 服务与驱动排查

服务是Windows持久化的另外一块沃土,因为服务自带开机自启和崩溃重启能力,攻击者写一个“服务”跑木马,比注册表Run键稳定得多。

sc query type= service state= all | findstr /i "SERVICE_NAME DISPLAY_NAME STATE" wmic service get name,displayname,pathname,startmode,state

重点看三个特征:

  1. StartMode=Auto且路径指向C:\Windows\Temp、C:\Users\Public、非系统目录的。
  2. 服务名的拼音或字母组合看起来很“随机”,如Microsoft Update Service这类伪造微软名字的服务。
  3. 路径是cmd.exe /c开头的服务,这种服务执行完就退出了,但攻击者用这一条命令去下载运行后续payload。

驱动服务更隐蔽,driverquery /v可以列出所有驱动,对比是否多了奇怪的第三方驱动。普通管理员一般记不住全部正常驱动,所以这里建议借助工具(如Sysinternals Autoruns或PowerShell的Get-CimInstance Win32_SystemDriver),然后优先找启动类型为“系统”或“自动”的陌生驱动。驱动层后门(Rootkit)在真实攻防里确实存在,但对大多数中毒服务器来说,能走到查服务这步基本已经能定位了。

4. Windows安全日志:最该被重视的证据源

4.1 先确认日志策略还活着

很多管理员排查时不看安全日志,理由是“看不懂”。但Windows安全日志是整个取证过程最权威的官方记录,攻击者做什么都会留下痕迹——除非他自己就是管理员,先把日志停了或者改了策略。所以第一步先检查审核策略是否完好:

auditpol /get /category:*

看“登录/注销”“账户登录”“账户管理”“进程创建”这几类是否处于“成功和失败”或至少“成功”。如果关键策略被关闭,说明攻击者有意清理过,这也是一个重要结论。

4.2 必须认识的几个事件ID

打开eventvwr.msc,进入Windows日志 -> 安全,按下面的表格重点筛选:

事件ID含义排查要点
4624登录成功看得登录类型、源IP、登录进程
4625登录失败短时间内高频出现=爆破
4672授予特殊权限管理员权限登录,配合4624看
4720创建用户新账户出现的时间点
4732成员添加到安全组谁把谁加入了管理员组
4726删除用户攻击者清理痕迹也可能删账户
1102安全日志已被清除重大异常信号,直接定级事故
7045新服务安装(系统日志)服务型后门创建记录

4.3 登录类型解读:4624背后的“Type”秘密

安全日志里4624事件中最关键的一个字段叫“登录类型”(Logon Type)。把登录类型搞明白,你才能判断一条登录记录到底是人坐在电脑前输密码,还是攻击者远程爆破进来的:

Logon Type含义说明
2交互式登录本机键盘输入,或物理机控制台
3网络登录访问共享、DCOM等内网凭据验证,常见于横向移动
4批处理登录计划任务以账户身份运行
5服务登录服务以账户身份启动
8网络明文登录某些旧协议或IIS基本认证
9新凭据登录使用runas或凭据管理器
10远程交互登录RDP远程桌面登录,排查的重点

如果服务器是机房里的物理机或云上的Windows虚机,你发现凌晨3点有Type 10登录成功,来源IP还是海外,那基本不需要再犹豫了——这条记录很可能就是攻击入口。

4.4 用PowerShell快速过滤可疑登录

事件查看器图形界面筛选慢,字段对不上,建议直接用PowerShell。比如查最近7天所有RDP远程登录成功的记录:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624; StartTime=(Get-Date).AddDays(-7)} | Where-Object { $_.Properties[8].Value -eq 10 } | ForEach-Object { [PSCustomObject]@{ TimeCreate = $_.TimeCreated User = $_.Properties[5].Value SourceIP = $_.Properties[18].Value LogonType = $_.Properties[8].Value } } | Sort-Object TimeCreate

Properties[8]对应LogonType,Properties[18]对应来源IP,Properties[5]对应用户名。不同Windows版本的属性下标可能有差异,实际使用时先选中一条4624事件点击“XML视图”,看字段名称和对应的Properties下标,确认后再批量跑。这是排查过程中最容易踩的坑,我第一次用这脚本查日志时,就因为下标对不上把管理员用户名全筛出来了,白忙一下午。

4.5 日志被人清空了怎么办

看到事件ID 1102,说明安全日志被某人(攻击者或管理员)主动清除过。这本身就是最高优先级的证据——正常运维不会闲着没事清安全日志。

日志被清不代表没线索:攻击者清除本机日志之前,可能已经在域控、防火墙、云平台安全组、Web服务器日志里留下了横向痕迹。查一下DNS记录、防火墙会话日志、RDP网关日志,往往能找到本机日志缺失时间段前后的网络外联行为。另外,检查C:\Windows\System32\winevt\Logs\Security.evtx文件大小和写入时间——如果文件被整个删了还没覆盖,部分数据恢复工具可能救回一些片段,但别抱太大期望,重点是转到网络侧查。

5. 持久化排查:计划任务、自启动与WMI

5.1 注册表Run键与启动文件夹

攻击者留后门的第一选择永远是“开机自启”,最传统的路径就是注册表Run键。手工查一遍也不难:

reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"

这四个位置是最常规的。RunOnce、RunServices、以及策略位置HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run也要看。启动文件夹shell:startup和shell:common startup同理,右键属性看指向的exe路径。

手工查容易漏,更推荐Sysinternals的Autoruns:勾选“Hide Signed Microsoft Entries”把微软签名项隐藏掉,剩下非微软的启动项逐一核对路径和签名。截图保存一份,这就是你判断“开机自启有没有被加料”的依据。

5.2 计划任务:攻击者最喜欢的隐藏地

计划任务比Run键高级的地方在于:它可以设置“登录时触发”“系统启动时触发”“每5分钟重复运行”,还可以用SYSTEM权限执行,真正做到重启后不掉线。攻击者特别喜欢把任务藏到微软自己的任务目录下,例如\Microsoft\Windows\...,你如果不逐个展开根本找不到。

排查命令:

schtasks /query /fo LIST /v

输出结果很长,重点看三列:任务名称、触发时间/触发器、要运行的任务。发现以下特征就要点开看XML(schtasks /query /xml /tn "任务名"):

  • 任务名伪装成Windows更新或系统组件(如Microsoft\Windows\Update\xxx)。
  • 操作(Actions)里执行的命令是powershell.exe -enc ...、cmd.exe /c ...、或者指向C:\Windows\Temp下的某个exe。
  • 触发条件是“登录时”或“启动时”且重复间隔很短,例如每5分钟跑一次——这种设计是为了保证即使你删掉正在运行的进程,任务也会把它拉起来。

PoewerShell过滤任务XML更高效:

Get-ScheduledTask | ForEach-Object { $info = $_ | Get-ScheduledTaskInfo $actions = ($_ | Select-Object -ExpandProperty Actions).Execute [PSCustomObject]@{ TaskName = $_.TaskName State = $_.State Actions = ($actions -join '; ') LastRun = $info.LastRunTime } } | Where-Object { $_.Actions -match 'temp|powershell|cmd|public' }

5.3 WMI事件订阅与COM劫持

WMI持久化是近几年攻防教材的高频词,因为它完全不出现在启动项、任务计划里,甚至tasklist里都看不到,它靠WMI服务常驻内存、事件触发执行。排查WMI事件订阅,用PowerShell最直接:

Get-WmiObject -Namespace root\subscription -Class __EventFilter Get-WmiObject -Namespace root\subscription -Class __EventConsumer Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding

正常机器上这三个查询结果应该很少,基本是空白。出现__EventConsumer里带有CommandLineEventConsumer或ActiveScriptEventConsumer的,特别是执行路径指向 exe、bat、ps1、vbs 的,基本可以判定是后门。删除可以先记录下来,别急着删,等文件层证据收集完之后统一清理。

COM劫持也值得提一句:通过修改注册表HKLM\SOFTWARE\Classes\CLSID\{...}\InprocServer32的默认值,把某个正常程序启动时加载的DLL指向恶意DLL。排查方法是导出HKEY_CLASSES_ROOT\CLSID下所有InprocServer32键的默认值,筛选指向非系统目录或非微软已签名的DLL项。这类手法比较进阶,但后果很隐蔽——很多杀毒软件全盘扫不出来,因为木马本身不落地为独立进程,而是寄生在正常程序里。

6. 文件痕迹排查:从时间线还原攻击路径

6.1 MACE时间属性:文件分析的重武器

Windows文件有四个时间属性:M(Modified修改时间)、A(Accessed访问时间)、C(Created创建时间)、E(Entry Modified目录项修改时间,也就是文件记录本身被改写的时间),合称MACE时间。安全排查时,创建时间和修改时间最重要的。

攻击者的工具(payload、扫描器、加密脚本)一定会在某个时间点写入磁盘。你只需要把最近7天内新建的、可执行文件全部列出来,基本就能看到攻击者活动的轨迹。入口处建议先查这几个目录,这是攻击脚本和下载器最爱的落脚点:

  • C:\Windows\Temp
  • C:\Users\Public\Documents
  • C:\Users\<用户>\AppData\Local\Temp
  • C:\ProgramData\Microsoft\Windows\Templates
  • 各盘符根目录下的隐藏文件夹

命令示例:

$dirs = @( 'C:\Windows\Temp', 'C:\Users\Public', 'C:\ProgramData', "$env:LOCALAPPDATA\Temp" ) Get-ChildItem -Path $dirs -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in '.exe','.dll','.bat','.cmd','.ps1','.vbs','.scr','.sys' } | Sort-Object CreationTime -Descending | Select-Object -First 80 FullName, CreationTime, LastWriteTime

结果里出现一个7天前创建的svchost.exe,那基本等于直球攻击了。

6.2 DLL加载与白加黑的核查

光查“有没有可疑exe”还不够,很多木马以DLL形式存在,被正常程序白加黑加载。对着第3章查到的异常进程,用Process Explorer或Process Hacker打开,点击“DLLs”标签,看加载的所有DLL路径。发现某个进程加载了来自Temp、Public、ProgramData的DLL,不管这个进程是不是微软签名的,都要把这个DLL当作重点样本。

没有图形工具也可以PowerShell查模块路径:

Get-Process -Name "疑似的进程名" | Select-Object -ExpandProperty Modules | Select-Object ModuleName, FileName | Where-Object { $_.FileName -match 'Temp|Public|ProgramData' }

查到结果后,不要急着删文件。先把文件的创建时间、修改时间、大小、签名状态记录到排查文档里,再用copy 路径 C:\evidence\样本名.exe备份一份。后续分析可以用在线沙箱(提交到VirusTotal一类平台)确认行为,也可以本地方便时用隔离环境复现。

6.3 查杀工具的正确用法

谈到文件层排查,必然绕不过杀毒软件。我的建议是:在证据收集完成之前,别开全盘清除。杀软的全盘扫描和清除功能会直接删掉恶意文件,等于把你的证据销毁了。正确顺序是:先按前面章节完成人工排查,把样本和日志备份好,最后才进入清理阶段。

清理阶段可以用Windows自带的Microsoft Defender离线扫描,或者常用的火绒、360系统急救箱等工具做最后一遍查漏。真正的排查看重不在一键扫描,而在于你通过时间线、路径、进程、日志把人家的“作案路径”拼出来了,查杀只是收尾动作。

7. 一次典型排查场景串联

7.1 场景:凌晨的挖矿告警

某台Windows Server 2016,同事凌晨收到告警:CPU持续跑到90%以上,外联流量异常增大。我远程登录上去后,第一步不是看CPU,也不是杀毒,而是先确认这台机器能不能断网——跟业务方确认可以隔离后,在云控制台只放行我的管理IP,相当于拔了对外网线。

然后按时间顺序执行第1章说的证据保全命令,把进程、网络、服务、账户列表全部导出到C:\evidence。

7.2 顺着链路定位

打开进程列表,先看到名为svchost.exe的进程占CPU极高,但路径指向C:\Windows\Temp\svchost.exe,第一眼就锁定异常。再用netstat -ano找到这个PID对应了到境外IP 45.xx.xx.xx:3333 的ESTABLISHED连接,挖矿特征极其明显。

接着查计划任务,果然发现一个叫Microsoft\Windows\Maintenance\SystemCheck的任务,每5分钟执行一次C:\Windows\Temp\svchost.exe。顺手查账户列表,发现多了一个helpdesk$用户。安全日志里,攻击前一天的凌晨有从某个内网办公IP发起的大量4625失败记录,随后跟着一条4624成功记录,登录类型是10(RDP)。

到这里整个事件链已经拼出来了:攻击者通过RDP爆破进来,创建隐藏账户建立长期入口,写入计划任务保证挖矿进程被杀了也能拉起来,挖矿程序本身放在Temp目录伪装成系统进程。

7.3 处置与加固

完整证据备份后,清理动作按顺序执行:

  1. 禁用并删除计划任务schtasks /delete /tn "Microsoft\Windows\Maintenance\SystemCheck" /f。
  2. 删除隐藏账户net user helpdesk$ /delete,顺手复查管理员组确保没有别的残留账户。
  3. 结束挖矿进程并删除C:\Windows\Temp\svchost.exe。
  4. 修改所有管理员密码,并把Administrator账户改名或禁用,RDP设置上启用NLA(网络级别身份验证)。
  5. 在RDP层面配置账户锁定阈值(连续5次失败锁定15分钟),同时限制来源IP白名单。

这一套下来,挖矿告警没有再出现过。事后复盘最关键的转折点,其实就是第3章那个路径查询命令——如果没有看进程路径,光靠杀毒软件扫,大概率只能清掉进程而漏掉计划任务,重启后一切照旧。

最后分享几点心得

做Windows安全排查这几年,我最深的体会是“先保现场、后谈修复”这条铁律。大多数人在看到异常的第一反应是着急处理,但这种着急恰恰会让问题变成僵尸——看起来没了,过两天又起来。备份证据、记录操作、按链路逐层排查,看起来慢,实际上是最快的路。

还有个小技巧:把日志审查做成例行习惯,不要等出事才去翻事件查看器。每周花十分钟看一眼4625失败次数和7045新服务记录,很多问题在爆发之前就有明显的预兆。我见过太多真实案例,攻击者早就进来了,在后门里蹲了几周甚至几个月,期间系统日志里全是爆破失败的记录,但因为没人看,直到数据被加密勒索才被发现。养成看日志的习惯,比装多少安全软件都管用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询