Windows应急响应 - 06 进程与网络分析

06-进程与网络分析 (Process & Network Analysis)

进程和网络是恶意活动最直接的外在表现。恶意软件必须作为进程运行,C2 通信必须建立网络连接。与 Linux 使用 ps aux + netstat + ss 的简洁体系不同,Windows 的进程分析涉及更复杂的父子关系树、服务宿主(svchost.exe)体系、DLL 加载机制和 Named Pipe 通信。掌握 Windows 正常进程基线是区分正常与异常的前提。

前置知识01-系统基础与注册表 | 02-排查命令速查

关联章节08-计划任务与服务审计 | 31-Sysinternals套件

Linux 对照05-进程与网络分析


1. 进程分析基础

1.1 CMD 和 PowerShell 进程枚举

CMD 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:: 基础进程列表
tasklist

:: 带 PID 和服务名
tasklist /svc

:: 带详细信息(内存、状态)
tasklist /v

:: 过滤特定进程
tasklist /fi "imagename eq svchost.exe"
tasklist /fi "pid eq 1234"

:: 显示模块(DLL)
tasklist /m
tasklist /m /fi "imagename eq explorer.exe"

PowerShell 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 基础进程列表
Get-Process | Select-Object Id, ProcessName, Path, StartTime | Sort-Object StartTime -Descending

# 获取完整命令行(关键!很多恶意行为通过命令行参数暴露)
Get-CimInstance Win32_Process |
Select-Object ProcessId, Name, CommandLine, ParentProcessId,
CreationDate, ExecutablePath | Format-List

# 获取进程所有者(哪个用户在运行)
Get-CimInstance Win32_Process | ForEach-Object {
$owner = Invoke-CimMethod -InputObject $_ -MethodName GetOwner
[PSCustomObject]@{
PID = $_.ProcessId
Name = $_.Name
Owner = "$($owner.Domain)\$($owner.User)"
CommandLine = $_.CommandLine
Path = $_.ExecutablePath
PPID = $_.ParentProcessId
Created = $_.CreationDate
}
} | Format-Table -AutoSize

# 获取进程树状关系
function Get-ProcessTree {
$processes = Get-CimInstance Win32_Process
function Show-Children($parentId, $indent) {
$processes | Where-Object { $_.ParentProcessId -eq $parentId } | ForEach-Object {
"$indent$($_.ProcessId) $($_.Name) [$($_.CommandLine)]"
Show-Children $_.ProcessId "$indent "
}
}
Show-Children 0 ""
}
Get-ProcessTree

1.2 进程数字签名验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查进程的签名状态
Get-Process | Where-Object { $_.Path } | ForEach-Object {
$sig = Get-AuthenticodeSignature $_.Path -ErrorAction SilentlyContinue
[PSCustomObject]@{
PID = $_.Id
Name = $_.ProcessName
Path = $_.Path
SignatureStatus = $sig.Status
Signer = $sig.SignerCertificate.Subject
}
} | Where-Object { $_.SignatureStatus -ne 'Valid' } | Format-Table -AutoSize

# sigcheck(Sysinternals)批量检查
# sigcheck.exe -e -u -s C:\Windows\System32
# -e 扫描可执行文件
# -u 仅显示未签名的文件
# -s 递归子目录

2. Windows 正常进程基线(父子关系树)

2.1 关键系统进程的正常父子关系

熟悉正常的进程父子关系,是检测异常的基础

进程名 正常父进程 正常路径 正常实例数 正常用户
System (PID 4) 无 (内核) N/A 1 SYSTEM
smss.exe System \SystemRoot\System32\ 1 (Session 0) SYSTEM
csrss.exe smss.exe (已退出) C:\Windows\System32\ ≥2 (每 Session 一个) SYSTEM
wininit.exe smss.exe (已退出) C:\Windows\System32\ 1 SYSTEM
winlogon.exe smss.exe (已退出) C:\Windows\System32\ ≥1 (每 Session 一个) SYSTEM
services.exe wininit.exe C:\Windows\System32\ 1 SYSTEM
lsass.exe wininit.exe C:\Windows\System32\ 1 SYSTEM
svchost.exe services.exe C:\Windows\System32\ 多个 SYSTEM/LOCAL SERVICE/NETWORK SERVICE
explorer.exe userinit.exe (已退出) C:\Windows\ 每用户 1 个 当前用户
taskhostw.exe svchost.exe C:\Windows\System32\ ≥1 当前用户/SYSTEM

