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 execstack
which 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.