前言

在上海某攻防演练时 通过”Geoserver”反序列化漏洞作为入口点拿下一台服务账户用户的windows机器,众所周知,服务账号通常具有”SeImpersonatePrivilege”特权,可用此特权通过土豆提权至system权限;但是当时这台入口机默认开启了 Windows Defender(作为微软在 Windows 系统中默认内置的反病毒软件),对一些公开且未做免杀的工具会直接查杀,导致一些工具无法落地。 因此,我在提权和后续内网渗透中被卡住了一整晚(因为我不擅长免杀);第二天的时候脑子就在想,竟然我无法通过免杀来绕过defender,还有没有其他比较骚的技巧?还真有,突然想起来之前看过一篇老外的文章:”Abusing AV/EDR Exclusions to Evade Detections“,介绍了如何滥用 AV/EDR 的排除机制来绕过检测,当时试了一下这个方法,没想到刚好有一个目录被win defender排除并且普通用户还对此目录还有写的权限;于是,我将 “土豆” 提权工具上传到该排除目录,成功执行并提权到 SYSTEM 权限,随后立即关闭了 Windows Defender;后面陆续上传fscan和代理等工具开始进行内网渗透。

攻防结束之后,觉得”滥用 AV/EDR 的排除机制来绕过检测”方法挺有意思的,就想着分享出来

Win Defender中的排除类型

排除类型 含义 场景示例
文件(File) 指定单个文件不扫描 某个脚本、工具、可执行文件
文件夹(Folder) 指定整个文件夹(含子文件)不扫描 临时目录、测试环境输出目录
文件类型(File Type) 按扩展名排除某类文件 比如排除所有 .log.bak 文件
进程(Process) 指定某个进程不受 Defender 实时保护 比如某些自研程序或自动化工具

枚举 Win Defender 排除项

使用此命令就可以查看当前排除项的详细信息

1
Get-MpPreference | Select-Object -Property ExclusionPath, ExclusionProcess, ExclusionExtension

但是有一个问题,只有管理员权限的用户才能执行此命令,否则会报错权限不足;

默认情况下,Defender 会记录配置更改,包括对排除项的修改的信息;所以枚举 Win Defender排除项的另一种技巧是检查 Windows Defender 操作的事件日志,这些日志即使是普通用户也可以读取;

可以利用此脚本解析日志并识别排除项目:

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
function Get-DefenderExclusions {
param (
[string]$logName = "Microsoft-Windows-Windows Defender/Operational",
[int]$eventID = 5007,
[switch]$Path,
[switch]$Process,
[switch]$Extension
)

if (-not ($Path -or $Process -or $Extension)) {
Write-Host "Please specify at least one type of exclusion to filter: -Path, -Process, -Extension."
return
}

# Get all event logs with the specified Event ID
$events = Get-WinEvent -LogName $logName -FilterXPath "*[System[(EventID=$eventID)]]" -ErrorAction SilentlyContinue

if (-not $events) {
Write-Host "No events found with Event ID $eventID in the $logName log."
return
}

# Define the regex patterns for exclusion paths, extensions, and processes
$patterns = @{
Path = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\([^`"]+)"
Extension = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Extensions\\([^`"]+)"
Process = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes\\([^`"]+)"
}

# Function to parse and return unique exclusions
function Get-UniqueExclusions {
param (
[string]$pattern,
[string]$exclusionType
)

$uniqueExclusions = @{}
foreach ($event in $events) {
$message = $event.Message
if ($message -match $pattern) {
$exclusionDetail = $matches[1] -replace ' = 0x0.*$', '' -replace 'New value:', '' -replace '^\s+|\s+$', ''
if (-not $uniqueExclusions.ContainsKey($exclusionDetail) -or $event.TimeCreated -gt $uniqueExclusions[$exclusionDetail]) {
$uniqueExclusions[$exclusionDetail] = $event.TimeCreated
}
}
}
return $uniqueExclusions.GetEnumerator() | Sort-Object Value -Descending | ForEach-Object {
[PSCustomObject]@{
ExclusionDetail = $_.Key
TimeCreated = $_.Value
}
}
}

# Extract and display exclusions based on the provided arguments
if ($Path) {
Write-Host "Path Exclusions:"
Get-UniqueExclusions -pattern $patterns.Path -exclusionType 'Path' | Format-Table -Property ExclusionDetail, TimeCreated -AutoSize -Wrap
}
if ($Process) {
Write-Host "Process Exclusions:"
Get-UniqueExclusions -pattern $patterns.Process -exclusionType 'Process' | Format-Table -Property ExclusionDetail, TimeCreated -AutoSize -Wrap
}
if ($Extension) {
Write-Host "Extension Exclusions:"
Get-UniqueExclusions -pattern $patterns.Extension -exclusionType 'Extension' | Format-Table -Property ExclusionDetail, TimeCreated -AutoSize -Wrap
}
}

# Example usage:
# Get-DefenderExclusions -Path -Process -Extension
# Get-DefenderExclusions -Process

由下图就可以看到,即使是普通用户也有方法得到”win defender”的排除项,进行下一步滥用;

注意:如果你在本地测试时,用管理员权限执行命令发现有排除项,但是使用脚本却没有输出排除项,这种情况大概是你的5007事件id的日志被清除或者不完整;

参考

https://medium.com/seercurity-spotlight/abusing-av-edr-exclusions-to-evade-detections-21fe31d7ed49