A single byte write opened a root execution exploit
daniel.haxx.se
daniel.haxx.se
The first principle was security: The principle that every syntactically incorrect program should be rejected by the compiler and that every syntactically correct program should give a result or an error message that was predictable and comprehensible in terms of the source language program itself. Thus no core dumps should ever be necessary. It was logically impossible for any source language program to cause the computer to run wild, either at compile time or at run time. A consequence of this principle is that every occurrence of every subscript of every subscripted variable was on every occasion checked at run time against both the upper and the lower declared bounds of the array. Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to - they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law.
-- Turing Award lecture 1981
This is why having C on our foundations matters, even if our daily programming languages happen to be safer and not susceptible to memory corruption.
Burroughs B5000, 1961
http://www.smecc.org/The%20Architecture%20%20of%20the%20Burr...
Nowadays sold by Unisys and known as ClearPath.
Just one example, there were other architectures with similar features.
The Intel 432 (developed in the very early 80s) had automatic bounds checking. The architecture as a whole failed because it was too complex, too slow, and too buggy to be viable.
The problem being not everyone can use them, of course.
Also to give another example, SPARC V9 has something similar.
However even if processor support was widespread, it requires willingness to turn on those compiler switches.
Which is something that goes against the culture in the C community of performance at all costs.
BOUND would have been great for compiling any language with built-in bound checking (I wouldn't be surprised if it was made with pascal in mind, same ENTER with nesting level > 1).
MPX was specifically designed for the C family languages, but it has a fairly high cost, we will have to see whether it gets widespread.
Re culture, aren't there quite a bit of high profile projects that are compiled with hardening by default ? At least firefox comes to mind.
Also although C++ shares the same flaws as C, due to the compatibility, the overall culture is a bit different.
There are the C expats that basically use it as C with Classes, and there there are the Ada/Pascal/ML expats that take advantage of the type system and standard library to write safer code.
The problem with security is that most projects tend to have a mix of those cultures, and also there is no control over 3rd party binary libraries.
bool authenticate(const char *username, const char *password)
{
const char *correct_pass = get_pass(username);
return (strcmp(correct_pass, password) == 0);
}
Now imagine you know a way to change the first byte in the password entry (i.e, what becomes correct_pass) to \0. Now pass a blank password to this function and it will always return true for any username.Then you might still get some mileage out of it (you'd be able to shorten the password).
You'd also hope that in all production systems live at the moment the passwords stored would not be in plaintext but properly hashed so writing random nuls into either one of the hashes would simply result in a mismatch.
Google finds some pocs, http://www.scasploit.org/?p=9
I have code samples + remote exploit code against nonvectorised strcmp; I can write this up if anyone thinks it would be helpful.
It was literally just a careless use of memcmp to check an HMAC that allowed for it to work.
For stack overflows, see -fstack-protector(-...) for gcc and clang.
For heap overflows, it would depend on the implementation of malloc. glibc has mcheck() and MALLOC_CHECK_.
If you're doing this as a part of release testing, ASan (and other *Sans like MSan) is worth looking into.
The difficulty is, as usual, finding out which one to change. ;-)
Later I used the +fravia site for hacking protection systems in much the same fashion - disassemble, convert the checks to NOPs, and patch the binary.
I've recently tried to go back into reversing, but one problem is that there are very few Linux binaries which even prompt for serial numbers!
There used to be no such thing as getting paid for security bugs and exploits, yet there was no shortage of free published research on mailing lists and other ascii-friendly distribution channels, including exploits and walkthroughs.
Early example: http://phrack.org/issues/57/9.html
Not trying to belittle the issue or the efforts spent to report it, but trying to understand how frequently it could be exploited.
Does not sound like a limitation at all. This is the very normal "browser attack model" where you assume that an attacker can execute code in your browser. (aka he either controls a webpage you are visiting, a banner on a webpage you are visiting or the network stream and messes with http webpages you are visiting).
Not sure what I missed. It must have some other redeeming qualities besides this one. :)
Learning to master nc and tcpclient before curl* had the same effect. I guess I am missing all the fun.
*There are so many features, so much rarely used code, I'm not sure one could ever hope to fully understand all the implications.
Firstly, the attacker has a level of control over the type of data that lies before the freed and wrongly coalesced block, and so they have a level of control over how the data they are overwriting will be interpreted. It might actually be possible to arrange that the data block is expected to contain dynamically generated executable code (e.g. output from JavaScript JIT compilation), and by replacing that with arbitrary position-independent code you immediately still have arbitrary code execution.
Secondly, this class of bug potentially also allows for information leakage. Block A precedes block B in memory, and B's header is overwritten. A is freed and merged with B. Now the attacker induces (A+B) to be allocated as a block type that lets them read out data, and then induces some data that includes addresses to be written to B by way of an update. The attacker then reads out (A+B), gaining information about the address space that they can then use for a successful exploit.
ASLR certainly can make attacks harder and some attacks impossible, but it is not safe to assume it gives you immunity from exploitation for this type of bug.
ASLR was enabled. The attacker worked around it.
"Being exposed to djbdns I was never tempted at all to try c-ares. Not sure what I missed. It must have some other redeeming qualities besides this one. :) Learning to master nc and tcpclient before curl* had the same effect. I guess I am missing all the fun. *There are so many features, so much rarely used code, I'm not sure one could ever hope to fully understand all the implications." jingo 22 hours ago [dead] [-]