Evil code - Printable Version +- Cuberite Forum (https://forum.cuberite.org) +-- Forum: Off Topic (https://forum.cuberite.org/forum-9.html) +--- Forum: Off Topic Discussion (https://forum.cuberite.org/forum-10.html) +--- Thread: Evil code (/thread-2367.html) Pages:
1
2
|
RE: Evil code - Barracuda72 - 02-11-2016 (02-10-2016, 12:21 AM)xoft Wrote: Tell me, Linux enthisiasts, how does this reflect the "Linux is safer" mantra that I hear oh so often? How could Linux be so safe if the default configuration allows programs to execute data, and thus is very prone to buffer over-/underflow attack vectors? OK, I will answer you =) But before reading my explanation, try to answer by yourself: is there really any harm in executing read-only data? Look at code. "main" is defined as const. That this means? Lets dig into C2011 standart, paragraph 6.7.3: Quote:If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.So, basically, object with const modifier can't be directly modified through C code and that's all; anything beyond is up to compiler/OS. So, let's see how different toolchain handles this. Simple code example: Code: #include <stdio.h> Windows 7 64-bit, MSVC 14.0 (from Visual Studio 13, if I remember correctly) compiles code fine, but gives a warning about mismatch of types because memset isn't expect to take const memory location. If we a trying to run code, this is what we will get: Code: TTTTTTTTTTTTT Now, Linux. Kernel 4.5.0 x86-64, GCC 4.9.3. Compiler emits the same warning about const qualifier, but code compiles. Let's run it: Code: Segmentation fault Now, I can answer your second question: (02-10-2016, 12:21 AM)xoft Wrote: On Windows, the original code doesn't work simply because the "code" for main is stored within the data segment, which is non-executable by default, thus making it safe. Why doesn't this happen on Linux, too?Because on Linux .data section is modifiable. By the way, on Windows too, as you can see. Windows loads read-only data into DATA x86 segment, thus not restricting it to change. So, that is better - allow read-only data to be changed (Windows way) or to be executed (Linux-way)? I think Linux way is better, because answer to my question ("Is there any harm in executing read-only data?") is no. This data isn't going to change as program executes. It just can't. No stack or buffer overflows can do any harm to read-only segment. And there is no way in mistakingly run variable, don't you think? But this is very simple to modify read-only data by mistake. Linux will not allow you to do that. Windows will. Refer to my example with RSA key. It's bad practice, but it will work on Linux. On Windows someone can modify your key with buffer over/underflow. So, is Linux safer or not? =) RE: Evil code - xoft - 02-12-2016 This is all fine as long as you have *const* data. The problem is, normally you don't. Quite a few programs have a global "buffer" object of a kind that they use for whatever buffering is needed, naturally it's stored in the writable data section. But on Windows, this still means code cannot execute from that location, so attacks cannot simply stuff data into that buffer and make it execute. On Linux, such an attack vector (oh so common for all the zero-day exploits) is perfectly viable. That, in my opinion, is very unsafe. RE: Evil code - LogicParrot - 02-12-2016 I wonder if there's a technical justification for this decision. RE: Evil code - Barracuda72 - 02-12-2016 (02-12-2016, 05:12 AM)xoft Wrote: This is all fine as long as you have *const* data. The problem is, normally you don't. Quite a few programs have a global "buffer" object of a kind that they use for whatever buffering is needed, naturally it's stored in the writable data section. But on Windows, this still means code cannot execute from that location, so attacks cannot simply stuff data into that buffer and make it execute. On Linux, such an attack vector (oh so common for all the zero-day exploits) is perfectly viable. That, in my opinion, is very unsafe.Try to remove const qualifier from your code and see what happens. I will predict you: Segmentation fault. Why? Well, try to figure by yourself, it's not very interesting to read someone's ready explanation, don't you think? =D You can find an answer by looking at readelf output on binary; pay attention to the section main belongs in both cases and figure out where each section is loaded in memory, especially to which segment. In short, there is no way to run modifiable data as code on Linux. You can run constant data, and it's okay: that data is defined on compilation time and can even be viewed as a part of code itself. It can't be modified. And you can have read-write data, but you will not be able to run it. Never. Yes, there are some tricks to surpass that (mremap), but it must be done by application manually. In Windows there too are some techniques for that as I remember (VirtualProtect or so), but I can't say exactly, I never done it on Windows. To the last: Why do you really though that people so experienced as Linux kernel and Glibc developers can be stupid enough to allow execution of dynamically changeable data? It's very unclear for me... RE: Evil code - xoft - 02-12-2016 Sorry to disappoint your overconfidence: Code: xoft@akima:~$ gcc --version RE: Evil code - xoft - 02-12-2016 I'm not too familiar with ELF file format and it's the first time I've encountered the readelf tool, so I have no idea what I'm looking at. I see a long list of sections and then a long list of symbols within the .symtab section, but there's no indication about what symbol is in what section. If I follow the "main" symbol's address, it falls in the ".data" section that has "WA" flags (write, alloc), so I'd guess the compiler produces a correct executable, but the runtime fails to abort with an error. Could this be due to an old processor, perhaps not supporting some feature needed to make this work? RE: Evil code - xoft - 02-12-2016 Ah, found it: Code: root@akima:/proc# check-bios-nx --verbose RE: Evil code - xoft - 02-12-2016 On a RasPi the non-const version fails with "segmentation fault", as expected, while the const version fails with "illegal instruction", which is expected as well, since the code is x86-specific. RE: Evil code - Barracuda72 - 02-12-2016 (02-12-2016, 06:56 PM)xoft Wrote: If I follow the "main" symbol's address, it falls in the ".data" section that has "WA" flags (write, alloc)And if you investigate a little bit more, you will see that .data section falls into "Program header" with flags "RW" and .rodata into "R E". (02-12-2016, 06:56 PM)xoft Wrote: No wonder there's no security, then=D Then, this is very good that you found an answer. By the way, NX bit isn't the only option to disable data execution on x86/x86-64, there are also mechanism of segmentation but it's considered deprecated about 15 years ago and modern OS (both Linux and Windows) don't use it (or, to be more precise, use it in "Flat way" where are 4 segments identical in size and mapped on same physical memory location but different in access rights). RE: Evil code - LogicParrot - 02-12-2016 This is a very informative thread |