Elf binaries do not enforce secure binary properties là gì năm 2024

Recently when trying to solve a pwn challenge I used pwndbg checksec, to get to know the security properties of the executable.

With this article I want to sum up what each of the “features” imply, what and why are they used, against which attacks they protect and for the developer, which compiler options in clang and gcc cause these features to be in the binary. Even check out, what is set to be the default in these 2 compilers.

Besides checksec there is another lesser known binary, that does something similar to checksec. hardening-check which checks binaries for security hardening features. It needs to be installed with: sudo apt-get install devscript. After installation your can check any executable:

hardening-check /bin/ls /bin/ls: Position Independent Executable: yes Stack protected: yes Fortify Source functions: yes [some protected functions found] Read-only relocations: yes Immediate binding: no, not found! Stack clash protection: unknown, no -fstack-clash-protection instructions found Control flow integrity: no, not found!

If you dnt have checksec installed from pwntools you can do it by ‘python3 -m pip install — upgrade pwntools’. checksec from pwntools looks like this [and in color] :

pwn checksec — file /bin/ls [*] ‘/bin/ls’ Arch: amd64–64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled FORTIFY: Enabled

We notice a difference in the output. In the checkse “control flow integrity” is missing.

  1. ] RELRO: Will be put into a post of its own as we need to have knowledge of how dynamic linking works in ELF binaries ٩[๏_๏]۶

2.] Stack Canary: A stack Canary is a “secret value” placed on the stack which changes every time the program is started. Before a function returns, the stack canary is checked and if it appears to be tampered with, the program exits immeadiately. Stack cookies can be leaked with the help of e.g format string vulnerabilities. They are a defense mechanism against stack buffer overflows

The 3 types of canaries available by StackGuard are:

  • Terminator canaries : a canary that contains NULL[0x00], CR [0x0d], LF [0x0a], and EOF [0xff]. These bytes mostly terminate most string operations in C [depends on the function used aka read[] vs strcpy[]]
  • Random canaries : just a random number uknown to the attacker
  • random XOR canaries: XOR of a random value and the saved return address.

GCC and stack protection:

-fstack-protector -fstack-protector-all -fstack-protector-strong -fstack-protector-explicit

clang and stack protection:

Clang supports mostly the same flags as GCC and in Clang 13 we have SafeStack.

SafeStack is an instrumentation pass that protects programs against attacks based on stack buffer overflows, without introducing any measurable performance overhead

clang --help | grep stack-protector -fno-stack-protector Disable the use of stack protectors -fstack-protector-all Force the usage of stack protectors for all functions -fstack-protector-strong -fstack-protector Enable stack protectors for functions potentially vulnerable to stack smashing

3.] NX: In a Von-Neumann-Architecture code and data is not seperated, thats why data, if this bit is not set can be executed,like data that has been put on the stack. It is short for “No eXecute” aka “Data Execution Prevention” or DEP. It marks areas of the program as non executable. This implies that stored input or data cannot be executed as code. . This is significant because it prevents attackers from being able to call custom shellcode that they have stored on the stack or in a global variable.

GCC: -z,noexecstack

Clang: ??

4.] PIE aka “Position Independent Executable”:

This indicates that the executable was built in such a way [PIE] that the ``text’’ section of the program can be relocated in memory. To take full advantage of this feature, the executing kernel must support text Address Space Layout Randomization [ASLR].

A question that always appears then is: “Difference between pic Vs pie”

GCC

clang: -fPIC and -fPIE but be sure to use -target [eg x86_64 otherwise it might silently drop PIE/PIC] so sth like: ‘-fpie -target x86_64’

Side note on defaults GCC vs CLANG here:

  • clang print.c -o print_clang
  • gcc print.c -o print_gcc

Watch out for the defaults for the PIE setting on Linux! [⊙.☉]7

This is based on "clang — version" --> Debian clang version 11.0.1–2

On *BSD it produces “PIE” by default.

5.] FORTIFY aka use Fortify Source functions.

FORTIFY_SOURCE is a GCC and GLIBC security feature that attempts to detect certain classes of buffer overflows. Its enabled by default on most Linux platforms.-> //stackoverflow.com/tags/fortify-source/info

and in depth discussion here: “Enhance application security with FORTIFY_SOURCE”

GCC: -­D_FORTIFY_SOURCE=2

CLANG: same as GCC but “But do we get the extra protection?”

6.] Control flow integrity, will be put in another post too, as for this some more background is needed too ٩[๏_๏]۶

Chủ Đề