Shellcode Injection Buffer Overflow: Beyond ret2win
Challenge 2: Simple Shellcode Buffer Overflow (2_simple.c)
Source Code:
#include <stdio.h>
int main() {
char name[64] = {0};
read(0, name, 150); // reading too much input so we can return to win()
printf("Your name is %s", name);
return 0;
}
// Now we have to create shellcode
// Compiled: gcc -Wall -Wextra -Iinclude -g -fno-stack-protector -z execstack -no-pie -Wl,-z,norelro -o bin/2_simple src/2_simple.c
What it does:
This is a buffer overflow challenge that requires shellcode injection since there's no win() function.
Vulnerability:
- Allocates a 64-byte buffer for
name - Uses
read(0, name, 150)which reads 150 bytes into a 64-byte buffer - This allows 86 bytes of overflow past the buffer boundary
- Unlike challenge 1, there's no convenient
win()function to return to
Other Functions That Can Cause Similar Buffer Overflows:
Input Functions:
gets()- reads until newline with no bounds checkingscanf("%s", buffer)- no bounds checking on string inputstrcpy(dest, src)- no bounds checking when copying stringsstrcat(dest, src)- concatenates without checking destination sizesprintf(buffer, format, ...)- can overflow if format string is too long
Example vulnerable code patterns:
char buffer[64];
gets(buffer); // Dangerous - no bounds check
scanf("%s", buffer); // Dangerous - no bounds check
strcpy(buffer, long_string); // Dangerous - no bounds check
sprintf(buffer, "%s", long_str); // Dangerous - no bounds check
Why shellcode injection works here:
- All these functions can be exploited in the same way when combined with:
- Executable stack (
-z execstack) - Disabled stack protector (
-fno-stack-protector) - No ASLR/PIE (
-no-pie)
- Executable stack (
Safer alternatives:
fgets(buffer, sizeof(buffer), stdin)instead ofgets()scanf("%63s", buffer)to limit input sizestrncpy()andstrncat()with proper size limitssnprintf()with buffer size specified
Exploitation:
- Since there's no
win()function, we need to inject our own shellcode - The executable stack (
-z execstack) allows code execution from the stack - Payload structure: shellcode + padding + return address pointing to shellcode
Compilation:
gcc -Wall -Wextra -Iinclude -g -fno-stack-protector -z execstack -no-pie -Wl,-z,norelro -o bin/2_simple src/2_simple.c
Security mitigations disabled:
- Same as challenge 1, with the key difference being
-z execstackwhich is crucial for shellcode execution
Key Differences:
- Challenge 1: ret2win technique - redirect execution to existing
win()function - Challenge 2: Shellcode injection - inject and execute custom assembly code
Both challenges use identical compilation flags that disable modern security protections, making them ideal for learning basic buffer overflow exploitation techniques.
-- Try it yourself with my Github Repo - Exploit Development Step-by-Step There you are able to check the whole code and also the full exploit script.