关键说明

smss.exe 启动 csrss.exewinlogon.exe/wininit.exe 后自身退出

因此在进程树中,csrss.exewinlogon.exe 的父进程 PID 通常已不存在

这是正常现象,不要误判为异常

2.2 svchost.exe 深度解析

svchost.exe 是 Windows 服务的宿主进程,正常系统有几十个实例

正常特征

路径必须是 C:\Windows\System32\svchost.exe

父进程必须是 services.exe

命令行格式:svchost.exe -k <group> [-p] [-s <service>]

用户必须是 SYSTEM / LOCAL SERVICE / NETWORK SERVICE

异常指标

路径不是 C:\Windows\System32\(如在 Temp 目录)

父进程不是 services.exe

没有 -k 参数

以普通用户身份运行

拼写变体:svch0st.exe, svchost.exe (末尾空格), svchost .exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 审计所有 svchost.exe 实例
Get-CimInstance Win32_Process -Filter "Name='svchost.exe'" | ForEach-Object {
$parent = Get-CimInstance Win32_Process -Filter "ProcessId=$($_.ParentProcessId)" -ErrorAction SilentlyContinue
[PSCustomObject]@{
PID = $_.ProcessId
CommandLine = $_.CommandLine
Path = $_.ExecutablePath
ParentPID = $_.ParentProcessId
ParentName = $parent.Name
CreationDate = $_.CreationDate
}
} | Format-Table -AutoSize

# 快速检查:svchost 路径是否异常
Get-CimInstance Win32_Process -Filter "Name='svchost.exe'" |
Where-Object { $_.ExecutablePath -ne 'C:\Windows\System32\svchost.exe' } |
Select-Object ProcessId, ExecutablePath, CommandLine

2.3 进程名伪装检测

攻击者常用的进程名伪装手法:

正常进程 常见伪装 区分方法
svchost.exe svch0st.exe, scvhost.exe, svchost .exe 检查路径 + 拼写
csrss.exe cssrs.exe, csrs.exe 应在 System32,只有 SYSTEM 运行
lsass.exe lsas.exe, lsass .exe, isass.exe 只应有 1 个,路径为 System32
services.exe service.exe 只应有 1 个
explorer.exe explore.exe, explorerr.exe 检查路径和父进程
taskhostw.exe taskhost.exe (Win7), taskh0st.exe 检查路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 检测类似系统进程名但路径异常的进程
$systemProcs = @('svchost.exe','csrss.exe','lsass.exe','services.exe',
'smss.exe','wininit.exe','winlogon.exe','explorer.exe')
$normalPaths = @{
'svchost.exe' = 'C:\Windows\System32\svchost.exe'
'csrss.exe' = 'C:\Windows\System32\csrss.exe'
'lsass.exe' = 'C:\Windows\System32\lsass.exe'
'services.exe' = 'C:\Windows\System32\services.exe'
'smss.exe' = 'C:\Windows\System32\smss.exe'
'wininit.exe' = 'C:\Windows\System32\wininit.exe'
'winlogon.exe' = 'C:\Windows\System32\winlogon.exe'
'explorer.exe' = 'C:\Windows\explorer.exe'
}

Get-CimInstance Win32_Process | Where-Object {
$_.Name -in $systemProcs -and
$_.ExecutablePath -and
$_.ExecutablePath -ne $normalPaths[$_.Name]
} | Select-Object ProcessId, Name, ExecutablePath, CommandLine, ParentProcessId

3. 可疑进程特征识别

3.1 可疑进程指标清单

进程属性异常

系统进程不在正常目录(svchost.exe 在 Temp 中)

未签名的可执行文件

系统进程的父进程异常(如 svchost 的父进程不是 services.exe)

进程名拼写变体

命令行异常

PowerShell 带 -enc / -EncodedCommand 参数

cmd.exe /c 执行长命令串

调用 certutil -urlcache -split -f 下载文件

mshta, regsvr32, rundll32 执行远程脚本(LOLBAS)

wmic process call create 创建进程

父子关系异常

Word.exePowerShell.exe(宏执行)

Word.execmd.execertutil.exe(下载器)

explorer.execmd.exepowershell.exe(可能正常,但需检查命令)

w3wp.execmd.exe(Web Shell 执行命令)

