Date: | April 21, 2016 / year-entry #84 |
Tags: | other |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20160421-00/?p=93326 |
Comments: | 25 |
Summary: | You never crossed a security boundary. |
We received a very professional security vulnerability report from a video driver manufacturer which reported a security vulnerability in DirectX. You can tell it's a professional operation because the vulnerability report took the form of a neatly-formatted PowerPoint presentation with corporate logos in every corner. Unfortunately, you'll have to make do with my distillation into boring text.
There is no vulnerability here yet because there is no elevation. I mean, sure, the attacker can pass bogus buffers and trick DirectX but let's take a closer look at who the attacker is and who the victim is. The attacker is a rogue program that is intentionally passing invalid buffers to DirectX. DirectX runs in-process and tries to read data from or write results to those buffers. The attacker can trick DirectX into reading or writing past the end of the buffer by lying about the buffer size. void UseDirectXToReadPastEndOfBuffer() { direct3dResource9->SetPrivateData( GUID_Attack, buffer, incorrectSize, 0); } void UseDirectXToWritePastEndOfBuffer() { DWORD size = incorrectSize; direct3dResource9->GetPrivateData( GUID_Attack, buffer, &size); } But so what? The attacker can already do that without needing to trick DirectX into doing anything. void JustReadPastEndOfBuffer() { memcmp(buffer, buffer, incorrectSize); } void JustWritePastEndOfBuffer() { memset(buffer, 0, incorrectSize); } Using DirectX to read memory from within your process is just adding style points. You aren't doing you can't already do. You're just going through a middle man and then blaming the middle man. Of course, one must verify that corruption or exposure of data within the process causes no damage beyond the process. If the corrupted data crosses a security boundary (e.g., gets passed to a kernel mode video driver), the recipient of the data must be resilient to intentionally invalid parameters.
The From that standpoint, these are indeed severe errors if a corrupted file can trick your application into passing incorrect buffer sizes to DirectX. And that's the bug you need to fix in the program: Make sure your program passes correct buffer sizes regardless of the contents of the file being parsed. But if the program itself is the attacker, then we have another instance of MS07-052: Code execution results in code execution. Previous discussion: |
Comments (25)
Comments are closed. |
This interestingly shows how confusing all of this stuff around security can be, if even large companies can do it.
/me takes note
I think I just found a way out of the WinRT sandbox that the auto-analyzer can’t find.
I don’t understand. WinRT applications really *are* in a sandbox enforced by the NT kernel (“lowbox token”), so if you can escape the WinRT sandbox, you would be crossing a security boundary with a real exploit.
Modern UI is unusable to me. The bug filed against Windows 8 stands yet unfixed. Unless I find a solution that allows CreateWindowEx(…, HWND_DESKTOP, …) to succeed RT might as well not exist at all.
If you want to write a desktop app, write a desktop app. If the “bug” is that you can’t escape the WinRT sandbox, that’s not a bug. That’s literally the only purpose of the sandbox.
The bug is a font rendering flaw in Modern UI.
Can you write a desktop app for RT without using an exploit yet?
Your messages are confusing. If the Modern UI is “unusable” to you, that’s fine. Don’t use it.
I have no idea what you mean by “the bug filed against Windows 8 stands yet unfixed”. Which bug? If you mean the font rendering flaw that you mentioned later, I predict that a font rendering flaw in Windows 8 is not high on Microsoft’s list of things to fix right now, in late spring 2016. Windows 8 likely won’t get much attention.
“A way out of the WinRT sandbox that the auto-analyzer can’t find” is also confusing. If you can get out of the WinRT sandbox under running code, that’s noteworthy. If the auto-analyzer doesn’t point it out, then that’s perhaps a problem in the auto-analyzer.
“Can you write a desktop app for RT without using an exploit”. Who is “you”? Do you mean ANYONE? Do people generally use exploits to write desktop apps “for RT”?
Maybe I shouldn’t feed you….
I see you mentioned later “font rendering” bug, but what is the nature, what is repro of it and how does it manifest.. Does it affect Windows 8.1 or not (aka Windows 8.0 only) and does it repro on Windows 10? I got few projects for WinRT, Universal Apps, so I am curious what are you talking about.
Try turning off anti-aliasing altogether. It doesn’t work. But I must turn it off.
Pretty sure not a bug. (aka by design) Second, why? You are still leaving many questions unanswered. I hope you reported design oversight far better then that.
Isn’t the usual concern these days about remote attacks, usually proxied by a web browser? So for example:
IE^H^HEdge gets a webpage from evil.com with Javascript that creates a canvas element. Edge uses Direct2D for canvas. The Javascript somehow gets Edge to pass the wrong buffer size which causes DirectX to read past the array and into SekritMemoryData[]. This is returned to the browser as a bag of bytes, and returned to the server via an async call.
Combine this with memory pressure (http://www.theregister.co.uk/2015/04/21/cache_creeps_can_spy_on_web_histories_for_80_of_net_users/) or something and maybe you can get the data you want. Or execute code. Or something.
Or not.
And if Edge does pass the wrong buffer to DirectX, that’s a security bug in Edge, not in DirectX.
Exactly – Edge (or its Javascript interpreter) is the one operating with untrusted data. The Javascript code presumably doesn’t even have access to the DirectX API – otherwise it wouldn’t work on platforms without DirectX.
There isn’t a tag for these posts yet?
My experience that when someone sends you an unsolicited PowerPoint deck to read, one can safely delete it unread.
If your job is to read unsolicited documents sent by customers, that’s also a great way to get fired.
Maybe they could share some wisdom with us on how to validate the size of a (void *)?
“You can tell it’s a professional operation because the vulnerability report took the form of a neatly-formatted PowerPoint presentation with corporate logos in every corner. Unfortunately, you’ll have to make do with my distillation into boring text.”
But you’re so good with the HTML fake images and such! Couldn’t you have rigged up at least a few pretend logos? I really feel like I’m missing out now.
Not even bullet points on the list? C’mon, throw us a bone here.
(no, not really)
So basically you’re saying that vulnerabilities that don’t involve privilege escalation aren’t real vulnerabilities?
Out of curiosity, have you seen http://www.xkcd.com/1200/ ?
Bad program behaviour != security vulnerability. In general, without elevation all you’re doing is finding a novel way to do something that your program could already do anyway. Remember, “security vulnerability” doesn’t mean the program gives out your gmail password, it means that the program allows your machine to be compromised in a way that your user account permissions should prevent.
I think Raymonds point is, that the caller of the DirectX API can do the same things directly, without calling DirectX APIs at all. Therefore this behavior isn’t a vulnerability *in DirectX*. The post isn’t about whether this is a security vulnerability, but where the vulnerability is.
I’m not sure this even counts as a security vulnerability, they are passing the wrong size for a buffer. It’s only a vulnerability if a user of the software has control over the size of the buffer, this is just a bug.
Basically, yeah. Raymond is saying that trusted code causing a crash in the same “security context” is not a security issue, because that doesn’t cross any security boundaries.
That xkcd is completely irrelevant. Privilege escalation isn’t only from a user account to an admin account. Something like Javascript code in a browser getting the full permissions of the user account also counts would be an actual exploit, because then the Javascript code can do something it’s not supposed to be able to do. In this case, the program is using an “exploit” to do something it was already supposed to be able to do (read/write to its own process’ memory), something which is not very interesting at all.
“MS07-052: Code execution results in code execution” is such a great and funny summary! :D And nice that you linked to the original author’s comment.
And as the original author of that comment (nine years ago!) I still get a chuckle when I read Raymond’s deconstruction of these dubious vulnerabilities… doubly so when he drops the MS07-052 on them.