84

I'm working on a homework problem that requires disabling compiler optimization protection for it to work. I'm using gcc 4.4.1 on ubuntu linux, but can't figure out which flags are are the right ones. I realize it's architecture dependant - my machine runs w/ 32-bit Intel processor.

Thanks.

Community
  • 1
  • 1
sa125
  • 28,121
  • 38
  • 111
  • 153

6 Answers6

127

That's a good problem. In order to solve that problem you will also have to disable ASLR otherwise the address of g() will be unpredictable.

Disable ASLR:

sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'

Disable canaries:

gcc overflow.c -o overflow -fno-stack-protector

After canaries and ASLR are disabled it should be a straight forward attack like the ones described in Smashing the Stack for Fun and Profit

Here is a list of security features used in ubuntu: https://wiki.ubuntu.com/Security/Features You don't have to worry about NX bits, the address of g() will always be in a executable region of memory because it is within the TEXT memory segment. NX bits only come into play if you are trying to execute shellcode on the stack or heap, which is not required for this assignment as it is using Return-Oriented Programming (ROP or ROP Chain) which is commonly used to defeat the protection provided by the NX bit.

Now go and clobber that EIP!

rook
  • 66,304
  • 38
  • 162
  • 239
  • 5
    thanks, I'll do just that :) Oh - how do I re-enable the protection to un-crap my machine?.. My guess is sudo echo 1 > /proc/sys/kernel/randomize_va_space – sa125 Feb 28 '10 at 07:23
  • @sa125 yep, thats how its re-enabled. In fact thats how you switch on and off other kernel modules while the system is running ;) – rook Feb 28 '10 at 17:41
  • 18
    Seems worth pointing out that on my system randomize_va_space defaulted to 2, not 1, so it's worth checking beforehand if you intend to re-enable it. – Rushyo Dec 01 '11 at 16:28
  • 4
    Actually the address of g() will very likely not be randomized by ASLR as it is part of the main binary. Only if you compile the binary with -PIE will it be randomized. – Robert Larsen Dec 15 '15 at 11:38
  • 1
    Modern Linux distros [configure GCC to build PIE executables by default](https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-linux), @RobertLarsen (and future readers). You can use `gcc overflow.c -fno-stack-protector -fno-pie -no-pie` to make tradition ELF executables, not shared objects. (Then you don't have to disable ASLR for non-stack segments either system-wide or for this executable, which BTW is something GDB does. No need to disable system-wide at all.) – Peter Cordes Nov 10 '21 at 01:35
  • Even in a non-PIE, the stack is still ASLRed, which is a problem for a code-injection attack (which would also need `-z execstack`). But generally not a problem for a ROP attack like this which only depends on known absolute addresses in already-executable mappings, not the stack. i.e. returning to some function that wouldn't normally be called, with interesting args in registers and/or on the stack. – Peter Cordes Nov 10 '21 at 01:37
  • @PeterCordes Yes, modern systems here in 2021. When I wrote my answer six years ago PIE was not the default. ROP does not need a full function. Small snippets of machine code can be chained together to achieve more or less anything. I realize you probably knew that. – Robert Larsen Nov 12 '21 at 19:48
  • @RobertLarsen: Yeah, I know your comment was correct at the time, mostly was addressing future readers. And right, I said "function" because that was the goal in *this* question, and I had in mind using gadgets to piece together args for a function like `system()` or `execl()`, or something specific to the program, but yeah if you can find the bytes for a `syscall` instruction itself you could use that directly. – Peter Cordes Nov 12 '21 at 19:53
37

Urm, all of the answers so far have been wrong with Rook's answer being correct.

Entering:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Followed by:

gcc -fno-stack-protector -z execstack -o bug bug.c

Disables ASLR, SSP/Propolice and Ubuntu's NoneXec (which was placed in 9.10, and fairly simple to work around see the mprotect(2) technique to map pages as executable and jmp) should help a little, however these "security features" are by no means infallible. Without the `-z execstack' flag, pages have non-executable stack markings.

poizan42
  • 1,461
  • 17
  • 22
  • 5
    You did not read the guys link. If you did you would know that he is trying to execute g() which is a function that is compiled into the binary. This is an address of a function. NX bits come into play when you are trying to execute shellcode on the heap or stack, his attack is far more simple. – rook Feb 26 '10 at 16:04
  • 1
    I agree that everyone else is completely wrong, its obvious that we are the only 2 that have exploited a buffer overflow. However i still think my answer is more correct. – rook Feb 26 '10 at 16:12
  • Hmm, just came across the link -- I thought it was just another generic, you're correct. I apologise. –  Feb 26 '10 at 20:43
  • 1
    I know this is a old post, but you can't use sudo with > < because it will not allow it. The command should be: **echo 0 | sudo tee /proc/sys/kernel/randomize_va_space** – Boogy Nov 22 '16 at 09:45
29

On newer distros (as of 2016), it seems that PIE is enabled by default so you will need to disable it explicitly when compiling.

Here's a little summary of commands which can be helpful when playing locally with buffer overflow exercises in general:

Disable canary:

gcc vuln.c -o vuln_disable_canary -fno-stack-protector

Disable DEP:

gcc vuln.c -o vuln_disable_dep -z execstack

Disable PIE:

gcc vuln.c -o vuln_disable_pie -no-pie

Disable all of protection mechanisms listed above (warning: for local testing only):

gcc vuln.c -o vuln_disable_all -fno-stack-protector -z execstack -no-pie

For 32-bit machines, you'll need to add the -m32 parameter as well.

Aydin K.
  • 3,309
  • 36
  • 44
  • `-m32` is needed when you want to build 32-bit *code* on a *64-bit machine*. Also, you can use `-fno-pie` to have the compiler generate asm that doesn't bother with PIE stuff, as well as `-no-pie` to have it not link that machine code into a PIE. For 32-bit mode, `-fno-pie` will significantly simplify the asm, removing crap like `call __x86.get_pc_thunk.bx`. For 64-bit mode, mostly just allowing `mov`-immediate instead of RIP-relative LEA for static addresses, and [more efficient indexing of static arrays](https://stackoverflow.com/questions/43367427/32-bit-absolute). – Peter Cordes Nov 10 '21 at 01:33
8

Try the -fno-stack-protector flag.

Kyle Lutz
  • 7,966
  • 2
  • 20
  • 23
6

You don't need to disable ASLR in order to do a buffer overflow! Although ASLR is enabled (kernel_randomize_va_space = 2), it will not take effect unless the compiled executable is PIE. So unless you compiled your file with -fPIC -pie flag, ASLR will not take effect.

I think only disabling the canaries with -fno-stack-protector is enough. If you want to check if ASLR is working or not (Position independent code must be set), use:

hardening-check executable_name
Melebius
  • 6,183
  • 4
  • 39
  • 52
AhlyM
  • 510
  • 1
  • 6
  • 16
2

I won't quote the entire page but the whole manual on optimisation is available here: http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Optimize-Options.html#Optimize-Options

From the sounds of it you want at least -O0, the default, and:

-fmudflap -fmudflapth -fmudflapir

For front-ends that support it (C and C++), instrument all risky pointer/array dereferencing operations, some standard library string/heap functions, and some other associated constructs with range/validity tests. Modules so instrumented should be immune to buffer overflows, invalid heap use, and some other classes of C/C++ programming errors. The instrumentation relies on a separate runtime library (libmudflap), which will be linked into a program if -fmudflap is given at link time. Run-time behavior of the instrumented program is controlled by the MUDFLAP_OPTIONS environment variable. See env MUDFLAP_OPTIONS=-help a.out for its options.