sqlservr.execmd.exe(SQL 注入执行命令)

3.2 LOLBAS (Living Off the Land Binaries) 检测

攻击者利用系统自带二进制文件执行恶意操作,绕过白名单检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 检测可疑的 LOLBAS 调用
$suspiciousPatterns = @(
'*certutil*urlcache*',
'*certutil*decode*',
'*mshta*http*',
'*mshta*javascript*',
'*regsvr32*/s*/n*/u*scrobj*',
'*rundll32*javascript*',
'*bitsadmin*transfer*',
'*wmic*process*call*create*',
'*wmic*os*get*/format*',
'*cmstp*/ni*/s*',
'*msiexec*/q*http*',
'*forfiles*/c*',
'*pcalua*-a*'
)

Get-CimInstance Win32_Process | ForEach-Object {
$cmdline = $_.CommandLine
foreach ($pattern in $suspiciousPatterns) {
if ($cmdline -like $pattern) {
[PSCustomObject]@{
PID = $_.ProcessId
Name = $_.Name
CommandLine = $cmdline
MatchedPattern = $pattern
ParentPID = $_.ParentProcessId
}
}
}
} | Format-List

3.3 Office 进程异常子进程检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 检测 Office 程序生成的可疑子进程(宏/漏洞利用)
$officeProcs = @('WINWORD.EXE','EXCEL.EXE','POWERPNT.EXE','OUTLOOK.EXE','MSACCESS.EXE')
$suspiciousChildren = @('cmd.exe','powershell.exe','pwsh.exe','wscript.exe',
'cscript.exe','mshta.exe','certutil.exe','regsvr32.exe','rundll32.exe',
'schtasks.exe','net.exe','net1.exe')

$allProcs = Get-CimInstance Win32_Process
foreach ($proc in $allProcs) {
if ($proc.Name -in $suspiciousChildren) {
$parent = $allProcs | Where-Object { $_.ProcessId -eq $proc.ParentProcessId }
if ($parent.Name -in $officeProcs) {
Write-Host "[!] 可疑:$($parent.Name) (PID:$($parent.ProcessId)) 生成了 $($proc.Name) (PID:$($proc.ProcessId))" -ForegroundColor Red
Write-Host " 命令行:$($proc.CommandLine)" -ForegroundColor Yellow
}
}
}

4. 网络连接分析

4.1 基础网络连接枚举

CMD 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
:: 显示所有连接和监听端口,含 PID
netstat -ano

:: 显示连接并解析进程名
netstat -anob

:: 仅显示已建立的连接
netstat -ano | findstr ESTABLISHED

:: 显示路由表
route print

:: 查看 ARP 缓存
arp -a

:: 查看 DNS 缓存
ipconfig /displaydns

PowerShell 方式(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 获取所有 TCP 连接并关联进程信息
Get-NetTCPConnection | Where-Object { $_.State -eq 'Established' } | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
LocalAddress = $_.LocalAddress
LocalPort = $_.LocalPort
RemoteAddress = $_.RemoteAddress
RemotePort = $_.RemotePort
State = $_.State
PID = $_.OwningProcess
ProcessName = $proc.ProcessName
ProcessPath = $proc.Path
}
} | Format-Table -AutoSize

# 获取所有监听端口
Get-NetTCPConnection -State Listen | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
LocalAddress = $_.LocalAddress
LocalPort = $_.LocalPort
PID = $_.OwningProcess
ProcessName = $proc.ProcessName
ProcessPath = $proc.Path
}
} | Sort-Object LocalPort | Format-Table -AutoSize

# UDP 端口(常被 C2 使用的 DNS 隧道等)
Get-NetUDPEndpoint | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
LocalAddress = $_.LocalAddress
LocalPort = $_.LocalPort
PID = $_.OwningProcess
ProcessName = $proc.ProcessName
}
} | Sort-Object LocalPort | Format-Table -AutoSize

4.2 DNS 缓存分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 导出 DNS 缓存(寻找可疑域名)
Get-DnsClientCache | Select-Object Entry, RecordName, RecordType, Data, TimeToLive |
Sort-Object Entry | Format-Table -AutoSize

