A Lesson in .NET Framework Versions

With the emergence of more C# and .NET tooling, I occasionally see people tripping up over this. It’s not a huge issue, just something to be aware of.

Seatbelt is one such project written in C# that performs various host-based enumeration. The project does not distribute pre-complied binaries, so you have to build it yourself. I suspect most people will therefore clone the repo, open the solution in Visual Studio and build with the default settings.

Let’s say we have a foothold on a client machine and we want to run Seatbelt for priv esc opportunities - we may choose to upload the exe to disk and run it via a shell command.

I know Cobalt Strike has execute-assembly, but most frameworks don’t have this functionality. I’m just using this as an example.

We upload and run Seatbelt.exe but never get any output :( Maybe we even run it a few times just to make sure…

What we’ve not realised is that the following windows have been popping up on the users’ desktop!

This is obviously a bit of an opsec fail, so how do we fix it?

The problem is that we’ve compiled Seatbelt with a target framework that is not available on the host. So all we really need to do it retarget the solution and re-compile. In Visual Studio, go to Project > Seatbelt Properties and in the Application tab, we’ll see the default Target framework set to .NET Framework 3.5.

There are numerous ways to check which .NET Framework versions are installed. Here’s one method:

After re-targetting the solution to .NET Framework 4.6, everything runs as expected and the user gets no prompts.

Moral of the story is to always check which .NET version is installed before running tools that leverage the framework. This is also handy as a quick reference to see which versions are default on different versions of Windows.