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.
Binary Exploitation Learning Path
Previous: Basic ret2win Buffer Overflow - Learn the fundamentals of return address hijacking
Next Steps:
- ret2libc ROP Attack (No ASLR) - Bypass NX protection when the stack is non-executable
- ASLR Bypass with Libc Leak - Defeat address randomization
- Format String GOT Overwrite Attack - Alternative exploitation technique
-- 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.