# 过滤可疑域名特征
Get-DnsClientCache | Where-Object {
# 超长域名(可能是 DNS 隧道)
$_.Entry.Length -gt 50 -or
# 高熵域名(DGA 生成)
($_.Entry -match '[0-9a-f]{16,}') -or
# 常见恶意 TLD
($_.Entry -match '\.(tk|ml|ga|cf|xyz|top|buzz|cn\.com)$')
} | Select-Object Entry, Data | Format-Table -AutoSize

# 导出完整 DNS 缓存到文件
Get-DnsClientCache | Export-Csv "C:\IR\dns_cache.csv" -NoTypeInformation -Encoding UTF8

4.3 PID-连接-二进制 关联工作流

在应急响应中,需要将网络连接与进程、二进制文件完整关联

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 综合关联:连接 → PID → 进程详情 → 签名 → 命令行
$connections = Get-NetTCPConnection | Where-Object {
$_.State -eq 'Established' -and $_.RemoteAddress -ne '127.0.0.1' -and $_.RemoteAddress -ne '::1'
}

foreach ($conn in $connections) {
$proc = Get-CimInstance Win32_Process -Filter "ProcessId=$($conn.OwningProcess)" -ErrorAction SilentlyContinue
$sig = if ($proc.ExecutablePath) {
Get-AuthenticodeSignature $proc.ExecutablePath -ErrorAction SilentlyContinue
}

[PSCustomObject]@{
RemoteIP = $conn.RemoteAddress
RemotePort = $conn.RemotePort
LocalPort = $conn.LocalPort
PID = $conn.OwningProcess
ProcessName = $proc.Name
Path = $proc.ExecutablePath
CommandLine = $proc.CommandLine
Signed = $sig.Status
Signer = $sig.SignerCertificate.Subject
ParentPID = $proc.ParentProcessId
} | Format-List
Write-Host "---" -ForegroundColor DarkGray
}

4.4 可疑外联指标

特征 说明 示例
非标准端口外联 HTTP(S) 不走 80/443 svchost.exe → X.X.X.X:8443
高频短连接 C2 心跳 Beacon 每 60s 连接相同 IP
DNS 隧道 超长子域名 abcdef0123456789.evil.com
直连 IP 不经过 DNS 解析 powershell.exe → 185.x.x.x:443
云服务滥用 C2 使用合法平台 连接 *.githubusercontent.com, *.pastebin.com
svchost 外联 除 Windows Update 外不应有外联 非 Microsoft IP 的 HTTPS 连接

5. Named Pipe 分析(C2 检测)

5.1 Named Pipe 基础

Named Pipe(命名管道)是 Windows IPC 机制,进程间通信不经过网络栈

攻击者常用 Named Pipe:

Cobalt Strike:默认管道名 \.\pipe\msagent_## 或自定义

PsExec\.\pipe\PSEXESVC

Metasploit Meterpreter:各种随机管道名

横向移动:通过 SMB 远程访问 Named Pipe

5.2 Named Pipe 枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 列出所有 Named Pipes
Get-ChildItem \\.\pipe\ | Select-Object Name | Sort-Object Name

# 使用 handle.exe(Sysinternals)查看进程的 pipe 句柄
# handle.exe -a \Device\NamedPipe

# 使用 pipelist.exe(Sysinternals)
# pipelist.exe

# PowerShell 获取 Named Pipe 并关联到进程
Get-ChildItem \\.\pipe\ | ForEach-Object {
[PSCustomObject]@{
PipeName = $_.Name
FullName = $_.FullName
}
} | Sort-Object PipeName | Format-Table -AutoSize

5.3 Cobalt Strike 管道检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Cobalt Strike 常见默认管道名
$csPipePatterns = @(
'msagent_*', # CS 默认
'MSSE-*', # CS 默认变体
'postex_*', # CS post-exploitation
'postex_ssh_*', # CS SSH
'status_*', # CS
'mojo.*', # Chrome 调试(可能被滥用)
'win_svc*', # CS 服务
'ntsvcs*', # CS SMB Beacon
'scerpc*', # CS SMB Beacon
'DserNamePipe*', # CS
'SearchTextHarvester*', # CS
'mypipe-f*', # CS
'mypipe-h*', # CS
'winsock' # Meterpreter
)

$pipes = (Get-ChildItem \\.\pipe\).Name
foreach ($pattern in $csPipePatterns) {
$matched = $pipes | Where-Object { $_ -like $pattern }
if ($matched) {
Write-Host "[!] 可疑管道匹配 ($pattern):" -ForegroundColor Red
$matched | ForEach-Object { Write-Host " $_" -ForegroundColor Yellow }
}
}

