Smash The Stack: IO Level 5 Walkthrough

Level 5 of the Smash The Stack IO wargame presents a classic stack-based buffer overflow scenario. Executing the binary simply echoes the supplied command-line argument: level5@io:/levels$ ./level05 test test Analyzing the Source Code The source file level05.c shows an unbounded strcpy into a fixed 128-byte stack buffer: #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buf[128]; if (argc < 2) return 1; strcpy(buf, argv[1]); printf("%s\n", buf); return 0; } Because strcpy() copies until it hits a null byte without checking the destination bounds of buf[128], an argument exceeding 128 bytes overwrites adjacent stack data, including the saved base pointer (EBP) and return address (EIP). ...

December 3, 2014 · 2 min · 344 words · Ahmad Mahfouz

Smash The Stack: IO Level 4 Walkthrough

In Level 4 of the Smash The Stack IO wargame, executing the binary prints a static welcome message regardless of input arguments: level4@io:/levels$ ./level04 Welcome level5 level4@io:/levels$ ./level04 $(python -c "print 'A' * 1024") Welcome level5 Analyzing the Source Code Inspecting level04.c: #include <stdio.h> #include <stdlib.h> int main() { char username[1024]; FILE* f = popen("whoami", "r"); fgets(username, sizeof(username), f); printf("Welcome %s", username); return 0; } Vulnerability Analysis: Insecure PATH Resolution Notice the popen call: FILE* f = popen("whoami", "r"); The author called whoami as a bare command name rather than specifying an absolute binary path (such as /usr/bin/whoami). When popen() spawns /bin/sh -c whoami, the shell searches for the whoami executable in the directories listed in the current user’s PATH environment variable from left to right. ...

December 3, 2014 · 1 min · 206 words · Ahmad Mahfouz

Smash The Stack: IO Level 2 Walkthrough

In Level 2 of the Smash The Stack IO wargame, source code is provided directly in level02.c: level2@io:/levels$ cat level02.c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <setjmp.h> void catcher(int a) { setresuid(geteuid(), geteuid(), geteuid()); printf("WIN!\n"); system("/bin/sh"); exit(0); } int main(int argc, char **argv) { puts("source code is available in level02.c\n"); if (argc != 3 || !atoi(argv[2])) return 1; signal(SIGFPE, catcher); return abs(atoi(argv[1])) / atoi(argv[2]); } Analyzing the Code The Target (catcher): The catcher function sets the real, effective, and saved UID to the effective UID (geteuid()) and drops into /bin/sh. This triggers when the program receives a SIGFPE signal. Input Validation: The check if (argc != 3 || !atoi(argv[2])) ensures two arguments are passed and argv[2] does not evaluate to 0. This explicitly prevents standard division-by-zero errors. The Division: The function returns abs(atoi(argv[1])) / atoi(argv[2]). Understanding SIGFPE and Two’s Complement Overflow In C on 32-bit x86 systems, a signed 32-bit integer ranges from -2,147,483,648 (INT_MIN / 0x80000000) to +2,147,483,647 (INT_MAX / 0x7FFFFFFF). ...

December 1, 2014 · 2 min · 261 words · Ahmad Mahfouz

Smash The Stack: IO Level 1 Walkthrough

In this challenge on the Smash The Stack IO wargame, the binaries are located under /levels. Let’s inspect the target binary for Level 1: level1@io:/levels$ ls -alh level01 -r-sr-x--- 1 level2 level1 1.2K Jan 13 2014 level01 Notice the permissions: -r-sr-x--- with the SUID bit set for level2. Executing this binary successfully will spawn a process with level2 privileges. Initial Execution Running the program prompts for a passcode: level1@io:/levels$ ./level01 Enter the 3 digit passcode to enter: 838 Providing an arbitrary number exits silently with no output. ...

December 1, 2014 · 2 min · 287 words · Ahmad Mahfouz