
Lecture 1: Introduction to Exploitation
In this lecture, we’ll lay the foundation for understanding software exploitation by breaking down complex security concepts into clear, intuitive ideas. You’ll learn what an exploit is, how vulnerabilities evolve into full attack chains, and why memory corruption bugs are still among the most dangerous flaws in modern systems.
We’ll also explore different categories of software vulnerabilities — including configuration, logic, and code-level bugs — and focus on the types that lead to control flow hijacking. By the end, you’ll understand the basic landscape of exploitation and the security mechanisms designed to stop it, including ASLR, NX-bit, and stack canaries.
By the end of this lecture, you’ll be able to:
Define what makes a vulnerability exploitable
Identify common bug classes targeted in memory corruption
Understand the anatomy of an attack chain
Recognize the role of mitigations and how they raise the bar for attackers
Build the foundational knowledge needed to move into the deep-dive, hands-on sections that follow
Section 2: Stack Overflows & Security Mitigations
In this section, we dive into one of the most fundamental — and still highly relevant — memory corruption techniques: the classic stack overflow. You’ll learn how the stack works across modern architectures, how buffer overflows lead to control flow hijacking, and how modern defenses try to stop them.
We’ll walk through a real example payload step-by-step — from triggering an overflow to executing malicious code — giving you practical insight into how attackers gain control. Then, you’ll learn how mitigations like ASLR, NX-bit, and stack canaries work in practice, and where their limitations lie.
By the end of this section, you’ll be able to:
Understand how the stack works and how function calls use memory
Identify stack-based vulnerabilities and trace overflow behavior
Walk through a real-world buffer overflow payload and see how execution is hijacked
Use GDB to analyze memory and debug exploit attempts
Understand how defenses like NX-bit, ASLR, and stack canaries block common attacks
Build confidence to move into more advanced exploitation topics like ROP and heap manipulation
In this hands-on lab, you’ll craft a basic stack overflow exploit to overwrite a return address and hijack control flow. Use the downloadable PDF and follow the guided steps to complete the exercise.
Lecture 1: ROP Made Simple – Step-by-Step Exploitation and CFI Basics
In this lecture, we take one of the most advanced exploitation techniques — Return-Oriented Programming (ROP) — and make it approachable. You’ll learn how attackers build payloads from existing instructions (gadgets) to bypass protections like the NX bit and execute code without injecting shellcode.
We’ll introduce ROP through real-world analogies that simplify its logic and mechanics, and then walk through the structure of a ROP chain step by step. Finally, we’ll explore the concept of Control Flow Integrity (CFI), how it attempts to stop ROP attacks, and where its limitations lie.
By the end of this lecture, you’ll be able to:
Understand what ROP is and why it’s used to bypass non-executable memory protections
Break down how ROP chains are constructed from existing code gadgets
Visualize how control flow is hijacked without injecting new code
Understand the concept of Control Flow Integrity and how it mitigates ROP
Prepare to get hands-on experience locating gadgets that form the foundation of real-world ROP chains
In this hands-on lab, you'll learn how to use ROPgadget to scan and analyze ELF binaries for useful gadget sequences — the building blocks of Return-Oriented Programming (ROP). You'll compile a simple vulnerable C program, discover key gadgets like pop rdi; ret, and explore how to chain them to redirect execution to a target function.
We'll also cover how to search for gadgets in libc, and optionally, compare results using Ropper, another powerful ROP analysis tool.
This lab is about understanding how attackers locate and assemble code reuse chains in modern binaries.
By the end of this lab, you’ll be able to:
Install and run ROPgadget on ELF binaries
Locate critical gadgets like pop rdi; ret and ret
Understand how gadgets are used to build ROP chains
Analyze gadgets in both your binary and linked libraries (libc)
Optionally explore Ropper as an alternative analysis tool
Lecture Description:
In this lecture, we explore heap exploitation — a powerful technique used to corrupt memory beyond the stack. You’ll learn how dynamic memory is managed in Linux systems (with a focus on SLUB), how heap layout affects exploitation, and how vulnerabilities can be abused to gain control over sensitive data like function pointers.
We'll walk through a real example of triggering a heap-based overflow, using a technique known as heap spraying to shape the memory layout, and ultimately hijacking a function pointer to execute arbitrary code.
This lecture sets the stage for the hands-on lab, where you'll build and exploit a simple heap vulnerability in practice.
By the end of this lecture, you’ll be able to:
Develop the core mindset and intuition needed to recognize exploit paths and shape the heap effectively for real-world attacks
Understand the basics of how heap allocation works in Linux (kmalloc and SLUB)
Recognize how overflows can affect adjacent heap objects
Learn what makes an object a good “target” for corruption
Visualize the impact of heap spraying and layout manipulation
Get ready to build your own heap exploit in the lab that follows
Hands-On Lab – Linux Heap Exploitation with Struct and Function Pointer Override
In this hands-on lab, you’ll exploit a heap-based buffer overflow in a C program to hijack a function pointer. Using heap spraying, you’ll manipulate the memory layout to place a “target” object adjacent to a vulnerable one. By overflowing a buffer, you’ll overwrite the function pointer and redirect execution to a chosen address — simulating a real-world control flow hijack.
You’ll use tools like readelf to extract addresses and Python’s struct.pack to craft your payload — all within a 32-bit Linux environment.
By the end of this lab, you’ll be able to:
Write and compile a vulnerable C program using structs and function pointers
Perform heap spraying to control memory layout
Trigger a heap overflow to overwrite a function pointer
Redirect execution to a chosen function (e.g., win())
Connect these fundamentals to real-world heap exploitation techniques
Learn how real-world software exploits work — and how attackers use them to break into systems, bypass protections, and take control.
In this hands-on course, you’ll go beyond theory and gain the skills to understand, analyze, and craft memory corruption exploits. You'll explore techniques like stack overflows, Return-Oriented Programming (ROP), and heap spraying — all using real C code, modern Linux targets, and guided labs that connect every concept to practice.
We break down complex topics using intuitive explanations, visual examples, and real-world analogies to make advanced exploitation techniques both accessible and actionable.
Whether you're a security researcher, defender, reverse engineer, or developer looking to level up your exploitation skills, investigate the "how" behind critical CVEs, or take your first steps into the security world — this course will equip you with the deep understanding and attacker mindset needed to analyze vulnerabilities and understand how modern mitigations are bypassed.
What You’ll Learn:
How attack vectors and chains unfold — and how they map to real-world exploits
How ROP chains are constructed from gadgets to bypass NX-bit
How to manipulate heap layout and corrupt function pointers
The purpose and limitations of modern mitigations like ASLR, NX, canaries, and CFI
How stack overflows work and how they’re used to hijack execution
How to think like an attacker — and defend like one too
Hands-On Labs Include:
Writing and exploiting a classic stack overflow
Using GDB and Python to craft real payloads
Finding ROP gadgets with ROPgadget and analyzing their purpose
Performing heap spraying and overriding function pointers in a custom binary