6. DLL 分析

6.1 进程加载的 DLL 枚举

1
2
3
4
5
6
7
8
9
10
11
# 查看特定进程加载的所有 DLL
Get-Process -Name "svchost" | ForEach-Object {
Write-Host "PID: $($_.Id) - $($_.ProcessName)" -ForegroundColor Cyan
$_.Modules | Select-Object ModuleName, FileName, Size | Format-Table -AutoSize
}

# 使用 listdlls.exe(Sysinternals)—— 更强大
# listdlls.exe # 所有进程
# listdlls.exe -u # 仅显示未签名的 DLL
# listdlls.exe <pid> # 特定进程
# listdlls.exe -d <dll_name> # 查找加载了特定 DLL 的进程

6.2 DLL 劫持与侧加载检测

DLL 搜索顺序劫持(DLL Search Order Hijacking)是常见攻击手法

Windows DLL 搜索顺序(SafeDllSearchMode 启用时):

  1. 应用程序目录

  2. C:\Windows\System32

  3. C:\Windows\System

  4. C:\Windows

  5. 当前工作目录

  6. %PATH% 环境变量中的目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 检查非标准目录中的 DLL
Get-Process | Where-Object { $_.Path } | ForEach-Object {
$proc = $_
$_.Modules | Where-Object {
$_.FileName -and
$_.FileName -notlike 'C:\Windows\*' -and
$_.FileName -notlike 'C:\Program Files*' -and
$_.FileName -notlike ''
} | ForEach-Object {
[PSCustomObject]@{
ProcessPID = $proc.Id
ProcessName = $proc.ProcessName
DLLName = $_.ModuleName
DLLPath = $_.FileName
}
}
} | Format-Table -AutoSize

# 检测 DLL 侧加载:合法 EXE + 恶意 DLL 在同一非标准目录
# 查找用户可写目录中的 EXE+DLL 组合
$suspiciousDirs = @("$env:TEMP", "$env:APPDATA", "C:\Users\Public", "C:\ProgramData")
foreach ($dir in $suspiciousDirs) {
$exes = Get-ChildItem $dir -Filter "*.exe" -Recurse -ErrorAction SilentlyContinue
foreach ($exe in $exes) {
$dlls = Get-ChildItem $exe.DirectoryName -Filter "*.dll" -ErrorAction SilentlyContinue
if ($dlls) {
Write-Host "[!] 可疑 EXE+DLL 组合:$($exe.DirectoryName)" -ForegroundColor Yellow
Write-Host " EXE: $($exe.Name)"
$dlls | ForEach-Object { Write-Host " DLL: $($_.Name)" }
}
}
}

6.3 已知恶意 DLL 注入检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 检查是否有进程加载了常见恶意 DLL 名
$maliciousDLLs = @(
'mimilib.dll', # Mimikatz
'wceaux.dll', # WCE
'amsi.dll', # AMSI bypass DLL(如果在非标准路径)
'dbghelp.dll', # 如果在非 System32(可能被劫持)
'winhttp.dll', # 侧加载常用
'version.dll', # 侧加载常用
'msasn1.dll' # 侧加载常用
)

Get-Process | Where-Object { $_.Modules } | ForEach-Object {
$proc = $_
$_.Modules | Where-Object { $_.ModuleName -in $maliciousDLLs } | ForEach-Object {
[PSCustomObject]@{
PID = $proc.Id
Process = $proc.ProcessName
DLL = $_.ModuleName
Path = $_.FileName
}
}
} | Format-Table -AutoSize

7. Handle 分析与线程注入检测

7.1 Handle 分析基础

1
2
3
4
5
6
7
8
9
# 使用 handle.exe(Sysinternals)
# handle.exe # 列出所有句柄
# handle.exe -p <pid> # 特定进程的句柄
# handle.exe -a <name> # 搜索特定名称的句柄
# handle.exe -p <pid> -s # 显示句柄计数摘要

# 查找持有特定文件的进程
# handle.exe C:\Windows\System32\config\SAM
# 如果非 SYSTEM 进程持有 SAM 文件句柄,极为可疑

7.2 线程注入检测

攻击者常通过远程线程注入将代码注入合法进程

