40 comments

[ 3.5 ms ] story [ 88.9 ms ] thread
Recently I approached a software project with the idea that I'd like to employ a fuzzer later when possible. What I found particularly interesting is that as soon as I had this idea in my head, my mind would constantly think of the code in a defensive "I-need-to-account-for-any-input" way.

Not just thinking about making the code work in the desired way, but also that any other input is walled of.

I think fuzzers are something that should get more attention, because it doesn't just help find critical bugs, it also changes your mind-set to defensive programming.

The teachers in my CS Labs would give us assignments that required reading all parameters from standard input. They would then run our code with /dev/random as input.

They didn't fail any project for failing this test, but it sure taught us a lesson on checking inputs and failing gracefully.

I went to a computer camp as a child and my first project was a number guessing game where the computer would pick a random number and then tell you hotter and colder as you guessed numbers.

I passed it to a friend to show off my work, and the first number he entered was "a", crashing the program immediately. Defending against rogue inputs was literally the first thing I ever learned about writing safe code.

That's my favorite software engineering joke:

A tester walks into a bar and orders a beer...

And orders 2147483648 beers...

And orders 0 beers...

And orders -1 beers...

And orders "banana" beers...

EDIT: I just thought, you might actually get a Bananenheizen if you order the last one in Germany...

> This full system x86 emulator runs as SYSTEM, is unsandboxed, is enabled by default and remotely accessible to attackers.

Can anyone more familiar with these issues tell me why Microsoft is still running this stuff as SYSTEM? Seeing as Tavis has been poking holes in the same component for a couple of months now, I assume it's a design choice and there has to be some good reason for it. Right?

Wondered that myself a couple of months ago when this first came up. I assumed: bacuase thoughtless, but perhaps there's an actual reason.
Windows is a rat's nest from hell when it comes to privilege separation. That was probably the only privilege level that allows it to communicate with what it needs to.

Even worse, despite this patch, it's still sitting here running as local system on my box. Total fucking nightmare.

Are you asking about Defender itself or the emulation component? I'd think that Defender does need the higher privilege level for obvious reasons, though conceivably the more "risky" emulation could be done in a separate process with reduced privileges. It would be a pretty big undertaking though; just consider e.g. DoS on a multi-user system by attacking the process with dropped privileges. Not saying it's infeasible, but I think it would be complex.
> by attacking the process with dropped privileges

In what way is this not strictly better for the defender than if that same process was running as SYSTEM?

I don't think limiting the capabilities of a child process (even by running it as "SYSTEM_LITE") impacts its scheduling priority, security settings, etc. It would depend on the policy around the process.

> In what way is this not strictly better for the defender than if that same process was running as SYSTEM?

You need to make sure there are no holes in the IPC. Like I said, it's presumably not infeasible, but it would have to be done right.

Why are there more likely to be holes in that IPC than the SYSTEM one?

Why are those holes more dangerous than having the entire thing happen in SYSTEM land?

Naturally, there's a danger that it's not bullet-proof and will lead to escalations/escapes. However, how is the risk of that not a strict improvement over the situation where it's running as SYSTEM and doesn't even need to bother with that?

It sounds like it's strictly harder to weaponize faults in the component if they need to find a secondary problem in IPC encapsulation over just running code as SYSTEM as soon as they compromise the component.

(comment deleted)
For defender to be able to do the kinds of things that AV does it has to run as system. Once you are running as SYSTEM what does "sandboxing" even mean?
> At the same time, AV in many cases prevents infections that would otherwise prove costly, particularly for less experienced users who aren't likely to be individually targeted by state-sponsored hackers.

Is there evidence for this claim that is placed precariously at the end of an article full of detailed evidence for the exact opposite claim?

Well, most AVs just check icon + some data like sections, import table and only sometimes put some signatures on code. By using packer(not hard to find one) you can make almost any executable undetectable.
Which is why most av products will flag any upx or mpress binary as "Trojan unknown" etc.

They mostly use a whitelist approach to work around that. Ask me how I know sometime.

Somehow you gotta give it to security researchers for slowly pushing the industry towards formally verified software. How long it is taking to even notice any change at all is a testament to how awkward (or at least peoples conception of how difficult) it must be to write formally verified software with current methods.
Or a testament to how little the industry actually cares about security once you ask them to actually put their money on the line.

Windows Defender was new in windows 10; there is no conceivable justification for using the kind of programming language that leads to this kind of vulnerability. But, here we are.

I feel that, for the end-user business at least, security is both a gamble (you may never be targeted at all) and being totally safe seems unreachable therefore stakeholders spend symbolic amount of resources to feel good about themselves.

Windows Defender is present on my Win7 installation.

> no conceivable justification for using the kind of programming language that leads to this kind of vulnerability

