Counter measure

You can find a script to check in this repo: https://github.com/slimm609/checksec.sh.

/checksec -f ~/ch20
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX disabled   No PIE          No RPATH   No RUNPATH   Yes 0       6   /challenge/app-systeme/ch20/ch20
app-systeme-ch20@challenge02:/tmp/_check$ ./checksec -ff ~/ch20
* FORTIFY_SOURCE support available (libc)    : Yes
* Binary compiled with FORTIFY_SOURCE support: Yes

 ------ EXECUTABLE-FILE ------- . -------- LIBC --------
 Fortifiable library functions | Checked function names
 -------------------------------------------------------
 printf                         | __printf_chk
 printf                         | __printf_chk
 fgets                          | __fgets_chk
 fgets                          | __fgets_chk
 memset                         | __memset_chk
 memset                         | __memset_chk

SUMMARY:

* Number of checked functions in libc                : 76
* Total number of library functions in the executable: 98
* Number of Fortifiable functions in the executable : 6
* Number of checked functions in the executable      : 0
* Number of unchecked functions in the executable    : 6

NX

Avoid trivial execution of shellcodes from the stack marking the pages as not executable

Canary

The implementation of the function __stack_chk_fail() is the following

/* Note how buffer overruns are undefined behavior and the compilers tend to
   optimize these checks away if you wrote them yourself, this only works
   robustly because the compiler did it itself. */
extern uintptr_t __stack_chk_guard;
noreturn void __stack_chk_fail(void);
void foo(const char* str)
{
    uintptr_t canary = __stack_chk_guard;
    char buffer[16];
    strcpy(buffer, str);
    if ( (canary = canary ^ __stack_chk_guard) != 0 )
        __stack_chk_fail();
}

with the value of __stack_chk_guard put into a static address that you can find reading a core dump

ASLR

When a process is mapped in memory, the addresses of heap are shifted of a random amount with a mask

Linux ASLR can be configured through /proc/sys/kernel/randomize_va_space. The following values are supported:

  • No randomization. Everything is static.
  • Conservative randomization. Shared libraries, stack, mmap(), VDSO and heap are randomized.
  • Full randomization. In addition to elements listed in the previous point, memory managed through brk() is also randomized.

RELRO