**Sysmon Event ID 8 (CreateRemoteThread)**:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查询远程线程创建事件
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-Sysmon/Operational'
ID = 8
} -MaxEvents 100 -ErrorAction SilentlyContinue | ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
SourcePID = $_.Properties[3].Value
SourceImage = $_.Properties[4].Value
TargetPID = $_.Properties[7].Value
TargetImage = $_.Properties[8].Value
StartAddress = $_.Properties[10].Value
}
} | Format-Table -AutoSize

# 高度可疑的组合:
# rundll32.exe → svchost.exe(进程注入)
# powershell.exe → explorer.exe(Cobalt Strike inject)
# 未知进程 → lsass.exe(凭据窃取)

检查进程的线程起始地址

1
2
3
4
5
6
7
8
9
10
11
12
13
# 使用 Process Explorer 或 Process Hacker:
# 1. 右键进程 → Properties → Threads
# 2. 正常线程的 Start Address 应在已知模块内
# 3. 如果 Start Address 指向未映射的内存区域,可能是注入的代码

# PowerShell 基础检查(有限)
Get-Process | ForEach-Object {
$threads = $_.Threads
$suspiciousThreads = $threads | Where-Object { $_.StartAddress -eq [IntPtr]::Zero }
if ($suspiciousThreads) {
Write-Host "[?] PID $($_.Id) ($($_.ProcessName)) 有可疑线程" -ForegroundColor Yellow
}
}

8. 综合进程与网络审计脚本

8.1 一键审计脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<#
.SYNOPSIS
Windows 进程与网络综合审计脚本
.DESCRIPTION
检查异常进程、可疑网络连接、命名管道、进程签名
#>

$OutputDir = "C:\IR\ProcessNetAudit_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null

Write-Host "========== 进程与网络审计 ==========" -ForegroundColor Cyan

# ---- 1. 进程快照 ----
Write-Host "`n[*] 1. 进程快照..." -ForegroundColor Yellow
$procs = Get-CimInstance Win32_Process | ForEach-Object {
$owner = Invoke-CimMethod -InputObject $_ -MethodName GetOwner -ErrorAction SilentlyContinue
[PSCustomObject]@{
PID = $_.ProcessId
PPID = $_.ParentProcessId
Name = $_.Name
Path = $_.ExecutablePath
CommandLine = $_.CommandLine
Owner = "$($owner.Domain)\$($owner.User)"
Created = $_.CreationDate
}
}
$procs | Export-Csv "$OutputDir\Processes.csv" -NoTypeInformation -Encoding UTF8
Write-Host " 已导出 $($procs.Count) 个进程" -ForegroundColor Green

# ---- 2. 未签名进程检测 ----
Write-Host "[*] 2. 检测未签名进程..." -ForegroundColor Yellow
$unsigned = Get-Process | Where-Object { $_.Path } | ForEach-Object {
$sig = Get-AuthenticodeSignature $_.Path -ErrorAction SilentlyContinue
if ($sig.Status -ne 'Valid') {
[PSCustomObject]@{
PID = $_.Id; Name = $_.ProcessName; Path = $_.Path
SigStatus = $sig.Status
}
}
}
if ($unsigned) {
Write-Host " [!] 发现 $($unsigned.Count) 个未签名进程" -ForegroundColor Red
$unsigned | Format-Table -AutoSize
$unsigned | Export-Csv "$OutputDir\UnsignedProcesses.csv" -NoTypeInformation -Encoding UTF8
}

# ---- 3. 外联连接审计 ----
Write-Host "[*] 3. 审计外联连接..." -ForegroundColor Yellow
$conns = Get-NetTCPConnection -State Established | Where-Object {
$_.RemoteAddress -ne '127.0.0.1' -and $_.RemoteAddress -ne '::1' -and $_.RemoteAddress -ne '0.0.0.0'
} | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
RemoteIP = $_.RemoteAddress; RemotePort = $_.RemotePort
LocalPort = $_.LocalPort; PID = $_.OwningProcess
Process = $proc.ProcessName; Path = $proc.Path
}
}
$conns | Format-Table -AutoSize
$conns | Export-Csv "$OutputDir\Connections.csv" -NoTypeInformation -Encoding UTF8

