In this tutorial, we will explore a defense mechanism against stack overflows, namely the stack canary. It is indeed the most primitive form of defense, yet powerful and performant, so very popular in most, if not all, binariesyou can find in modern distributions. The lab challenges showcasea variety of designs of stack canaries, and highlight their subtle pros and cons in various target applications.
- Use Stack Protector All (stack Canaries For Macular Degeneration
- Use Stack Protector All (stack Canaries For Mac Os
Fstack-protector enables protection, but only inserts protection for functions that have arrays in local variables -fstack-protector-all Enable protection, insert protection for all functions -fstack-protector-strong -fstack-protector-explicit Only protects functions with explicit stackprotect attribute -fno-stack-protector Disable protection. So then i was looking for a way to ensure the stack canaries are enabled and as the other sites say i tried with the otool command in terminal($ otool -Iv appName grep stackchk) to ensure it and expecting it to return 'stackchkguard and stackchkfail' flags but it did not return any value/flags. Fstack-protector: enables stack protection for vulnerable functions that contain buffers larger than 8 bytes. This includes functions that call “alloca”.-fstack-protector-all adds stack protection to all functions.-fstack-protector-strong: like -fstack-protector. But it includes additional functions that have local array definitions,. Some compilers are built with -fstack-protector enabled by default, but the standard setting tends to be -fno-stack-protector by default. The stackchkguard and stackchkfail symbols are normally supplied by a GCC library called libssp. On OS X, they are implemented in libSystem. Stack canaries can greatly increase the difficulty of exploiting a stack buffer overflow because it forces the attacker to gain control of the instruction pointer by some non-traditional means such as corrupting other important variables on the stack. Built with option -fstack-protector'.
Step 0. Revisiting 'crackme0x00'
This is the original source code of the crackme0x00 challengethat we are quite familiar with:
We are going to compile this source code into four different binarieswith following options:
There are a few interesting compilation options that we used:
-fno-stack-protector
: do not use a stack protector-z execstack
: make its stack 'executable'
So we name each binary with a following convention:
Step 1. Let's crash the 'crackme0x00' binary
crackme0x00-nossp-exec
behaves exactly same as crackme0x00
. Notsurprisingly, it crashes with a long input:
What about crackme0x00-ssp-exec
compiled with a stack protector?
The 'stack smashing' is detected so the binary simply prevents itselffrom exploitation; resulting in a crash instead of being hijacked.
You might want to run gdb
to figure out what's going on this binary:
Step 2. Let's analyze!
To figure out, how two binaries are different. We (so kind!) provide youa script, ./diff.sh
that can easily compare two binaries.
Two notable differences are at the function prologue andepilogue. There is an extra value (%gs:0x14
) placed right after theframe pointer on the stack:
And it validates if the inserted value is same right before returningto its caller:
__stack_chk_fail_local()
is the function you observed in the gdb's backtrace.
Step 3. Stack Canary
This extra value is called, 'canary' (a bird, umm why?). Moreprecisely, what are these values?
Did you notice the canary value keeps changing? This is greatbecause attackers should truly guess (i.e., bypass) the canary valuebefore exploitation.
Step 4. Bypassing Stack Canary
However, what if the stack canary implementation is not 'perfect',meaning that an attacker might be able to guess (i.e., %gs:0x14
)?
Let's check out this binary:
Instead of this:
What about this? This implementation uses a known value (i.e., 0xdeadbeef
)as a stack canary.
So the stack should be like:
[Task] How could we exploit this program? like last week's tutorial?and get the flag?
Reference
I have a few questions about Stack Guard and SSP protections. First question is about Stack Guard and its three types of canaries, if I am correctly - terminator, random and random XOR.
1) I'd like to know, how to disabled Stack Guard on x86 Linux system? Somewhere I read, it's possible with this command, while compiling with gcc '-disable-stackguard-randomization', it's same like with this command for enable '-enable-stackguard-randomization', both doesn't work. If needed, my gcc version is 4.8.2.
2) Next question about Stack guard, when I will able to enable/disable it, how can I set, which type of canaries I want to use? What I read, terminator canaries are used by default, for random I have to compiled with '-enable-stackguard-randomization', but how about random XOR? (Or with null 0x00000000)
3) Now about SSP(ProPolice), I know, for random canary I have to compiled with 'fstack-protector-all', but how about terminator, is it same as in Stack Guard, by default?
4) Last one, if anyone of you, can tell me, where I can find random canary in memory. For example, I have this scenario - compiled C program, like 'gcc -g example.c -o example -fstack-protector-all', so with random canaries. Let's say, I'm able to get address of canary, after every execution. So expect, I have: Canary = 0x1ae3f900. From a different papers, I get some info, that canary is located in .bss segment. So I get address of .bss segment using readelf: 'readelf -a ./example | grep bss'. It's 080456c9. In gdb I set some breakpoints, to get address of canary, but when I check .bss address x/20x 0x080456c9, all I see are only 0x00000000 addresses, butcanary is nowhere. Plus, I checked __stack_chk_fail's if it isn't there, but with same result, I can't see it there. I get address of stack_chk_fail from PLT/GOT.
Use Stack Protector All (stack Canaries For Macular Degeneration
Thank in advance for your answer and time.