โ† Back to Portfolio
CS 647 - Counter Hacking Techniques Lab Assessment Report

Merry Lab: Stack Buffer Overflow
Return Address Subversion

Exploiting an unsafe string copy operation to hijack control flow and retrieve restricted data.

AuthorPercy Flores
InstitutionNJIT
CourseCS 647 - Fall 2025
Lab TargetMerry (retAddr3 application)
Vulnerability ClassCWE-121: Stack-based Buffer Overflow
Outcomeโœ“ Execution Hijacked
Abstract

This report outlines the methodology I used to successfully exploit a stack-based buffer overflow in the retAddr3 binary. By utilizing the GNU Debugger (GDB), I identified an unsafe strcpy() operation and reverse-engineered the program's memory layout to calculate the specific offset needed to reach the saved Return Instruction Pointer (RIP). I subsequently constructed an exact 108-byte padding payload followed by the little-endian address of a hidden getFlag function. The crafted exploit achieved arbitrary control flow redirection and yielded the system flag.

ยง 1

Environment Setup & Constraints

For this specific pedagogical lab, modern memory protections were intentionally disabled to provide a deterministic environment. This simulates older systems or legacy embedded devices where such mitigations might be unavailable.

Protection MechanismStatusImplication
ASLR (Address Space Layout Randomization)DisabledMemory addresses remain static across executions.
SSP (Stack Smashing Protection / Canaries)DisabledNo runtime detection of buffer overwrites.
DEP/NX (Data Execution Prevention)DisabledStack memory is executable.
ยง 2

Vulnerability Analysis

2.1 Execution & Disassembly

Initial interaction with the program revealed that it accepted a command-line argument. Supplying an excessively long string caused the program to crash, strongly indicating a buffer overflow.

BASH - SEGMENTATION FAULT
merry@lab:~$ ./retAddr3 $(python3 -c "print('A' * 200)")
Segmentation fault (core dumped)

I utilized gdb to disassemble the binary. Upon inspecting the main function, I discovered a call to the notoriously unsafe strcpy(), which does not perform bounds checking before copying the user-provided argument into a fixed-size stack buffer.

2.2 Locating the Hidden Target

Using the info functions command in GDB, I identified an undocumented function named getFlag. My objective was to redirect execution flow to this exact address.

GDB - MEMORY ADDRESS IDENTIFICATION
(gdb) print getFlag
$1 = {<text variable, no debug info>} 0x565563c2 <getFlag>

The target address to hijack execution is 0x565563c2.

ยง 3

Payload Development & Exploitation

3.1 Offset Calculation

To successfully hijack execution, I needed to precisely overwrite the saved return address on the stack. I generated a cyclic pattern and fed it into the program within GDB to observe exactly which bytes overwrote the instruction pointer (EIP).

Through iterative testing and stack inspection, I determined that the exact distance from the start of the buffer to the saved return address was exactly 108 bytes.

3.2 Payload Construction

The final payload must consist of 108 bytes of random padding (character 'A'), immediately followed by the target memory address. Because the underlying x86 architecture is little-endian, the address was packed in reverse byte order:

EXPLOIT STRUCTURE
[ 108 Bytes of Padding ("A"x108) ] + [ Target Address (0x565563c2) ]
                                     โ†ช \xc2\x63\x55\x56 (Little Endian)

3.3 Execution

Using Perl to effortlessly generate the binary payload sequence, I injected it into the application as a command-line argument.

BASH - FINAL EXPLOIT
merry@lab:~$ ./retAddr3 $(perl -e 'print "A"x108 . "\xc2\x63\x55\x56"')
Success! Here is your flag:
merryflag{st4ck_sm4sh1ng_c0mpl3t3}
Segmentation fault (core dumped)
โœ…

Return Flow Hijacked

Execution successfully redirected to the hidden function. The subsequent segmentation fault is expected as the stack frame was entirely corrupted post-execution.

ยง 4

Defensive Mitigations

To prevent this class of vulnerability, the following changes must be implemented:

  1. Replace Unsafe Functions: The obsolete strcpy() function should be immediately replaced with boundary-checked alternatives such as strncpy() or strlcpy().
  2. Enable Stack Smashing Protection (SSP): Compiling with -fstack-protector places a randomized canary value adjacent to the return pointer. If the buffer overflows, the canary is corrupted, and the program halts safely before executing the hijacked pointer.
  3. Enable Address Space Layout Randomization (ASLR): Activating ASLR at the OS level prevents attackers from hardcoding target memory addresses like 0x565563c2, as the addresses randomize on every execution.

Appendix: Raw Execution Evidence

The following are the raw screenshots captured during the original execution of this lab on the target VM network.

Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot Raw Execution Screenshot