# ---- 4. 监听端口审计 ----
Write-Host "[*] 4. 监听端口..." -ForegroundColor Yellow
Get-NetTCPConnection -State Listen | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
LocalAddress = $_.LocalAddress; LocalPort = $_.LocalPort
PID = $_.OwningProcess; Process = $proc.ProcessName; Path = $proc.Path
}
} | Sort-Object LocalPort | Export-Csv "$OutputDir\ListeningPorts.csv" -NoTypeInformation -Encoding UTF8

# ---- 5. Named Pipe 检查 ----
Write-Host "[*] 5. 检查命名管道..." -ForegroundColor Yellow
$pipes = (Get-ChildItem \\.\pipe\ -ErrorAction SilentlyContinue).Name
$csPipes = $pipes | Where-Object { $_ -like 'msagent_*' -or $_ -like 'MSSE-*' -or
$_ -like 'postex_*' -or $_ -like 'DserNamePipe*' }
if ($csPipes) {
Write-Host " [!] 发现可疑命名管道:" -ForegroundColor Red
$csPipes
}

# ---- 6. DNS 缓存 ----
Write-Host "[*] 6. 导出 DNS 缓存..." -ForegroundColor Yellow
Get-DnsClientCache | Export-Csv "$OutputDir\DNSCache.csv" -NoTypeInformation -Encoding UTF8

Write-Host "`n========== 审计完成:$OutputDir ==========" -ForegroundColor Cyan

9. 实战练习:识别可疑进程链

9.1 场景描述

收到告警,某服务器有异常外联行为。使用上述方法排查可疑进程。

9.2 排查思路

Step 1:从网络连接入手

1
2
3
# 找到外联可疑 IP 的进程
Get-NetTCPConnection -State Established | Where-Object { $_.RemoteAddress -eq '185.x.x.x' }
# 假设输出 PID = 3456

Step 2:追溯进程信息

1
2
Get-CimInstance Win32_Process -Filter "ProcessId=3456"
# 发现是 rundll32.exe,命令行包含可疑参数

Step 3:追溯父进程链

1
2
3
4
5
6
7
8
9
10
11
12
13
# 向上追溯
function Trace-ParentProcess($pid) {
$proc = Get-CimInstance Win32_Process -Filter "ProcessId=$pid"
if ($proc) {
Write-Host "PID: $($proc.ProcessId) | Name: $($proc.Name) | Cmd: $($proc.CommandLine)"
if ($proc.ParentProcessId -and $proc.ParentProcessId -ne 0) {
Trace-ParentProcess $proc.ParentProcessId
}
}
}
Trace-ParentProcess 3456
# 可能发现:rundll32.exe ← powershell.exe ← cmd.exe ← WINWORD.EXE
# 这是典型的宏钓鱼攻击链!

Step 4:检查该进程的 DLL 和管道

1
2
# listdlls.exe 3456
# handle.exe -p 3456

9.3 Linux 对照

Linux 操作 Windows 对应
ps auxf (进程树) Get-CimInstance Win32_Process + 手动构建树
ss -tlnp (监听端口) Get-NetTCPConnection -State Listen
ss -tnp (已建立连接) Get-NetTCPConnection -State Established
lsof -i :80 (端口关联) Get-NetTCPConnection -LocalPort 80
ls -la /proc/<pid>/exe (Get-Process -Id <pid>).Path
cat /proc/<pid>/cmdline (Get-CimInstance Win32_Process -Filter "ProcessId=<pid>").CommandLine
strace -p <pid> Process Monitor (Sysinternals)
ltrace -p <pid> API Monitor / Frida

10. 快速参考

10.1 进程排查命令速查

目标 命令
进程列表+命令行 Get-CimInstance Win32_Process | Select ProcessId,Name,CommandLine
进程树 Process Explorer 或手动 PPID 追溯
进程签名 Get-AuthenticodeSignature <path> / sigcheck.exe
进程 DLL Get-Process -Id <pid> -Module / listdlls.exe
Named Pipes Get-ChildItem \\.\pipe\ / pipelist.exe
远程线程 Sysmon Event ID 8

10.2 网络排查命令速查

目标 命令
TCP 连接 Get-NetTCPConnection
UDP 端点 Get-NetUDPEndpoint
DNS 缓存 Get-DnsClientCache
ARP 表 arp -a / Get-NetNeighbor
路由表 route print / Get-NetRoute
防火墙规则 Get-NetFirewallRule


上一章 目录 下一章
05-账户安全排查 Windows应急响应 07-文件系统取证