From f7a695cce74cdab7e1f9a0c4c615246536284739 Mon Sep 17 00:00:00 2001 From: Urval Date: Tue, 7 Apr 2026 23:39:47 +0530 Subject: [PATCH] Final push all version fixex --- .github/workflows/build.yml | 23 +++ .gitignore | 13 ++ Makefile | 21 +-- README.md | 277 ++++++++++++-------------------- archive/main.c | 13 ++ archive/stack_behavior_demo.c | 11 ++ docs/advanced-concepts.md | 31 ++++ docs/demo.md | 191 ++++++++++++++++++++++ docs/gdb-guide.md | 134 +++++++++------ docs/images/README.md | 15 ++ docs/images/control-flow.png | Bin 0 -> 19004 bytes docs/images/gdb-session.png | Bin 0 -> 28724 bytes docs/images/overflow-output.png | Bin 0 -> 14053 bytes docs/lab-exercises.md | 206 ++++++++++++++++++++++++ docs/protections.md | 59 +++++++ src/control_flow_simulation.c | 52 ++++++ src/main.c | 120 -------------- src/overflow_behavior_demo.c | 42 +++++ src/safe_input_demo.c | 27 ++++ src/stack_layout_demo.c | 31 ++++ src/vuln_buffer_overflow.c | 24 +++ 21 files changed, 938 insertions(+), 352 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 archive/main.c create mode 100644 archive/stack_behavior_demo.c create mode 100644 docs/advanced-concepts.md create mode 100644 docs/demo.md create mode 100644 docs/images/README.md create mode 100644 docs/images/control-flow.png create mode 100644 docs/images/gdb-session.png create mode 100644 docs/images/overflow-output.png create mode 100644 docs/lab-exercises.md create mode 100644 docs/protections.md create mode 100644 src/control_flow_simulation.c delete mode 100644 src/main.c create mode 100644 src/overflow_behavior_demo.c create mode 100644 src/safe_input_demo.c create mode 100644 src/stack_layout_demo.c create mode 100644 src/vuln_buffer_overflow.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e83f0ef --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,23 @@ +name: Build + +on: [push, pull_request] + +jobs: + compile: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install GCC + run: | + sudo apt-get update + sudo apt-get install -y gcc + + - name: Compile all lab programs + run: | + gcc -Wall -Wextra -Werror src/vuln_buffer_overflow.c -o vuln_buffer_overflow + gcc -Wall -Wextra -Werror src/safe_input_demo.c -o safe_input_demo + gcc -Wall -Wextra -Werror src/stack_layout_demo.c -o stack_layout_demo + gcc -Wall -Wextra -Werror src/overflow_behavior_demo.c -o overflow_behavior_demo + gcc -Wall -Wextra -Werror src/control_flow_simulation.c -o control_flow_simulation diff --git a/.gitignore b/.gitignore index e8e8365..cbbf398 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,17 @@ vuln_lab vuln_lab.exe vuln_lab_test vuln_lab_test.exe +stack_behavior_demo +stack_behavior_demo.exe +vuln_buffer_overflow +vuln_buffer_overflow.exe +safe_input_demo +safe_input_demo.exe +stack_layout_demo +stack_layout_demo.exe +overflow_behavior_demo +overflow_behavior_demo.exe +control_flow_simulation +control_flow_simulation.exe +*.exe *.o diff --git a/Makefile b/Makefile index ed28068..87fb4dd 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,20 @@ CC = gcc CFLAGS = -Wall -Wextra -g -O0 -TARGET = vuln_lab -SRC = src/main.c +VERIFY_CFLAGS = -Wall -Wextra -Werror +SRC_DIR = src +PROGRAMS = vuln_buffer_overflow safe_input_demo stack_layout_demo overflow_behavior_demo control_flow_simulation -.PHONY: all run clean +.PHONY: all verify clean -all: $(TARGET) +all: $(PROGRAMS) -$(TARGET): $(SRC) - $(CC) $(CFLAGS) -o $(TARGET) $(SRC) +$(PROGRAMS): %: $(SRC_DIR)/%.c + $(CC) $(CFLAGS) -o $@ $< -run: $(TARGET) - ./$(TARGET) +verify: $(addprefix verify-,$(PROGRAMS)) + +verify-%: $(SRC_DIR)/%.c + $(CC) $(VERIFY_CFLAGS) -o $* $< clean: - -$(RM) $(TARGET) $(TARGET).exe + -$(RM) $(PROGRAMS) $(addsuffix .exe,$(PROGRAMS)) diff --git a/README.md b/README.md index c222e15..45f70b2 100644 --- a/README.md +++ b/README.md @@ -1,236 +1,171 @@ -# Exploit Lab (C/C++) - Memory Vulnerability Learning Lab +# Exploit Lab (C/C++) - Safe Memory Vulnerability Learning Lab -This project demonstrates how memory vulnerabilities can appear in C programs and how they affect behavior at the stack level. +> A structured, multi-phase lab for understanding memory vulnerabilities from first principles using safe, controlled demonstrations. -It is a hands-on educational lab focused on understanding and observing memory behavior, not exploitation. +A modular, beginner-friendly lab for understanding memory vulnerability concepts in C through conceptual demonstration and controlled simulation. -## Overview +This project is educational only. It does not include exploit payloads or exploitation instructions. -Memory vulnerabilities are common in low-level languages such as C and C++. -They often happen when a program writes outside intended memory boundaries or does not validate input size. +## What This Lab Covers -This lab helps you learn: -- How unsafe input handling can cause problems -- How stack memory is laid out for local variables -- How to inspect behavior with GDB -- How safer input handling reduces risk +- Unsafe vs safe input handling +- Stack memory layout observation +- Overflow behavior observation (controlled) +- Conceptual control-flow redirection using function pointers +- Practical debugging with GDB +- Runtime protection concepts (ASLR, NX, stack canaries) -## What Are Memory Vulnerabilities? +## Core Programs (5) -A memory vulnerability happens when code incorrectly reads or writes memory. - -Example of unsafe input: - -```c -char buffer[16]; -scanf("%s", buffer); /* No size limit */ -``` - -If the input is longer than the buffer, nearby memory can be overwritten. -Possible outcomes include: -- Unexpected variable value changes -- Program instability -- Crashes -- Undefined behavior - -## What This Program Demonstrates - -### 1. Safe vs Unsafe Input Handling -- `unsafe_input(...)` uses unbounded `%s` input to show risk -- `safe_input(...)` uses `fgets(...)` with buffer limits - -### 2. Memory Layout Observation - -The program prints addresses of: -- `buffer` -- local variable `x` -- function parameter (`demo_id`) - -This helps visualize how stack variables are typically stored close together. - -### 3. Stack Behavior - -You can observe: -- Relative ordering of local variables in stack memory -- Address changes across runs (commonly due to ASLR) -- Similar local layout patterns between runs - -### 4. Controlled Overflow Observation - -In unsafe mode, very long input may: -- Trigger warning messages -- Change nearby variable values unexpectedly -- Crash the program - -This is used to observe undefined behavior in a controlled, educational context. - -### 5. Debugging With GDB - -Use GDB to: -- Set breakpoints -- Step through execution -- Print local variables -- Inspect register state - -See [docs/gdb-guide.md](docs/gdb-guide.md) for the full walkthrough. +1. `vuln_buffer_overflow` - unsafe input pattern demonstration +2. `safe_input_demo` - bounded input with `fgets(...)` +3. `stack_layout_demo` - stack address observation +4. `overflow_behavior_demo` - controlled overflow behavior observation +5. `control_flow_simulation` - conceptual control-flow redirection ## Project Structure ```text exploit-lab-cpp/ |-- src/ -| `-- main.c +| |-- vuln_buffer_overflow.c +| |-- safe_input_demo.c +| |-- stack_layout_demo.c +| |-- overflow_behavior_demo.c +| `-- control_flow_simulation.c +|-- archive/ +| |-- main.c +| `-- stack_behavior_demo.c |-- docs/ | |-- gdb-guide.md -| `-- memory-layout.md +| |-- memory-layout.md +| |-- protections.md +| |-- advanced-concepts.md +| |-- lab-exercises.md +| |-- demo.md +| `-- images/ |-- Makefile `-- README.md ``` -## Requirements - -- GCC -- GDB (recommended for debugging) -- `make` (optional; you can compile directly with `gcc`) - -## Build and Run +## Build -### Build With Make +Compile all core programs: ```bash make ``` -### Build Manually (if `make` is not available) +## Manual Compilation (No Make) + +If `make` is not available, compile each program directly: ```bash -gcc -Wall -Wextra -g -O0 -o vuln_lab src/main.c +gcc src/vuln_buffer_overflow.c -o vuln_buffer_overflow +gcc src/safe_input_demo.c -o safe_input_demo +gcc src/stack_layout_demo.c -o stack_layout_demo +gcc src/overflow_behavior_demo.c -o overflow_behavior_demo +gcc src/control_flow_simulation.c -o control_flow_simulation ``` -### Run +## Verification (Quick Check) -Linux/macOS: +Run this to verify setup in seconds: ```bash -./vuln_lab +make +./vuln_buffer_overflow ``` Windows (MinGW): ```powershell -.\vuln_lab.exe +make +.\vuln_buffer_overflow.exe ``` -Choose a mode: -- `1` = Unsafe demo -- `2` = Safe demo - -## How to Test Safely +## Quick Sanity Check -Run in a local, controlled environment and use simple test inputs. +1. Safe demo: + - Run `./safe_input_demo` + - Expected: input works normally with no warnings. +2. Overflow demo: + - Run `./overflow_behavior_demo` with long input. + - Expected: warning appears and behavior may change. +3. Control flow demo: + - Run `./control_flow_simulation`. + - Expected: output changes before/after pointer reassignment. -### Normal input +## Run Commands -Example: +Linux/macOS: -```text -hello +```bash +./vuln_buffer_overflow +./safe_input_demo +./stack_layout_demo +./overflow_behavior_demo +./control_flow_simulation ``` -Expected: -- No warning -- Stable behavior - -### Long input - -Example: +Windows (MinGW): -```text -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +```powershell +.\vuln_buffer_overflow.exe +.\safe_input_demo.exe +.\stack_layout_demo.exe +.\overflow_behavior_demo.exe +.\control_flow_simulation.exe ``` -Expected in unsafe demo: -- Warning about input length (in many runs) -- Possible variable corruption -- Possible crash +## Learning Path -Expected in safe demo: -- Input is bounded by `fgets(...)` -- No out-of-bounds write from input read +1. Start with `vuln_buffer_overflow` (unsafe behavior). +2. Compare with `safe_input_demo` (bounded input). +3. Run `stack_layout_demo` and observe address relationships. +4. Run `overflow_behavior_demo` with long input and observe effects. +5. Run `control_flow_simulation` to understand conceptual redirection. +6. Use GDB to inspect variables, stack state, and registers. -## Example Output (Unsafe Demo) +## Lab Exercises -```text -Address of buffer: 0x7ffd1234... -Address of x: 0x7ffd1240... -Address of parameter demo_id: 0x7ffd1250... -Value of x before input: 10 -... -WARNING: Input length (...) exceeds buffer capacity (15). -Nearby stack values may be corrupted (undefined behavior). -Value of x after input: ... -``` - -## GDB Quick Start - -```bash -gdb ./vuln_lab -``` +Step-by-step exercises: +- [docs/lab-exercises.md](docs/lab-exercises.md) -Useful commands: +## Demo Guide -```gdb -break main -run -step -next -print buffer -info locals -info registers -``` +Commands + sample outputs: +- [docs/demo.md](docs/demo.md) -More details: [docs/gdb-guide.md](docs/gdb-guide.md) +## Protection Mechanisms -## Core Concepts You Learn +Beginner explanation of ASLR, NX bit, and stack canaries: +- [docs/protections.md](docs/protections.md) -- Stack memory basics -- Safe vs unsafe input handling -- Why buffer size checks matter -- Undefined behavior and why it is dangerous -- Basic debugging workflow in GDB +## Advanced Concepts (Theory Only) -## How to Prevent Memory Vulnerabilities +Conceptual overview of stack smashing, shellcode, and ROP: +- [docs/advanced-concepts.md](docs/advanced-concepts.md) -- Prefer bounded input APIs like `fgets` -- Validate input lengths before processing -- Avoid unbounded input patterns like `scanf("%s", ...)` -- Compile with warnings enabled (`-Wall -Wextra`) -- Keep security protections enabled in real applications +## Debugging Guide -## Disclaimer +Current GDB workflow for modular binaries: +- [docs/gdb-guide.md](docs/gdb-guide.md) -This project is for education only. -Do not use these concepts on systems you do not own or have explicit permission to test. +## Demo Assets -## Learning Outcomes +Screenshots and visual captures: +- `docs/images/` +- `docs/images/gdb-session.png` +- `docs/images/overflow-output.png` +- `docs/images/control-flow.png` -After completing this lab, you should be able to: -- Identify unsafe input handling patterns -- Explain basic stack layout for local variables -- Observe and reason about undefined behavior -- Use GDB to inspect program state -- Write safer C input-handling code +## Safety and Scope -## Future Improvements +- Educational use only. +- Focused on understanding behavior and prevention. +- No exploit payloads, no exploitation walkthroughs. -- Add heap memory safety examples -- Add format-string safety module -- Add small guided debugging exercises -- Add diagrams for function stack frames - -## Contributing +## Disclaimer -Contributions are welcome: -- Improve docs and explanations -- Add beginner-friendly exercises -- Improve platform-specific run notes +Do not test on systems you do not own or have explicit permission to analyze. diff --git a/archive/main.c b/archive/main.c new file mode 100644 index 0000000..6d5fbf1 --- /dev/null +++ b/archive/main.c @@ -0,0 +1,13 @@ +/* + * Deprecated placeholder. + * + * This file is intentionally kept empty for compatibility with environments + * that currently lock file deletion/rename operations. + * + * Active lab programs are the modular demos in: + * - src/vuln_buffer_overflow.c + * - src/safe_input_demo.c + * - src/stack_layout_demo.c + * - src/overflow_behavior_demo.c + * - src/control_flow_simulation.c + */ diff --git a/archive/stack_behavior_demo.c b/archive/stack_behavior_demo.c new file mode 100644 index 0000000..d5e386d --- /dev/null +++ b/archive/stack_behavior_demo.c @@ -0,0 +1,11 @@ +/* + * Deprecated placeholder. + * + * This file is intentionally inactive. The project now uses five focused + * core programs: + * - vuln_buffer_overflow + * - safe_input_demo + * - stack_layout_demo + * - overflow_behavior_demo + * - control_flow_simulation + */ diff --git a/docs/advanced-concepts.md b/docs/advanced-concepts.md new file mode 100644 index 0000000..30eb5de --- /dev/null +++ b/docs/advanced-concepts.md @@ -0,0 +1,31 @@ +# Advanced Concepts (Theory Only) + +This file explains higher-level security concepts in simple terms. +It is conceptual only and does not include exploit code. + +## 1) Stack Smashing (Conceptual) + +- Stack smashing means writing past a local stack buffer into nearby stack data. +- Nearby data can include local variables, saved frame information, and return-control data. +- If return-control data is corrupted, execution may jump to an unintended location. +- Even small out-of-bounds writes can create unstable or unpredictable behavior. +- Modern systems add protections (canaries, ASLR, NX), but unsafe writes are still bugs. +- The key learning point is prevention: use bounded input and validate sizes. + +## 2) Shellcode (Conceptual) + +- Shellcode is a historical term for byte sequences intended to run as machine instructions. +- In older vulnerable setups, attackers tried to place these bytes in writable memory. +- Modern systems typically mark stack/heap as non-executable (NX), blocking this path. +- This concept matters for understanding why executable vs non-executable memory matters. +- In secure development, the priority is preventing memory corruption in the first place. +- This lab does not build, inject, or execute shellcode. + +## 3) Return-Oriented Programming (ROP) (Conceptual) + +- ROP is a technique that reuses short existing instruction sequences already in a program. +- Instead of injecting new code, it chains existing code snippets conceptually. +- ROP became relevant as protections like NX made direct code injection harder. +- Address randomization (ASLR) makes reliable chaining more difficult in practice. +- Understanding ROP is useful for threat awareness, not for implementation here. +- This lab keeps ROP as theory only and focuses on safe fundamentals. diff --git a/docs/demo.md b/docs/demo.md new file mode 100644 index 0000000..db815c3 --- /dev/null +++ b/docs/demo.md @@ -0,0 +1,191 @@ +# Demo Guide + +This is a quick, clean walkthrough for running the core memory lab demos. + +## 1) Setup + +Compile all core programs: + +```bash +make +``` + +Windows (MinGW) note: +- Use `.\\program.exe` instead of `./program`. + +## 2) Run Each Core Lab + +### Lab 1: Unsafe Input Behavior + +Run: + +```bash +./vuln_buffer_overflow +``` + +Example output: + +```text +[vuln_buffer_overflow] Unsafe input demo +Enter a word: AAAAAAAAAAAAAAAAAAAAA +You entered: AAAAAAAAAAAAAAAAAAAAA +``` + +What you will see: +- Input is accepted without explicit length limits. +- Long input can produce unstable behavior in unsafe programs. + +### Lab 2: Safe Input Demo + +Run: + +```bash +./safe_input_demo +``` + +Example output: + +```text +[safe_input_demo] Safe input demo +Enter text: hello +You entered safely: hello +``` + +What you will see: +- `fgets(...)` reads with a size boundary. +- Behavior is safer and more predictable. + +### Lab 3: Stack Layout Demo + +Run: + +```bash +./stack_layout_demo +``` + +Example output: + +```text +[stack_layout_demo] Stack address observation +Address of main_local: 0x7ff... +Address of buffer: 0x7ff... +Address of x: 0x7ff... +Address of parameter demo_id: 0x7ff... +``` + +What you will see: +- Local addresses are often close together. +- Absolute addresses may change between runs. + +### Lab 4: Overflow Behavior Demo + +Run: + +```bash +./overflow_behavior_demo +``` + +Example output: + +```text +[overflow_behavior_demo] Observe behavior with long input +Value of x before input: 10 +Enter input: WARNING: Input length (30) exceeds buffer capacity (15). +Behavior may be unstable (undefined behavior). +Value of x after input: 1094795585 +Buffer content: AAAAAAAAAAAAAAAA... +``` + +Clean beginner-friendly version: + +```text +User types: AAAAAAAAAAAAAAAA +Output: +Value of x before input: 10 +WARNING: Input exceeds buffer size +Value of x after input: 1094795585 +``` + +What you will see: +- Warning for oversized input. +- Possible unstable values because overflow is undefined behavior. + +### Lab 5: Control Flow Simulation + +Run: + +```bash +./control_flow_simulation +``` + +Example output: + +```text +[control_flow_simulation] Conceptual control-flow demo +Address of safe_function: 00401460 +Address of target_function: 00401475 +Address of func_ptr var: 0061FF1C + +Calling through function pointer (before change): +safe_function(): normal control flow path. + +Simulating conceptual pointer corruption by manual reassignment... +Calling through function pointer (after change): +target_function(): alternate control flow path. +``` + +What you will see: +- Changing function pointer target changes executed function. +- This is a controlled simulation, not real memory corruption. + +Visual proof: +- `docs/images/overflow-output.png` +- `docs/images/control-flow.png` + +### Lab 6: Debugging with GDB (Optional but Recommended) + +Start with `stack_layout_demo`: + +```bash +gdb ./stack_layout_demo +``` + +Useful commands: + +```gdb +break main +run +next +step +info locals +info registers +``` + +What you will see: +- Line-by-line execution state. +- Variable and register values during runtime. + +Visual proof: +- `docs/images/gdb-session.png` + +## 3) What This Teaches + +- Why unbounded input is risky. +- How bounded input reduces risk. +- How stack variables are arranged in memory. +- Why undefined behavior is dangerous. +- How control flow concepts can be taught safely. + +## 4) Screenshot Evidence + +### GDB Session + +![GDB session](images/gdb-session.png) + +### Overflow Output + +![Overflow output](images/overflow-output.png) + +### Control Flow Simulation + +![Control flow simulation](images/control-flow.png) diff --git a/docs/gdb-guide.md b/docs/gdb-guide.md index 12576a3..749ce45 100644 --- a/docs/gdb-guide.md +++ b/docs/gdb-guide.md @@ -1,96 +1,126 @@ -# GDB Beginner Guide (Memory Learning Lab) +# GDB Guide (Current Multi-File Lab) -This guide helps you inspect program state while learning safe vs unsafe memory handling. +This guide uses the current modular binaries: +- `stack_layout_demo` +- `overflow_behavior_demo` -## 1. Compile With Debug Symbols +## 1. Build With Debug Symbols -Debug symbols let GDB map machine code back to your C source code and variable names. +Use the project Makefile: ```bash -gcc -g -Wall -Wextra -O0 -o vuln_lab src/main.c +make ``` -If you use the project Makefile, it already includes `-g` and `-O0`. - -## 2. Start GDB +Or compile specific targets manually: ```bash -gdb ./vuln_lab +gcc -Wall -Wextra -g -O0 -o stack_layout_demo src/stack_layout_demo.c +gcc -Wall -Wextra -g -O0 -o overflow_behavior_demo src/overflow_behavior_demo.c ``` -## 3. Core GDB Commands +Why `-g` and `-O0` matter: +- `-g` gives GDB variable and line information. +- `-O0` avoids heavy optimization so variables are easier to inspect. -Set a breakpoint at program entry: +## 2. GDB on stack_layout_demo -```gdb -break main +Start debugger: + +```bash +gdb ./stack_layout_demo ``` -Run the program: +Useful flow: ```gdb +break main run +next +step +info locals +print main_local ``` -Execute the next line (without stepping into function calls): +What to inspect: +- `main_local` in `main()` +- addresses printed by `print_stack_layout(...)` + +Example address checks: ```gdb -next +break print_stack_layout +run +print &demo_id +print &x +print &buffer +info registers ``` -Step into the next function call: +What this teaches: +- local variables and parameters are placed in the function stack frame +- addresses are often close together +- exact addresses can vary between runs -```gdb -step +## 3. GDB on overflow_behavior_demo + +Start debugger: + +```bash +gdb ./overflow_behavior_demo ``` -Print a variable value: +Set breakpoints around unsafe input: ```gdb -print choice -print buffer +break main +run +next +next ``` -Show all local variables in the current function: +Step until you reach the `scanf("%s", buffer)` line, then inspect: ```gdb +print x +print &x +print &buffer info locals ``` -Show CPU register values: +Continue after input and inspect again: ```gdb -info registers +next +next +print x +print input_len +info locals ``` -## 4. Memory Concepts (Beginner-Friendly) - -### What Is The Stack? - -The stack is a memory region used for function calls. -When a function starts, it gets a stack frame that stores local data (like `char buffer[16]`) and bookkeeping data for returning to the caller. - -### How Local Variables Are Stored - -Local variables are usually stored inside the current stack frame. -That is why printing a local buffer address (for example, with `printf("%p", (void *)buffer)`) helps you see where that variable lives in memory during execution. +What this teaches: +- `x` and `buffer` are neighboring local values in stack memory +- oversized input can lead to undefined behavior +- observed outcomes can vary by run and environment -### Why Buffer Size Matters +## 4. Core GDB Commands (Quick Reference) -A buffer has a fixed capacity. -If input writes more bytes than the buffer can hold, memory outside the buffer can be overwritten. This is called a buffer overflow and can cause crashes or undefined behavior. - -Safe input APIs such as `fgets(buffer, sizeof(buffer), stdin)` limit how many bytes are written, helping prevent overflow. +```gdb +break main +run +next +step +print x +print buffer +print &buffer +info locals +info registers +continue +quit +``` -## 5. Suggested Practice +## 5. Beginner Practice Path -1. Run program normally: - - `./vuln_lab` -2. Start debugger: - - `gdb ./vuln_lab` -3. Try these commands: - - `break main` - - `run` - - `step` - - `print buffer` - - `info registers` +1. Run `stack_layout_demo` in GDB and inspect variable addresses. +2. Run `overflow_behavior_demo` in GDB and inspect `x`, `buffer`, and `input_len`. +3. Compare runs to see what stays similar (relative layout) and what changes (absolute addresses). diff --git a/docs/images/README.md b/docs/images/README.md new file mode 100644 index 0000000..59431f8 --- /dev/null +++ b/docs/images/README.md @@ -0,0 +1,15 @@ +# Demo Screenshots + +Real captured outputs are available: + +- `gdb-session.png` - GDB breakpoint, locals, and register snapshot +- `overflow-output.png` - overflow behavior run with long input +- `control-flow.png` - control flow simulation before/after pointer change + +Supporting raw transcripts: + +- `gdb-session.txt` +- `overflow-output.txt` +- `control-flow-output.txt` + +Note: older placeholder files may remain due file-lock restrictions in this environment; use the PNG files above as the canonical visuals. diff --git a/docs/images/control-flow.png b/docs/images/control-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..7188008a6f133917ce6ecac86951793cd66e70cc GIT binary patch literal 19004 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 literal 0 HcmV?d00001 diff --git a/docs/images/overflow-output.png b/docs/images/overflow-output.png new file mode 100644 index 0000000000000000000000000000000000000000..5c04223dd0d1e75aa0ce41e4d07ada72c2003f5a GIT binary patch literal 14053 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 SLFB}Mt2TCj)?EDS!T$ovkD#;w literal 0 HcmV?d00001 diff --git a/docs/lab-exercises.md b/docs/lab-exercises.md new file mode 100644 index 0000000..b0a735d --- /dev/null +++ b/docs/lab-exercises.md @@ -0,0 +1,206 @@ +# Lab Exercises (Beginner-Friendly) + +These exercises help you practice memory-safety concepts step by step. +Each lab includes: +- what to run +- what to observe +- what it means + +## Lab 1: Unsafe Input Behavior + +### What to run + +Build: + +```bash +make vuln_buffer_overflow +``` + +Run: + +Linux/macOS: + +```bash +./vuln_buffer_overflow +``` + +Windows (MinGW): + +```powershell +.\vuln_buffer_overflow.exe +``` + +Try entering a long input string. + +### What to observe + +- Program behavior with normal input vs long input +- Whether output becomes unstable or unexpected + +### What it means + +`scanf("%s", ...)` does not limit input length. +If input is longer than the buffer, memory outside the buffer may be overwritten (undefined behavior). + +## Lab 2: Safe vs Unsafe Comparison + +### What to run + +Build both: + +```bash +make safe_input_demo vuln_buffer_overflow +``` + +Run each program and enter similar inputs: + +- short input (for example: `hello`) +- long input (for example: many `A` characters) + +### What to observe + +- `safe_input_demo` remains stable because input is bounded +- `vuln_buffer_overflow` may behave unpredictably with long input + +### What it means + +Bounded input functions like `fgets(...)` reduce overflow risk. +Unbounded input patterns are dangerous in C. + +## Lab 3: Stack Memory Layout + +### What to run + +Build: + +```bash +make stack_layout_demo +``` + +Run: + +Linux/macOS: + +```bash +./stack_layout_demo +``` + +Windows (MinGW): + +```powershell +.\stack_layout_demo.exe +``` + +### What to observe + +- Printed addresses for local variables and function parameters +- Addresses are often close together +- Re-running may change absolute addresses + +### What it means + +Local variables are typically placed in the current stack frame. +Relative ordering is often similar, while exact addresses can change between runs (for example, due to ASLR). + +## Lab 4: Overflow Behavior + +### What to run + +Build: + +```bash +make overflow_behavior_demo +``` + +Run and enter a long string: + +Linux/macOS: + +```bash +./overflow_behavior_demo +``` + +Windows (MinGW): + +```powershell +.\overflow_behavior_demo.exe +``` + +### What to observe + +- Value of variable `x` before and after input +- Warning message for oversized input +- Possible instability depending on run/environment + +### What it means + +When input exceeds buffer size, nearby memory may be affected. +This is undefined behavior, so outcomes are not guaranteed. + +## Lab 5: Control Flow Simulation + +### What to run + +Build: + +```bash +make control_flow_simulation +``` + +Run: + +Linux/macOS: + +```bash +./control_flow_simulation +``` + +Windows (MinGW): + +```powershell +.\control_flow_simulation.exe +``` + +### What to observe + +- Function pointer calls `safe_function()` first +- After reassignment, the same pointer calls `target_function()` +- Printed function addresses and pointer variable address + +### What it means + +Control flow depends on which code address is used. +This lab safely demonstrates redirection conceptually through normal reassignment, not memory corruption. + +## Lab 6: Debugging with GDB + +### What to run + +Use GDB on any demo program (example: `stack_layout_demo`): + +```bash +gdb ./stack_layout_demo +``` + +Useful commands inside GDB: + +```gdb +break main +run +next +step +info locals +print x +info registers +``` + +### What to observe + +- Program state line by line +- Current variable values +- Register changes during execution + +### What it means + +GDB helps you see how C code maps to runtime behavior. +This is essential for understanding memory layout, variable lifetimes, and debugging unsafe behavior. diff --git a/docs/protections.md b/docs/protections.md new file mode 100644 index 0000000..8f3b375 --- /dev/null +++ b/docs/protections.md @@ -0,0 +1,59 @@ +# Runtime Protections (Beginner Guide) + +Modern systems include security protections to make memory bugs harder to abuse. +These protections reduce risk, but they do not replace safe coding. + +## 1. ASLR (Address Space Layout Randomization) + +What it does: +- ASLR places important memory regions (stack, heap, libraries) at different addresses each run. + +Why addresses change between runs: +- The operating system intentionally randomizes where things are loaded. +- So an address you see in one run is often different in the next run. + +How it helps: +- Attackers cannot easily rely on fixed memory addresses. +- This makes many memory-abuse attempts less reliable. + +## 2. NX Bit (Non-Executable Memory) + +What it does: +- NX marks some memory areas as data-only, not executable code. + +What it prevents: +- It blocks running injected bytes as machine code from places like the stack. + +Why stack code execution is blocked: +- The stack is usually marked non-executable on modern systems. +- Even if unsafe data is written there, the CPU refuses to execute it as code. + +## 3. Stack Canaries + +What they are: +- A small secret value placed on the stack near sensitive control data. + +How they detect buffer overflow: +- If a buffer overflow overwrites past a local buffer, it often changes the canary too. +- Before returning from a function, the program checks whether the canary changed. +- If changed, the program stops because stack corruption is detected. + +## How These Protections Help Prevent Memory Exploitation + +- ASLR makes target addresses unpredictable. +- NX blocks executing data from non-executable memory regions. +- Stack canaries detect many stack overwrites before normal return flow continues. + +Together, they add layered defense and make memory exploitation much harder. + +## Why This Lab Still Works Conceptually + +This lab focuses on understanding memory behavior and safe vs unsafe coding patterns. +Even when real systems have protections, the core concepts are still important: + +- Buffers still have fixed sizes. +- Out-of-bounds writes are still bugs. +- Undefined behavior is still dangerous. + +In other words, protections reduce impact, but they do not make unsafe code safe. +That is why this lab may conceptually ignore or simplify protections while teaching fundamentals. diff --git a/src/control_flow_simulation.c b/src/control_flow_simulation.c new file mode 100644 index 0000000..d142b84 --- /dev/null +++ b/src/control_flow_simulation.c @@ -0,0 +1,52 @@ +#include + +/* + * safe_function: + * Default control-flow target in this demo. + */ +static void safe_function(void) { + printf("safe_function(): normal control flow path.\n"); +} + +/* + * target_function: + * Alternate function used to show how changing a function pointer + * changes which code executes. + */ +static void target_function(void) { + printf("target_function(): alternate control flow path.\n"); +} + +int main(void) { + /* + * A function pointer stores an address of executable code. + * Calling through this pointer transfers control to the function + * currently stored in it. + */ + void (*func_ptr)(void) = safe_function; + + printf("[control_flow_simulation] Conceptual control-flow demo\n"); + printf("Address of safe_function: %p\n", (void *)safe_function); + printf("Address of target_function: %p\n", (void *)target_function); + printf("Address of func_ptr var: %p\n", (void *)&func_ptr); + + printf("\nCalling through function pointer (before change):\n"); + func_ptr(); + + /* + * Conceptual simulation: + * We manually reassign the function pointer to a different function. + * This is a safe, explicit reassignment (not memory corruption). + * + * In real stack-smashing scenarios, overwritten return addresses can + * redirect execution unexpectedly. This demo only illustrates the idea + * of control-flow redirection without exploit code. + */ + printf("\nSimulating conceptual pointer corruption by manual reassignment...\n"); + func_ptr = target_function; + + printf("Calling through function pointer (after change):\n"); + func_ptr(); + + return 0; +} diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 470501d..0000000 --- a/src/main.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -/* - * Memory Vulnerability Learning Lab - * - * This file demonstrates unsafe and safe ways to read user input. - * The unsafe version is kept for education only. - */ - -void unsafe_input(int demo_id) { - char buffer[16]; - int x = 10; - size_t input_len = 0; - - printf("\n[UNSAFE DEMO] Enter your name: "); - printf("Address of buffer: %p\n", (void *)buffer); - printf("Address of x: %p\n", (void *)&x); - printf("Address of parameter demo_id: %p\n", (void *)&demo_id); - printf("Value of x before input: %d\n", x); - - /* - * These addresses are locations of variables inside this function's - * stack frame (current function call memory). - * - * Typical behavior on many systems: - * - The stack grows downward (from higher to lower addresses). - * - Local variables and parameters are often stored near each other. - * - * Exact order can vary by compiler, architecture, and optimization level. - */ - - /* - * DANGEROUS: - * "%s" with scanf() does not limit input length. - * If the user types more than 15 characters (+ '\0'), - * it can write past buffer boundaries (buffer overflow). - * - * Important learning point: - * this read happens before any length check below, so the overflow - * (if it occurs) may already have corrupted nearby stack data. - */ - if (scanf("%s", buffer) != 1) { - printf("Input error.\n"); - return; - } - - input_len = strlen(buffer); - if (input_len >= sizeof(buffer)) { - printf("WARNING: Input length (%lu) exceeds buffer capacity (%lu).\n", - (unsigned long)input_len, - (unsigned long)(sizeof(buffer) - 1)); - printf("Nearby stack values may be corrupted (undefined behavior).\n"); - } - - printf("Value of x after input: %d\n", x); - printf("You entered (unsafe path): %s\n", buffer); -} - -void safe_input(int demo_id) { - char buffer[16]; - int x = 10; - - printf("\n[SAFE DEMO] Enter your name: "); - printf("Address of buffer: %p\n", (void *)buffer); - printf("Address of x: %p\n", (void *)&x); - printf("Address of parameter demo_id: %p\n", (void *)&demo_id); - - /* - * Same stack concept as the unsafe demo: - * buffer, x, and demo_id belong to this function call context. - * Their addresses help visualize how stack memory is laid out. - */ - - /* - * SAFER: - * fgets() receives the buffer size, so it reads at most - * sizeof(buffer) - 1 characters and always terminates with '\0'. - * This prevents writing beyond the buffer. - */ - if (fgets(buffer, sizeof(buffer), stdin) == NULL) { - printf("Input error.\n"); - return; - } - - /* Remove trailing newline (if present) for cleaner output. */ - buffer[strcspn(buffer, "\n")] = '\0'; - - printf("You entered (safe path): %s\n", buffer); -} - -int main(void) { - char choice_line[8]; - int choice = 0; - - printf("Memory Handling Lab\n"); - printf("1 = Unsafe input demo\n"); - printf("2 = Safe input demo\n"); - printf("Choose an option: "); - - if (fgets(choice_line, sizeof(choice_line), stdin) == NULL) { - printf("Failed to read choice.\n"); - return 1; - } - - if (sscanf(choice_line, "%d", &choice) != 1) { - printf("Invalid choice.\n"); - return 1; - } - - if (choice == 1) { - unsafe_input(choice); - } else if (choice == 2) { - safe_input(choice); - } else { - printf("Invalid option. Use 1 or 2.\n"); - } - - return 0; -} diff --git a/src/overflow_behavior_demo.c b/src/overflow_behavior_demo.c new file mode 100644 index 0000000..e3816dc --- /dev/null +++ b/src/overflow_behavior_demo.c @@ -0,0 +1,42 @@ +#include +#include + +/* + * Overflow behavior observation demo (educational only). + * + * This intentionally keeps an unsafe read to demonstrate that + * out-of-bounds writes can lead to undefined behavior. + * No exploit logic is included. + */ +int main(void) { + char buffer[16]; + int x = 10; + size_t input_len = 0; + + printf("[overflow_behavior_demo] Observe behavior with long input\n"); + printf("Value of x before input: %d\n", x); + printf("Enter input: "); + + /* + * Unsafe: no width limit is provided. + * If input exceeds buffer capacity, overflow may happen before + * the length check below can run. + */ + if (scanf("%s", buffer) != 1) { + printf("Input error.\n"); + return 1; + } + + input_len = strlen(buffer); + if (input_len >= sizeof(buffer)) { + printf("WARNING: Input length (%lu) exceeds buffer capacity (%lu).\n", + (unsigned long)input_len, + (unsigned long)(sizeof(buffer) - 1)); + printf("Behavior may be unstable (undefined behavior).\n"); + } + + printf("Value of x after input: %d\n", x); + printf("Buffer content: %s\n", buffer); + + return 0; +} diff --git a/src/safe_input_demo.c b/src/safe_input_demo.c new file mode 100644 index 0000000..0c8de82 --- /dev/null +++ b/src/safe_input_demo.c @@ -0,0 +1,27 @@ +#include +#include + +/* + * Safe input demo. + * + * fgets() receives the buffer size, so it reads at most + * sizeof(buffer) - 1 characters and prevents buffer overflow + * from this input operation. + */ +int main(void) { + char buffer[16]; + + printf("[safe_input_demo] Safe input demo\n"); + printf("Enter text: "); + + if (fgets(buffer, sizeof(buffer), stdin) == NULL) { + printf("Input error.\n"); + return 1; + } + + /* Remove trailing newline for cleaner output. */ + buffer[strcspn(buffer, "\n")] = '\0'; + + printf("You entered safely: %s\n", buffer); + return 0; +} diff --git a/src/stack_layout_demo.c b/src/stack_layout_demo.c new file mode 100644 index 0000000..e6b2ffe --- /dev/null +++ b/src/stack_layout_demo.c @@ -0,0 +1,31 @@ +#include + +/* + * Stack layout demo. + * + * Prints addresses of local variables and a function parameter + * to help visualize how function-call memory is arranged. + */ +static void print_stack_layout(int demo_id) { + char buffer[16]; + int x = 10; + + /* + * These addresses are typically in the current stack frame. + * On many systems, the stack often grows downward + * (from higher addresses toward lower addresses). + */ + printf("Address of buffer: %p\n", (void *)buffer); + printf("Address of x: %p\n", (void *)&x); + printf("Address of parameter demo_id: %p\n", (void *)&demo_id); +} + +int main(void) { + int main_local = 1; + + printf("[stack_layout_demo] Stack address observation\n"); + printf("Address of main_local: %p\n", (void *)&main_local); + print_stack_layout(42); + + return 0; +} diff --git a/src/vuln_buffer_overflow.c b/src/vuln_buffer_overflow.c new file mode 100644 index 0000000..a1044c0 --- /dev/null +++ b/src/vuln_buffer_overflow.c @@ -0,0 +1,24 @@ +#include + +/* + * Unsafe buffer input demo (educational only). + * + * WARNING: + * scanf("%s", ...) does not enforce a maximum length. + * If input is longer than the buffer, memory past the buffer + * may be overwritten. + */ +int main(void) { + char buffer[16]; + + printf("[vuln_buffer_overflow] Unsafe input demo\n"); + printf("Enter a word: "); + + if (scanf("%s", buffer) != 1) { + printf("Input error.\n"); + return 1; + } + + printf("You entered: %s\n", buffer); + return 0; +}