The legacy tail is longer than you think.

Microsoft have started moving things towards C#, but generally in order to do things on Windows the only sensible option is C++. Even if you write your app in something else you'll end up having to deal with pre-existing DLLs that have the usual issues.

Really the Morris Worm should have been more of a wakeup, but in a world where there's no external liability for insecurity the commercial and market pressure is towards whatever gets the app built and saleable, with security trailing behind.

Windows Defender was introduced as an antispyware in Windows Vista. Antivirus functionality was initially available separately as a part of Security Essentials, which was merged with Defender for the Windows 8 release.
Windows Defender has been around since Vista (XP, if you include systems it didn't ship with).

More important than that nitpick - do you really see no conceivable justification for using C++? Really? None? The entire language is unsuitable for new development? And somehow, you captured this insight which managed to be overlooked by all the engineers working at Microsoft?

What do you suggest we do? Gather the whole world, hold hands as one and unite in abandoning the language? Cast it aside for...what, exactly?

Yes, I see no conceivable justification. A program running with maximum privilege that automatically reads every incoming file? Writing such a component in a memory-unsafe language is almost criminal negligence.
> The entire language is unsuitable for new development?

Yes.

> And somehow, you captured this insight which managed to be overlooked by all the engineers working at Microsoft?

Apparently. Astonishing that they didn't, but the fact that they managed to ship this bug is already astonishing, so any explanation of how that happened will also be astonishing.

> What do you suggest we do? Gather the whole world, hold hands as one and unite in abandoning the language? Cast it aside for...what, exactly?

Mostly OCaml, probably - I guess F# in Microsoft's case. Maybe Rust or Ada in places where we absolutely need non-GC, if any of those turn out to actually exist.

There really aren't any codebases the size of Linux or Windows written in those languages. I'm not saying that there couldn't be, but there isn't currently. There is also a great deal of effort being put into making C++ more robust.

When there finally are large codebases written in Rust, it will be apparent that there are still some of the same issues.

I think that I agree with you though that there may not be real cases where GC won't work anymore.

While I agree with much of your response I specifically disagree with the notion that a single person on the outside cannot identify a problem with the decision making of an insular group.

Many people in microsoft seem to be thoroughly stuck in the microsoft way of doing things even when not ideal. How many COM objects did they for years after COM was dead? For how long did they ignore the concept of an AST during parsing of C++? Even in msvc2015 rev 3 you can't reliably turn this feature on for even a moderately sized codebase, but it is the default for GCC and Clang and has been for years. There might be a lot of smart people as microsoft, but they are often isolated from cutting edge ideas or squashed by bureaucracy.

I even really like C++, but perhaps for a security product that isn't particularly performance sensitive something else would have been better. It doesn't seem to run all the time like other AV products and just at the boundaries where information can get in and out this means it does a lot less work and has looser performance constraints, perhaps they could have used C# another in house languages.

> The entire language is unsuitable for new development?

Arguably, yes. Look at the outcome: a component specifically intended to improve system security has been found to have multiple extremely severe vulnerabilities. If Microsoft can't write memory-safe C++ code, even with PREfix at their disposal, maybe high-privilege code shouldn't be written in C++.

It was new for Microsoft. They bought the solution from someone else.
Once again hats off, and thanks, to Project Zero.
> Asked if Microsoft had previously fuzzed the Windows Defender component, a company representative said yes.

> "Fuzzing is one of a number of techniques we employ to update and strengthen our software," the representative said in an e-mail. "It is a standard practice we use as part of the Security Development Lifecyle for our products."

This journalist is naive. This answer says "sure we use fuzzing, but we have no idea if this particular bit of code was fuzzed." When you ask a binary question and a binary answer isn't provided, someone is usually trying to obfuscate the fact that they're on the wrong side of the binary.

That's awfully cynical. The answer they got is more indicative of the fact that they're talking to a representative rather than one of the engineers who would have actually been responsible for fuzzing it, so all the representative can really do is say what the policy is rather than answer the specific question of "was this particular component fuzzed"?
We live in a society presently governed by anarchic advertising and mass-hypnosis. Cynical is called-for.
A good PR representative doesn't want to get caught flat-footed, and usually gets all the information they need from inside sources so that they can bullshit properly without (accidentally) misleading the public and causing the company legal trouble. Microsoft can afford good PR staff. If they didn't say yes, than the answer is probably no.
(comment deleted)
Also remember that on Windows 10, you cannot easily get rid of the insecure scanner. It will automatically reenable itself along with its insecure x86 emulator that runs as SYSTEM.
AV is such as losing battle. Whitelisting, developer vetting, and code signing (the IOS store...I know you guys hate it) are the only things that have shown to be a reasonable defense.