The hijacking flaw that lurked in Intel chips is worse than anyone thought
arstechnica.com
arstechnica.com
1. There's a second bug that allows non-root local users to provision AMT. "An unprivileged local attacker could provision manageability features"[1]
2. Access to AMT allows you to boot a recovery image, mount local drives, and do whatever you like with the included remote KVM.[2][3]
So, even if this is turned off, there are issues to address. If it's on, they have control of the whole machine, remotely. It's as bad as it can get.
[1] https://security-center.intel.com/advisory.aspx?intelid=INTE...
What the programmer should have done is check if the hash coming from the browser has the correct length, 32 characters, before attempting to compare the two strings. Or even better, the programmer should have used the proper string comparing function, strcmp, that already does that for you...
Also, fixed length hashes aren't strings. They shouldn't use the same functions as strings.
Edit: Using a proper cryptography library also might have saved them from using MD5. At the very least, most modern libraries have a warning that is is deprecated and should not be used for new projects.
Maybe they used some in-place HTTP parser and that's why they didn't have zero-termination to use strcmp.
And btw, it's not clear if the code was C to begin with. I believe large chunk of ME firmware is said to be written in Java, which kinda makes sense for a network facing system considering how shitty string.h is.
It would be interesting if somebody found that they are using some COTS webserver, C/Java - doesn't matter, and see if there are some CVEs for it.
(Btw. there are many smaller Java VMs for stuff like Java Card and JEFF)
Few years ago somebody published analysis of the ME firmware for servers (desktop version was compressed with unknown algorithm). I'm sure you can google this for details.
> the fact that the issue was with strncmp
But we don't know for sure if it was strncmp. It's a logic bug, which can be implemented in any language. But again, maybe this server runs outside JVM and is written in C.
In HTTP everything is a string.
> Using a proper cryptography library also might have saved them from using MD5.
HTTP, again. Browser sends MD5 whether you like it or not.
Once you parse it out of HTTP it is no longer as string (or at least it should no longer be a string).
>HTTP, again. Browser sends MD5 whether you like it or not.
They are quite clearly doing verification themselves. They can use whatever algorithm they want.
[0] https://en.wikipedia.org/wiki/Digest_access_authentication
Even though your example ends up being ok-ish (if the computed hash is a prefix of the response, perhaps it is ok to ignore any trailing junk in the response), intent is important for code quality and maintainability.
In this instance, the operation desired is "string a matches string b", which means strcmp() would be the right solution (ignoring timing attacks).
Of course, since we're talking about sensitive crypto operations here, neither is really the right answer. But in non-crypto contexts, if you want to know if two (valid) strings are the same, just use strcmp().
The "n" and the length argument doesn't automatically make strncmp() "safer" somehow; it is a totally different operation.
Though perhaps memcmp with fixed size buffers would be better still, no worrying about null terminated strings.
Or is the commenter just guessing?
They are using HTTP Digest Authentication, which is built into browsers. The purpose was to keep passwords from being clear text over regular http connections.
So, the code on the client side is in the browser. The code on the server side is in the management processor, and it is a C implementation of HTTP Digest Auth.
The bug is that they used strncmp, but used the length of the incoming hash from the client as the string length to compare, versus the actual length that the hash string is supposed to be. The exploit is to send an empty hash. That requires a proxy, or browser plugin, since the browser creates the Digest Auth Headers. The empty hash causes something like strncmp(expected, received_hash_string, 0), and of course, two zero length strings are equal.
Ignoring timing attacks, they should have used strcmp(), not strncmp(). strncmp() is for testing if one string is a prefix of another; they wanted to test if some string equaled another.
Since this is crypto related stuff, though, they should be using a strcmp()-like routine that works in a content-independent timing fashion.
But normally strncmp isn't safer than strcmp. They just do different things.
That's unsurprising now I think about it, given how AMT works, but aren't the sort of companies that would want to use AMT also the sort of companies that have security policies that require all such things to be logged?
- It's a logic bug (authentication bypass) instead of a memory corruption. An authentication bypass is bad, but a full compromise would have been much worse.
- It's a bug in the opt-in AMT management, which means that the default config is not vulnerable.
Given the authentication bypass essentially leads to full compromise, where's the difference, here?
Arbitrary code execution on the ME would mean total control of the host, i.e. privileges above any software you can run on a computer.
You don't need arbitrary code execution, the ME already has privileges above any software you can run on the computer. The ME operates in ring -2 mode [0], whereas the OS kernel has at most ring 0 privileges.
With the built-in ME functionality you can: reboot the host, change BIOS settings, re-install the OS, update BIOS (boot FreeDOS & run the vendor utility).
Couple this with a vendor vulnerability such as not signing and verifying a BIOS before flashing, and you can easily use the ME to flash a BIOS with malicious components to the computer.
So, yes, it's not as bad as using the ME to read arbitrary memory regions while the host is on, but the default ME functionality for remote management is still enough for a malicious actor to cause a lot of harm.
ME runs below the SMM. So ring -3 or lower.
All this talk about "privilege level above normal software" and "ring -7" just muddies the water. It simply is a physically separate core running its own software which has access to all RAM and all PCIe devices and can program the Intel NIC to silently redirect selected packets away from the x86 cores to itself.
I mean, not everybody runs Windows 10 and is used to his machine having a free will of its own ;)
I don't think so. There's a second bug that allows local non-privileged users to provision AMT.
And, once it's up and running, you have a full remote KVM where you can boot recovery disks, edit the local files then reboot, etc.
Having AMT on isn't that unusual either. It's not the default, but lots of people use it. I know some digital signage units using NUCS have it on, for example. Also, some large company data centers use it instead of IPMI. The ports aren't exposed to the internet, but if hackers get inside a different way, they are off to the races.
AMT is on by default in at least a number of the popular thinkpad series[1] (i'm the only owner of a relatively old thinkpad, and only because of this security alert i checked and it was on; never haven't turned it on myself)
[1] https://forums.lenovo.com/t5/Security-Malware/Intel-AMT-back...
If you want to fix this, there's no strict need to move away from C (not that I'd particularly encourage you to stay, but if you have some reason to prefer C, you can solve this in C). There are a number of C libraries that give you a struct string {char *ptr; int len;} of some sort, from bstring to GLib. And there's always C++, too.
What need does the Intel AMT firmware have for compatibility with POSIX string APIs? It's not running a POSIX OS, is it?
It's more convenient and safer to have these two variables packed together as a "string object" and have string functions operate on that - then they always know where the string starts and ends in memory.
Really you want both a length, of the data actually in the string, and a capacity, marking how much memory is valid.
If I'm understanding the vulnerability right: strncmp takes three arguments, the beginning of the first string, the beginning of the second string, and the maximum number of bytes to compare. That maximum isn't quite a length or a capacity. It's a bound on the length, if one of the strings isn't null-terminated. But if you provide too small a maximum, it'll only compare the first few characters, and return a value based on that.
In particular they compared the target string to the user-provided string, with a user-provided length, so if you provide an empty string, it compares 0 bytes and returns success.
An API of the form strcmp(struct actual_string a, struct actual_string b) wouldn't have this problem - the actual string structures (instead of a char pointer) would provide a length for both strings, so the API wouldn't let you make this sort of error.
With them you don't have to worry about lack of null termination as the n determines the length of the string.
Problem here was usage of them at all. Hashes are not really strings, memcmp should have been used or even better secure (that doesn't leek timings) memcmp should be used.
Problem here was just mistake in the program not in the C lib.
"More secure" doesn't imply "not dangerous". It's definitely safer to drive a car without seatbelts than to ride a bike down the highway, but that doesn't mean that not wearing your seatbelt isn't dangerous.
> Problem here was usage of them at all. Hashes are not really strings, memcmp should have been used or even better secure (that doesn't leek timings) memcmp should be used.
This is incorrect for two reasons.
The first is that hashes in ASCII format are strings: it's useful to want, for example, case-insensitive hash comparisons.
The second is that (if I'm understanding the vulnerability correctly) the exact same bug would be present with memcmp:
if (memcmp(target, user_string, user_string_length) == 0)
> Problem here was just mistake in the program not in the C lib.Yes. But a library that people make mistakes with all the time is dangerous. If you are a programmer who ever makes mistakes (and clearly the AMT folks are, but I'm pretty sure so is everyone), you should avoid dangerous libraries.
In general I agree, we have a long way to go to writing more secure software by default.
But this specific issue is different. The issue was not the string length was incorrect (the length passed to strncmp was the correct length for the response string); the problem here was a logic problem, which is harder to get right just by switching string implementations.
The buggy code in question was basically (in an imaginary language with fully managed strings):
if response is_a_prefix_of expected_hash:
allow_login()
when it should have been if response is_equal_to expected_hash:
allow_login()The problem is that strncmp is in fact a prefix-comparison function when used with n calculated one way, but also it's the "safer" version of strcmp when used with n calculated another way, and it's easy to confuse the two uses.
In any other string implementation, you'd just use the most obviously-named compare function, there would be no need for a "safer" version of that function (there'd just be one reasonable comparison function), and it would do the right thing.
This isn't true; first off it isn't "safer" than strcmp() at all (this isn't strcpy vs strncpy after all), and second, no length argument to strncmp() will make it act like strcmp(). In order to get strcmp(), you have to also check the lengths are the same first.
strlen(a) == strlen(b) && strncmp(a, b, strlen(either))
This is less safe than using strcmp() when you want equality (as this Intel issue shows) because it is easy to forget the length check. strcmp() does it implicitly for you.I agree the names are not ideal (in fact I write my own streq() and strpfx() routines because I think it reads easier and it is also easy to get the return value of strcmp() wrong), but again, that has nothing to do with separating the string's pointer and its length.
An API where experienced users don't even agree what the function is supposed to be is a bad API.
MD5 is not broken for the usage that you think it's broken for. Please don't snipe on things like this again. People like you who say things like "md5 is always bad" or "you should bcrypt, duh" are literally cargo culting the idea of computer security.
In addition to the fundamental technical deficiency you've demonstrated, people who opine on security threads while not quite understanding anything about computer security allow charlatans to sell "computer security". Every single comment like this lends credence to literal scam artists.
¹note, this is actually a prize for a weaker claim than an preimage attack; all I want is a second preimage (!)
Correct; it's broken for everything since we've got the computational power to make it essentially ineffective.
MD5 is still preimage and second-preimage resistant.
MD5 is known to be a poor option. And every few years the practicalities of attacking it increase. And when the type of attack described here does become practical, all we'll be hearing is one side saying "they had ten years to fix this" and another side saying "but experts we consulted said it was fine".
It is incredibly easy for whatever process builds a website with an MD5 hash of a download to instead display something else, so the cost trade off becomes:
Cost: Virtually nil Mitigation: Currently minimal but has future potential
That a company would look at that and say "I guess we'll make a choice to stick with MD5" says something, even if it doesn't say the website downloads are easily compromised.
Alternatively, the parent comment could be pointing out that no hash signature that only exists on the download site itself offers value, and they would be better served offering a GPG signature or similar.
It's almost certainly a question of when, not if, I will be able to collect on that offer.
In addition, you are completely wrong about the harm caused by simplifying the rules of thumb for security. There is not good reason to ever use MD5 for this purpose, and saying "MD5 is ok in some cases" has the potentially to do far more harm than "never use MD5".
> note, this is actually a prize for a weaker claim than an preimage attack; all I want is a second preimage (!)
Don't act like you are doing GP a favor, second preimage is the attack that would cause a vulnerability in this usage of MD5.
You are the one who is"opin[ing] on security threads while not quite understanding anything", so I think before the next time you condescendingly correct someone you should make sure you have a basic understanding of what you are talking about.
Aside: a preimage attack implies a second preimage attack.
Not all devs are security experts, or can even afford to focus on security. To deny the value of rules of thumb is to deny that they need to consider security.
> Did I ever say "MD5 is ok in some cases"?
Oh, really? Were you not arguing that MD5 is ok if you only need preimage resistance?
> MD5 is not broken for the usage that you think it's broken for. Please don't snipe on things like this again. People like you who say things like "md5 is always bad" or "you should bcrypt, duh" are literally cargo culting the idea of computer security.
Hmm. Seems like you were...
Which means, the published MD5 on on the Intel site would have to be the hash that the attacker created.
Though I'm sure there are better methods that Intel could implement.
That seems a lot better than Intel's stance on the ME.
Surely a new one must have been created since NSA tools are out on the net
Sure about that? From what I can tell, it's a recently discovered vulnerability that was promptly fixed.
https://www.embedi.com/files/white-papers/Silent-Bob-is-Sile...
> An authentication bypass vulnerability, which will be later known as CVE-2017-5689, was originally discovered in mid-February of 2017 while doing side-research on the internals of Intel ME firmware. The first objects of interest were network services and protocols.
> When AMT is enabled, all network packets are redirected to the Intel Management Engine and from there to the AMT. The packets bypass the OS completely. The vulnerable management features were made available in some but not all Intel chipsets starting in 2010, Embedi has said.
The vulnerability is in AMT, not ME (though I agree that the ME is an unnecessary security risk, and am well behind the current research to disable it).