måndag 04 oktober 2004 03:54 skrev Paul W. Abrahams:
Linux, with its underlying foundation of old C code, is particularly vulnerable to buffer-overflow attacks.
Which is not correct ... The buffer overflow attack, is based on very old information ... let me try to explain. subroutine(const char *data) { char buffer[BUFSIZ]; ... } would, depending on architecture ... become an assembly code: allocate cost_char*_data; push return-address. push registers; allocate char_buffer[BUFSIZ]; The above is the stack... the trick here, is that the stack is filled bottom-up, while memory variables are filled top-down. So, writing over buffer[BUFSIZ+12] variables will overwrite the return-adress ( or some saved register). However, this is compiler and architecture specific. Some will save the registers, AFTER they've entered the routine. And your script kiddie, has to have detailed knowledge of the subroutine that he's going to install his rootkit in. Because, you see ... he can't have the program just return to anywhere ... that's impossible. He also has to have detailed knowledge of the processor involved, in assembly code ... as the return adress information has to include information for the memory controller, as well ... not merely the cpu, those days are long since over. All in all ... the script kiddie explanation, as I told someone earlier ... is total TB ... or Tom Bluhr. I say, it's a TB because it's not merely a deliberate lie ... it's intended to obscure the facts. In the case of closed platforms, like Windows ... you have to be in the loop of development, to know the exact size of the buffer variable. It's not always BUFSIZ long, you know ... it rarely is. In the case of Open Source, this can be a problem ... since people only have to read the source, to know. Yet, in open source, the code changes rapidly ... so you have to know what version the other side is running, as well. Which means, you have to be pretty competent to do it ... and it's usually beyond the average script kiddie. The solution, is very simple ... subroutine(const char *data) { char *buffer; buffer = malloc(BUFSIZ); ... free(buffer); } In the above case, the memory will be allocated on the heap and will consist of a memory allocation block, in 4096 byte blocks which are limited to the current process only. No program code, is within that block or near it ... that is accessable through the memory variable. The memory controller, will give a segmentation violation if the buffer is overrun into the next block, which may contain program code. I really don't think that there are many programs out there, today ... that are mission critical, that are vulnerable to buffer attacks. Of course, I haven't taken a look into the kernel ... but I doubt the kernel has any loop holes, such as the old Atari ST(e) did. You see, all you had to do with the old ST, was to put some program code in high memory somewhere and then make it warm reboot. The memory check routine would look for a signature on every 1024 block, and if found, would run a code that was there. And you really don't know what windows does or doesn't ... this is the sort of things you can do with closed architectures, but wouldn't leave lying around in an open source core. My 0,2€ worth.