Hacker News new | comments | show | ask | jobs | submit login
Microsoft didn’t sandbox Windows Defender, so I did (trailofbits.com)
196 points by ingve 11 months ago | hide | past | web | favorite | 43 comments

I mean, the reason is almost certainly for performance reasons - would've been interesting to see the hit that sandboxing takes here to something like `npm install` (aka something that does lots and lots of file creates / writes)

We just got McAfee installed, and the performance is horrendous on `npm install`. Even something like kicking off headless Chrome to run unit tests now takes 5 mins instead of 30s.

So yes, this is probably a major concern for a product that actually cares about their user's performance.

Get it changed from "scan all files", which humorously scans things like .css and .jpg files for malware, to "scan executable files". This has a huge impact on McAfee's performance, and has for years.

Sadly it's controlled by the higher ups who worry about 'security'... never mind that it decreases programmer productivity quite a bit!

Wasted developer time = wasted money.

How much wasted money could they save each year by changing this setting? You need to speak their language. If you can legitimately show that it costs 15k per year to have that checkbox on, they will act.

Performance is important when you are scanning all system IO for the "I Love You" virus.

The only sandbox I apply to this "realtime scanning" is to disable it wholesale. Instead of this waste of a Moore cycle Microsoft should add a few more patch days.

I'm sure all the people who already pitch a fit about updates and restarts would be thrilled.

"Performance reasons" meanwhile I kid you not when I say that the Antimalware Executable of Microsoft swallows about half my CPU performance when I am downloading, unzipping, executing files. They could have implemented their antivirus in JavaScript and it wouldn't have mattered.

implemented in JavaScript... something like this?


> The core component of MsMpEng responsible for scanning and analysis is called mpengine. Mpengine is a vast and complex attack surface, comprising of handlers for dozens of esoteric archive formats, executable packers and cryptors, full system emulators and interpreters for various architectures and languages, and so on. All of this code is accessible to remote attackers.

> NScript is the component of mpengine that evaluates any filesystem or network activity that looks like JavaScript. To be clear, this is an unsandboxed and highly privileged JavaScript interpreter that is used to evaluate untrusted code, by default on all modern Windows systems. This is as surprising as it sounds.

Time we bring back the C64 design, with no internal storage?

And no networking.

Try TempleOS, though a scamp from /g/ implemented a full network stack, along with video players, etc.

And thus the first shim was formed...

I had to create exclusions[1] for some stuff (mainly visual studio) because I had the same problem (mainly during builds).

[1] https://www.drivereasy.com/knowledge/antimalware-service-exe...

I don't fully understand this - It isn't critical to virus scan files when reading or writing them. It's important to scan them between a write and a read.

That means many written files (which won't be read for a long time) can be scanned hours later.

Others can be checked for matching a "known good" hash whitelist which can be downloaded from the net. That should cover all kinds of files which are parts of software distributions etc.

That leaves very few files which really need real time scanning.

Problem is, for example, if you compute checksums of many files after writing them...

At the same time, it's miles better than AVG!

Can antimalware suites remain effective if they are sandboxed ?

Seems to me that the "system police", as it were, needs access to the system it is policing.

The scanning engine of an AV system is like the render process of a browser. The browser itself has tentacles all over the system, but most of the danger is in parsing and executing untrusted code, and that subsystem doesn't have a lot of tentacles.

The browser and renderer is a perfect analogy. Only the scanning code that contains the format parsers, emulators, etc, needs to be sandboxed.

It is my opinion that the author's primary concern is that Windows Defender (or any antimalware suite [1][2]) has a huge attack surface, due to the high privileges assigned, and the huge amounts of file formats supported (which require custom or 3rd party parsing libraries.) Sandboxing substantially reduces that attack surface, by placing the parsing engines, and the untrusted executable in protected environments.

I agree with your sentiment that sandboxing will require more complex interactions between sandboxes for antimalware suites to act on pre-existing threats (and minimizing the required privileges for the 'SYSTEM'-level process that must act on those threats.)

[1]: https://www.engadget.com/2016/06/29/google-symantec-antiviru... [2]: https://www.engadget.com/2016/01/13/trend-micro-security-pas...

To use an analogy, this is the police laboratory that can be zombified by a virus not having access to guns.

That's a very poor analogy.

> After extensive differential debugging in ProcMon (comparing AppContainer vs non-AppContainer execution), I realized the issue might actually be with the detected Windows version. Tavis’s code always self-reported the Windows version as Windows XP. My code was reporting the real underlying operating system; Windows 10 in my case. Verification via WinDbg proved that this was indeed the one and only issue causing the initialization failures. I needed to lie to MpEngine about the underlying Windows version.

This doesn't make sense to me. It may have been easier to accomplish within the author's skillset, but it seems to me that the more beneficial approach would be to modify Tavis’ code to report the correct version of Windows.

Tavis's code ran on Linux and hooked the import table of Defender's scanning engine to report Windows XP as the underlying Windows version [1].

Originally the author didn't hook and let Defender call the native version check APIs, which (correctly) reported Windows 10. Apparently there was extra initialization code in that case that failed to run in a sandbox. The fix was to reproduce the hooking code, in Rust, to report XP as the underlying Windows version.

[1] https://github.com/taviso/loadlibrary/blob/master/peloader/w...

Sounds likley that impersonating an old windows version would probably disable various security features.

The MpEngine behaves differently on XP vs newer operation systems. It was necessary for both Tavis and Andy (Trail of Bits) to lie to MpEngine to get it to start up properly in loadlibrary and AppJailLauncher, respectively.

My understanding is that:

- Tavis' original code ran on Linux, where there's no correct version of Windows

- it actually worked with the old code; it's only broken when msmpeng sees the new Windows version

- the old code is not in use at all (the whole thing was ported to rust), which didn't have a good DLL interception library

So it would seem the suggestion to modify the old code wouldn't help.

What's most surprising is that, even though they have all the bad publicity they could possibly get (security wise), they still chose not to go from scratch working on a new secure solution (They have smart people working there for sure), but chose to continue modifying an older codebase of a product they probably bought 10 years ago (Only explanation I can think of why you'd run so much untrusted code, at system level).

