# Stack Canary

The Stack Canary is another mitigation designed to protect against things like stack based buffer overflows. The general idea is, a random value is placed at the bottom of the stack frame, which is below the stack variables where we actually have input. If had a buffer overflow to overwrite the saved return address, this value on the stack would be overwritten. Then before the return address is executed, it checks to see if that value is the same one it set. If it isn't then it knows that there is a memory corruption bug happening and terminates the program. Also the name comes from the use of canaries in a mine. If the canary stops singing, get out before you die from gas poisoning.

To understand this better, let's look at a binary compiled with a stack canary:

```
gef➤  disas main
Dump of assembler code for function main:
   0x[PII_REDACTED]401132 <+0>:    push   rbp
   0x[PII_REDACTED]401133 <+1>:    mov    rbp,rsp
   0x[PII_REDACTED]401136 <+4>:    sub    rsp,0x20
   0x[PII_REDACTED]40113a <+8>:    mov    rax,QWORD PTR fs:0x28
   0x[PII_REDACTED]401143 <+17>:    mov    QWORD PTR [rbp-0x8],rax
   0x[PII_REDACTED]401147 <+21>:    xor    eax,eax
   0x[PII_REDACTED]401149 <+23>:    mov    rdx,QWORD PTR [rip+0x2ef0]        # 0x404040 <stdin@@GLIBC_2.2.5>
   0x[PII_REDACTED]401150 <+30>:    lea    rax,[rbp-0x12]
   0x[PII_REDACTED]401154 <+34>:    mov    esi,0x9
   0x[PII_REDACTED]401159 <+39>:    mov    rdi,rax
   0x[PII_REDACTED]40115c <+42>:    call   0x401040 <fgets@plt>
   0x[PII_REDACTED]401161 <+47>:    mov    DWORD PTR [rbp-0x18],0x5
   0x[PII_REDACTED]401168 <+54>:    nop
   0x[PII_REDACTED]401169 <+55>:    mov    rax,QWORD PTR [rbp-0x8]
   0x[PII_REDACTED]40116d <+59>:    xor    rax,QWORD PTR fs:0x28
   0x[PII_REDACTED]401176 <+68>:    je     0x40117d <main+75>
   0x[PII_REDACTED]401178 <+70>:    call   0x401030 <__stack_chk_fail@plt>
   0x[PII_REDACTED]40117d <+75>:    leave  
   0x[PII_REDACTED]40117e <+76>:    ret    
End of assembler dump.
```


Now let's look at a binary compiled from the same source code, but without a stack canary:

```
gef➤  disas main
Dump of assembler code for function main:
   0x[PII_REDACTED]401122 <+0>:    push   rbp
   0x[PII_REDACTED]401123 <+1>:    mov    rbp,rsp
   0x[PII_REDACTED]401126 <+4>:    sub    rsp,0x10
   0x[PII_REDACTED]40112a <+8>:    mov    rdx,QWORD PTR [rip+0x2eff]        # 0x404030 <stdin@@GLIBC_2.2.5>
   0x[PII_REDACTED]401131 <+15>:    lea    rax,[rbp-0xe]
   0x[PII_REDACTED]401135 <+19>:    mov    esi,0x9
   0x[PII_REDACTED]40113a <+24>:    mov    rdi,rax
   0x[PII_REDACTED]40113d <+27>:    call   0x401030 <fgets@plt>
   0x[PII_REDACTED]401142 <+32>:    mov    DWORD PTR [rbp-0x4],0x5
   0x[PII_REDACTED]401149 <+39>:    nop
   0x[PII_REDACTED]40114a <+40>:    leave  
   0x[PII_REDACTED]40114b <+41>:    ret    
End of assembler dump.
```

We can see a few differences between the code, like when it checks the stack canary:

```
   0x[PII_REDACTED]401169 <+55>:    mov    rax,QWORD PTR [rbp-0x8]
   0x[PII_REDACTED]40116d <+59>:    xor    rax,QWORD PTR fs:0x28
   0x[PII_REDACTED]401176 <+68>:    je     0x40117d <main+75>
   0x[PII_REDACTED]401178 <+70>:    call   0x401030 <__stack_chk_fail@plt>
```

Let's actually take a look at the stack canary in memory:

```
Breakpoint 1, 0x[PII_REDACTED]401168 in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────── registers ────
$rax   : 0x00007fffffffdfde  →  0x7fffffffe0d0000a
$rbx   : 0x0               
$rcx   : 0xfbad2288        
$rdx   : 0x00007fffffffdfde  →  0x7fffffffe0d0000a
$rsp   : 0x00007fffffffdfd0  →  0x[PII_REDACTED]401180  →  <__libc_csu_init+0> push r15
$rbp   : 0x00007fffffffdff0  →  0x[PII_REDACTED]401180  →  <__libc_csu_init+0> push r15
$rsi   : 0x00007ffff7fb2590  →  0x[PII_REDACTED]000000
$rdi   : 0x0               
$rip   : 0x[PII_REDACTED]401168  →  <main+54> nop
$r8    : 0x00007ffff7fb2580  →  0x[PII_REDACTED]000000
$r9    : 0x00007ffff7fb7500  →  0x00007ffff7fb7500  →  [loop detected]
$r10   : 0x00007ffff7fafca0  →  0x[PII_REDACTED]405660  →  0x[PII_REDACTED]000000
$r11   : 0x246             
$r12   : 0x[PII_REDACTED]401050  →  <_start+0> xor ebp, ebp
$r13   : 0x00007fffffffe0d0  →  0x[PII_REDACTED]000001
$r14   : 0x0               
$r15   : 0x0               
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdfd0│+0x0000: 0x[PII_REDACTED]401180  →  <__libc_csu_init+0> push r15 ← $rsp
0x00007fffffffdfd8│+0x0008: 0x000a[PII_REDACTED]05
0x00007fffffffdfe0│+0x0010: 0x00007fffffffe0d0  →  0x[PII_REDACTED]000001
0x00007fffffffdfe8│+0x0018: 0x92105577ff879300
0x00007fffffffdff0│+0x0020: 0x[PII_REDACTED]401180  →  <__libc_csu_init+0> push r15 ← $rbp
0x00007fffffffdff8│+0x0028: 0x00007ffff7df1b6b  →  <__libc_start_main+235> mov edi, eax
0x00007fffffffe000│+0x0030: 0x[PII_REDACTED]000000
0x00007fffffffe008│+0x0038: 0x00007fffffffe0d8  →  0x00007fffffffe3f7  →  "/tmp/tryc"
─────────────────────────────────────────────────────────────── code:x86:64 ────
     0x401159 <main+39>        mov    rdi, rax
     0x40115c <main+42>        call   0x401040 <fgets@plt>
     0x401161 <main+47>        mov    DWORD PTR [rbp-0x18], 0x5
 →   0x401168 <main+54>        nop    
     0x401169 <main+55>        mov    rax, QWORD PTR [rbp-0x8]
     0x40116d <main+59>        xor    rax, QWORD PTR fs:0x28
     0x401176 <main+68>        je     0x40117d <main+75>
     0x401178 <main+70>        call   0x401030 <__stack_chk_fail@plt>
     0x40117d <main+75>        leave  
─────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "tryc", stopped, reason: BREAKPOINT
───────────────────────────────────────────────────────────────────── trace ────
[#0] 0x401168 → main()
────────────────────────────────────────────────────────────────────────────────
gef➤  x/g $rbp-0x8
0x7fffffffdfe8:    0x92105577ff879300
```

Here we can see is the stack canary. We can tell that it is the stack canary from several different things. Firstly it is the value being used when it is doing the stack canary check. Also it is around the spot on the stack it should be. Also it matches the pattern of a stack canary. While they are random they do fit a general pattern.

For `x64` elfs, the pattern is an `0x8` byte qword, where the first seven bytes are random and the last byte is a null byte.

For `x86` elfs, the pattern is a `0x4` byte dword, where the first three bytes are random and the last byte is a null byte.

Let's change the value of the canary and see what happens!

```
gef➤  x/g $rbp-0x8
0x7fffffffdfe8:    0x92105577ff879300
gef➤  set *0x7fffffffdfe8 = 0x0
gef➤  x/g $rbp-0x8
0x7fffffffdfe8:    0x[PII_REDACTED]000000
gef➤  c
Continuing.
*** stack smashing detected ***: <unknown> terminated
```

As we can see, it saw that the value of the canary changed and it terminated the process.

So what's the bypass? If we need to overwrite the stack canary, then we