MSBuild logger code execution

MSBuild-Logger-Code-Execution.png

Using msbuild to bypass application white-listing Is a well known and documented technique. You simply need to add some C# code to a msbuild task within an msbuild XML project file and msbuild will happily compile and run your code.

That’s a good approach and in most cases it will get the much wanted execution, as long as a file can be written to the victim’s disk, msbuild is present and it is not blacklisted.

There’s another less known and undocumented approach from which code execution can also be achieved. Using msbuild.exe logging functionality allows a threat actor to run any managed library that implements ILogger.

Msbuild command has an option to specify a custom logger. The custom logger must implement the Microsoft.Build.Framework.ILogger interface but that’s as far as the requirements go. No other requirement is needed.

namespace MSBuildLogger
{
	public class SimpleLogger : Microsoft.Build.Utilities.Logger
	{
		public override void Initialize(Microsoft.Build.Framework.IEventSource eventSource)
		{
			System.Windows.Forms.MessageBox.Show("Got code execution!");
		}
	}
}

After compiling this piece of code, just go for it with msbuild.

The logger assembly must be specified with the -logger switch but the actual file name can be anything. It can be renamed to an image or to an XML file, for example.

ren MSBuildLogger.dll legit.xml

There’s no need for any additional files and we can specify any file for the XML project as it will be processed after the event we’ve implemented on our logger. In this case, we’re using the same file, legit.xml.

1591890538668.png

This is the simplest way to use msbuild to get code execution using the -logger switch. The full logger parameter specification can be seen on Microsoft msbuild documentation.

It would be loads of fun if we could specify a remote assembly as a logger because Assembly.LoadFrom allows an URL as parameter. But there is no way to load a remote assembly since msbuild checks if the given logger is an existing file with File.Exists prior to loading the assembly, and if not, it assumes that the logger argument is an assembly name. This leads to loading the assembly with Assembly.Load instead of using Assembly.LoadFrom that would otherwise allow remote loggers as a bonus.

This technique is less noisy because it does not create temp files and doesn’t require csc.exe to compile the task. Apart from that, the use of this technique has no other advantages to the already well known use of msbuild tasks to bypass code execution restrictions. It requires local execution of the msbuild binary and write permissions to drop the logger. Nevertheless, it’s always good to have alternatives!

Sources:

https://docs.microsoft.com/en-us/visualstudio/msbuild/build-loggers?view=vs-2019

https://attack.mitre.org/techniques/T1127/

https://bleepsec.com/2018/11/26/using-attack-atomic-red-team-part1.html

https://ired.team/offensive-security/code-execution/using-msbuild-to-execute-shellcode-in-c

https://pentestlaboratories.com/2020/01/27/msbuild-without-msbuild/

https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html

You may also be interested in...

DLL-Hollowing.png
Nov. 10, 2021

DLL Hollowing

A deep dive into a stealthier memory allocation variant, analyzing advantages, pitfalls and artifacts

See more
imagensecforcepost.png
Jan. 5, 2015

SPARTA 1.0 BETA released

SPARTA is a python GUI application which simplifies network infrastructure penetration testing by aiding the penetration tester in the scanning and enumeration phase.

See more