Even Sandboxing is no longer the golden grail it once was, after all, you can still milk the machine for one of the ressources (computation power) without leaving the sandbox.

Just tangential, but [are we sure], we added enough obnoxious UI-Dialog so that the usual user will [Allow everything ?] once shelled to oblivion with [Can you Confirm] boxes? After all, real secure Security, is when you shirk the responsibilty as fast as possible by getting a User to act dumb or get some overworked [Administrator started]?

Anyone got links to sites that try to aggregate and/or compare the various sandboxing solutions in Windows that are open-source?

I think the only solution you want to use are AppContainers. AppJailLauncher (our code) wraps them to make taking advantage of AppContainers easier.

I think the one other useful sandboxing-related tool for Windows comes from Project 0, and they are for assessing the security of a product that uses one: https://github.com/google/sandbox-attacksurface-analysis-too...

Do you know of any good starting points for documentation/information for AppContainers? I'm finding it hard sifting through irrelevant news articles and somewhat-relevant-but-still-irrelevant microsoft/docker marketing statements

Both AppJailLauncher and AppJailLauncher-rs have a good overview of how to use them in their source code!

Not a Windows expert, but: are you looking for different libraries using the same ACL mechanism? Windows isn't Linux, you're not going to find ten different incompatible sandboxing mechanisms...

a Rust-based framework to contain untrustworthy apps in AppContainers [...] wrap the I/O of an application behind a TCP server

as well as thoughts about Rust on Windows.

While this is an interesting exercise, it ignores the fact that the anti-virus apps run with SYSTEM privileges for a reason: they need to access all the files on the machine.

Running Windows Defender in a sandbox will mitigate its own vulnerabilities, but also make it easy for viruses to hide from it.

That is not ignored, the article includes a simple architecture diagram that explains the standard solution to problems like this. In the diagram, you can see that there is a privileged process (labeled parent) and a sandboxed process (labeled child). The sandboxed process inherits a readonly handle to the file to scan and a handle to a pipe to communicate the scan result to the parent.

If the sandboxed process is compromised, all you can do is read a file that you already had access to (because it's your exploit), and lie about the scan result. That is not terribly exciting.

As the parent process doesn't do very much other than setup handles and read simple results from the sandboxed process, it is significantly harder to compromise.

This is the same model that browsers use. Your browser needs access to all your files to manage Downloads and so on, but all the dangerous stuff happens in the sandboxed renderer process. It is not "easier to hide from it", because the process that intercepts i/o still runs at the same privilege.

I was wrong. Thanks for your clear explanation, taviso.

I had a long talk with one of the Punkbuster engineers many years ago, and his take on sandboxing was: It's like you're now standing in a deep pit, and your enemies are up there at ground level, where they get to peek down into your hole and throw rocks at you whenever you want.

Except, without sandboxing, your enemy is on ground level, you are privileged (up on a hill), yet they can lob pandora's box in your direction, and you'll helpfully open it from your almighty position of power on top of the hill...

So in other words, it's damned if you do, damned if you don't.

This is a great example of why compiled applications with no sourcecode are harmful and prevent advancement.

If the sourecode for Windows Defender was mostly open source, with only critical portions linked in, then it would be possible to improve the portions that integrate the libraries into the system without moving each process used by it into some sort of wrapper.

There is not even a need for the sourcecode to be "free", merely that it is able to be viewed and alterations contributed back to be available to anyone who has paid for Windows.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact