5 ms·
I guess it's time for another one of my periodic rants about the importance of memory safety, and the undesirability of being left alone in the ring against a t
by yaakov34 12y ago
I guess it's time for another one of my periodic rants about the importance of memory safety, and the undesirability of being left alone in the ring against a team of people who know the x86 architecture like you know the back of your eyelids, and who can slice your program like a piece of sushi and spread it all over printouts and wall diagrams in some apartment in Eastern Europe. Which by the way is what happens whenever you decide to write a user-facing program in a language in which you manage the memory, i.e. C and C++.
Previous editions:
https://news.ycombinator.com/item?id=7548991 https://news.ycombinator.com/item?id=7548991
https://news.ycombinator.com/item?id=2686580 https://news.ycombinator.com/item?id=2686580
Last time, the technique was simple: OpenSSL gave anyone a piece of the process's memory for the asking. This time, we are talking about return-oriented programming. I know that all of us here are completely up to date on exploits and defenses, but let's refresh our memory: the most typical and serious exploit overwrites the return location of some function and points it to malicious data (i.e. code), which takes over your computer. After decades of exploits, a two-pronged strategy was adopted by most hardware and OS vendors: program code became non-modifiable (after the OS loads it and sets a flag), and data became non-executable. So the exploit writers gave up... we wish. The ROP technique involves finding "gadgets" in existing program code (which is already marked executable). These gadgets are an instruction or two which do something (change a register, say), followed by a return opcode which will transfer control to the next gadget, whose address has been placed on the stack due to the buffer overwrite. There are actually automated or semi-automated tools to find these gadgets in your code, and to compile code which is targeted to the virtual machine which is made up of these little broken-off pieces of your program. A single buffer overrun is then enough for the malware writer to start playing your program like a xylophone, jumping hither and thither, without changing its code, to perform a malicious task.
Address Space Randomization, a.k.a. ASR or ASLR, was supposed to save us from this, by making the locations of all code randomly determined at runtime. Then the attacker won't know the address of his gadgets. Except that anything which is loaded into the same space as your process (which is a HUGE amount of stuff) may leak the pointer to some function to the attacker (by placing it somewhere within reach, like on the stack), which enables him to build his xylophone out of pieces of the leaking library. Or he can try any number of other techniques to derandomize the base pointer to your code (remember, if his code crashes, many processes will simply respawn and he can try again). Or ASR might be turned off for one or more of the libraries in your process space - this happens a lot and you have no control over it.
One of the articles about this bug calls the address leak from the Flash plugin "well-known". Well, it's certainly not well-known to me, or was known at all until 10 minutes ago (it's not like I am an exploit writer). But it's apparently very well known to the people exploiting network-facing code.
Your choice is to let your language runtime manage your memory, or to face attacks of this sophistication, which by the way happen against obscure programs too (only we don't hear about them).
Maybe I'll write a FAQ about this...
- simcop2387 12y agoThis is one of the reasons that I'm looking forward to Servo. They're taking advantage of Rust's ability to make these types of memory errors explicit (i.e. you have to ask to be unsafe). That should cause these kinds of bugs to be much much more difficult to crop up randomly.