tl;dr MSBuild.exe and all its parts are absolutely amazing, but read on to learn more.
This is a follow along blog, so break out your command prompt and lets get started, first some background…
I first discussed some of the capabilities of the MSBuild.exe tool in 2016. It's time to hear the rest of the story as they say... Back then I was able to leverage one of the capabilities to bypass Windows Device Guard. But there is certainly much more possible here, more than you probably ever imagined.
Microsoft Build Engine, is a set of tools and libraries that enable complex build operations to be performed by development teams. While I can't share the details of my personal development and build experience, I think what I have to share will be interesting to you.
Imagine for a moment, you have as your objective to compromise not a single organization, but dozens or hundreds of organizations that use a particular piece of software. For some reason, your objective is to affect organizations that use this application, by surreptitiously injecting code into the application. You might think that the place to start is to find vulnerabilities in the application, or perhaps add source code to the application. One might immediately think of the The International Obfuscated C Code Contest. You may consider a compiler bug like the epic article found in
POC || GTFO 8:3 “ Deniable Backdoors Using Compiler Bugs”.
I would like to propose here, an alternative method, and solicit feedback. Hypothetical of course. I would like you to consider that the Microsoft Build Engine, specifically as it is implemented in MSBuild.exe and corresponding libraries, is capable of injecting and influencing the build operations. In such as way as to limit visibility, auditing, detection and prevention.
Questions to consider:
How do you ensure the integrity of your project files?
How do you ensure your application hasn't been altered during the build process?
Ok, on with the story... Imagine a build environment, that implements application whitelisting, and only allows trusted binaries to execute in order to protect the integrity of the build process. I will demonstrate exploit-free capabilities, to alter binaries at run time. These are sanctioned developer patterns. These are not limited to .NET application targets. The Build Engine has several areas that can lead to arbitrary code execution in the context of the build process. These include but are not limited to:
- Project File Parsing And Import Injection
- MSBuild Tasks, both builtin and custom
- PropertyGroup Expansion and Injection
- Command Line injection to influence build process
- Dynamic Properties
- Ok, I’ll stop there for now…
First, in order to study how to affect the build process we need a very basic project file.
Let’s use the sample provided to us by Microsoft here:
Complete the steps there first and then return…
Ok friend, welcome back, you now have a complete Microsoft Build Engine Solution and understand some basic properties of how to use MSBuild.exe
Now let us look at a very basic example of executing arbitrary .NET code to influence the build process.
For this hypothetical objective, our first phase is to display a message box during the build.
The project might look like this. Yes, this is bare bones with no actual code compilation.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<Target Name="Hello" >
<Message Text="$([System.Windows.Forms.MessageBox]::Show('Boom Town!'))" />
However, upon running this… You will get this error.
All hope is lost. Or is it :-)
Again, I encourage you to stop here and think about, or investigate the mechanism that prevents us from executing arbitrary .NET methods.
I’ll save you some time, but if you look into to it, you will find that there is a check for an environment variable named “MSBUILDENABLEALLPROPERTYFUNCTIONS”. If you enable this environment variable, you unlock the constraints on MSBuild.exe Property Functions.
Ok, I could go on. And I will in a later blog post. There is really much more to explore inside the internals of the Microsoft Build Engine and its corresponding tools and libraries.
But I’ll leave you with a sample gist to show some of the other interesting ways to alter or influence build operations with .NET code. Reminder, MSBuild can be used to build drivers, unmanaged applications. These tasks and code snippets can be used to execute pre and post build operations. Including binary alterations on files before signing… Maybe. ;-)
Ok, thats all.
Some additional reading if you are interested in these things. One can certainly use your imagination about what can be done from memory in the build process to influence the outcome.
MSBuild Property Functions
That all for today, there is much more here to tell, and I will as I have time.