Locating Environment Variable Memory Addresses for Exploit Payloads

When exploiting buffer overflows in space-constrained stack frames (e.g., when the vulnerable buffer is only 20 or 30 bytes), you cannot fit a standard 50-byte shellcode payload directly on the stack. A classic exploitation technique is ret2env: injecting the shellcode into an environment variable (export EGG=...) and redirecting execution to its address located near the high end of the process address space. Why Addresses Shift Environment variables reside at the top of the user stack directly below the initial stack frame. Because the program name (argv[0]) is pushed onto the stack immediately following the environment pointer (envp), the exact address of an environment variable depends slightly on the length of the binary name: ...

December 4, 2014 · 2 min · 280 words · Ahmad Mahfouz

Duplicate File Finder via Cryptographic Hashes in Python

Redundant and duplicated files consume valuable disk capacity and complicate backup management. Because identical files often have different names or modification timestamps, simple filename comparisons are insufficient. By computing cryptographic checksums (MD5 or SHA-256) for each file’s binary content, we can reliably group and identify duplicate files across extensive filesystem trees. Python Duplicate File Scanner This script traverses the target directory recursively, calculates chunked cryptographic checksums to minimize memory usage, and prompts interactively to safely delete redundant copies. ...

December 4, 2014 · 2 min · 387 words · Ahmad Mahfouz

TrueCrypt / VeraCrypt Password Auditing via Dictionary Automation

Encrypted disk containers generated by TrueCrypt (and modern successors like VeraCrypt) do not contain detectable headers or magic bytes. The container appears indistinguishable from random noise, protecting against forensic identification. During forensic investigations or lost credential recovery, if specialized GPU cracking tools (such as Hashcat or John the Ripper) are unavailable, you can audit container passwords using a headless CLI mounting script. Python Dictionary Testing Script (tc_crack.py) This script iterates through a wordlist, attempting non-interactive mount commands against the target container file until a successful exit status is returned: ...

December 4, 2014 · 2 min · 284 words · Ahmad Mahfouz

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

Underc0de 3 Boot2Root Walkthrough: LFI, Python Cron Command Injection, and SUID Binary Exploitation

Underc0de 3 is a vulnerable Boot2Root virtual machine designed for penetration testing practice. The attack chain spans web reconnaissance, encoded Local File Inclusion (LFI), credential discovery, cronjob command injection, and final privilege escalation via an SUID buffer overflow. Phase 1: Network Reconnaissance and Port Scanning Identify the target VM using netdiscover or arp-scan: Target IP: 192.168.1.112 Run a full Nmap service scan: nmap -sS -sV -p- -T4 192.168.1.112 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.0p1 Debian 4+deb7u2 25/tcp open smtp Postfix smtpd 80/tcp open http Apache httpd 2.2.22 (Debian) Phase 2: Web Reconnaissance & Base64-Encoded LFI Directory enumeration using dirb reveals an /ascii/ folder and /index.html. Inspecting the HTML source reveals a hidden comment: ...

December 3, 2014 · 3 min · 485 words · Ahmad Mahfouz

Smash The Stack: IO Level 3 Walkthrough

In Level 3 of the Smash The Stack IO wargame, passing a large argument quickly causes a segmentation fault: level3@io:/levels$ ./level03 $(python -c "print 'A' * 1000") Segmentation fault Analyzing the Source Code The source file level03.c is provided in /levels: #include <stdio.h> #include <string.h> #include <unistd.h> void good() { puts("Win."); execl("/bin/sh", "sh", NULL); } void bad() { printf("I'm so sorry, you're at %p and you want to be at %p\n", bad, good); } int main(int argc, char **argv, char **envp) { void (*functionpointer)(void) = bad; char buffer[50]; if (argc != 2 || strlen(argv[1]) < 4) return 0; memcpy(buffer, argv[1], strlen(argv[1])); memset(buffer, 0, strlen(argv[1]) - 4); printf("This is exciting we're going to %p\n", functionpointer); functionpointer(); return 0; } Vulnerability Analysis Target Function: good() spawns a privileged shell via execl("/bin/sh", ...). Buffer and Function Pointer: main() allocates a 50-byte buffer (char buffer[50]) and initializes a function pointer pointing to bad(). Unbounded Copy: memcpy(buffer, argv[1], strlen(argv[1])) copies the entire input into buffer without checking against its 50-byte bound. Partial Clear: memset(buffer, 0, strlen(argv[1]) - 4) zeroes out buffer up to strlen(argv[1]) - 4. The last 4 bytes of our input remain untouched in memory. Execution: The program invokes functionpointer(). If we overflow buffer such that the trailing 4 bytes align precisely over functionpointer, we redirect execution to good(). Finding Addresses and Offset in GDB Disassemble and locate the address of good(): ...

December 1, 2014 · 2 min · 352 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

Encrypting and Decrypting Files with GnuPG (GPG)

GnuPG (GPG) is a complete implementation of the OpenPGP standard (RFC 4880). It allows you to encrypt data either symmetrically (using a shared passphrase) or asymmetrically (using public/private key pairs). When you need to protect sensitive documents (such as financial records, credentials, or backups) before sending them over email or untrusted channels, symmetric GPG encryption provides strong, zero-infrastructure security. Symmetric Encryption with a Passphrase To encrypt a file symmetrically using a password: ...

November 24, 2014 · 1 min · 212 words · Ahmad Mahfouz