Windows Memory Layout: A Security Researcher's Guide
Thilan Dissanayaka Exploit Development May 08, 2020

Windows Memory Layout: A Security Researcher's Guide

If you want to exploit software, analyze malware, or reverse engineer binaries on Windows, there’s one thing you need to understand before anything else — how memory is laid out. Where does the code live? Where’s the stack? Where does the heap start? What’s the PEB, and why does every piece of malware walk its module lists?

Every buffer overflow, every ROP chain, every process injection technique is built on top of a mental model of how memory is organized. If that model is wrong or incomplete, you’re flying blind.

In this post, we’ll walk through the Windows process memory layout from top to bottom — what each region is, why it exists, how to inspect it with real tools, and what it means for security research.

Virtual Memory — The Big Picture

Every Windows process gets its own virtual address space. The process thinks it has a flat, contiguous block of memory all to itself, starting from address 0x0. In reality, the OS and hardware collaborate to map these virtual addresses to physical RAM (or disk) through page tables.

This isolation is critical for both stability and security. Process A can’t read Process B’s memory because they have completely different page tables — the same virtual address 0x00400000 maps to different physical memory in each process.

Pages and Permissions

Memory is managed in pages — 4KB (4096 bytes) on x86/x64 by default. Each page has permissions:

Permission Meaning
R (Read) The page can be read
W (Write) The page can be written to
X (Execute) The page can be executed as code
RW Read + Write (typical for data, stack, heap)
RX Read + Execute (typical for code sections)
RWX Read + Write + Execute (dangerous — shellcode target)

Modern Windows almost never creates RWX pages by default. Code pages are RX, data pages are RW. If you see an RWX page in a process, that’s either JIT compilation (like a browser’s JavaScript engine), a packer unpacking itself, or something suspicious.

32-bit vs 64-bit Address Space

On 32-bit Windows, the address space is 4GB:

  • User mode: 0x000000000x7FFFFFFF (2GB)
  • Kernel mode: 0x800000000xFFFFFFFF (2GB)

On 64-bit Windows, the theoretical space is 16 exabytes, but only a portion is currently usable:

  • User mode: 0x00000000'000000000x00007FFF'FFFFFFFF (128TB)
  • Kernel mode: 0xFFFF8000'000000000xFFFFFFFF'FFFFFFFF (128TB)

There’s a massive gap in the middle — the “canonical address hole” — where addresses are invalid by hardware design.

The Memory Map — What Lives Where

Here’s a map of a typical 64-bit Windows process, from low addresses to high:

┌─────────────────────────────────────────────────────┐
│  0x00000000'00000000 - 0x00000000'0000FFFF          │
│  NULL Page (64KB) — Unmapped, catches NULL derefs    │
├─────────────────────────────────────────────────────┤
│  0x00000000'00010000+                                │
│  Executable Image (.exe)                             │
│  ┌─────────────────────────────────────────┐        │
│  │ PE Header                               │        │
│  │ .text   (code)           [RX]           │        │
│  │ .rdata  (read-only data) [R]            │        │
│  │ .data   (initialized)    [RW]           │        │
│  │ .bss    (uninitialized)  [RW]           │        │
│  │ .rsrc   (resources)      [R]            │        │
│  └─────────────────────────────────────────┘        │
├─────────────────────────────────────────────────────┤
│  DLLs (ntdll.dll, kernel32.dll, user32.dll, ...)    │
│  Each with their own .text, .data, etc.             │
│  Positions randomized by ASLR                        │
├─────────────────────────────────────────────────────┤
│  Heap(s)                                             │
│  Default process heap + additional heaps             │
│  Grows upward                           [RW]        │
├─────────────────────────────────────────────────────┤
│  Memory-Mapped Files / Shared Memory                 │
│                                                      │
├─────────────────────────────────────────────────────┤
│  Thread Stacks (one per thread)                      │
│  Grow downward                          [RW]        │
├─────────────────────────────────────────────────────┤
│  Thread Environment Blocks (TEBs)                    │
│  Process Environment Block (PEB)                     │
├─────────────────────────────────────────────────────┤
│  0x00007FFF'FFFFFFFF                                 │
│  End of user mode                                    │
├═════════════════════════════════════════════════════┤
│  0xFFFF8000'00000000+                                │
│  Kernel Mode — not accessible from user mode         │
│  (kernel, drivers, SSDT, IDT, etc.)                  │
└─────────────────────────────────────────────────────┘

Let’s explore each region in detail.

The NULL Page

The first 64KB of memory (0x000000000x0000FFFF) is intentionally unmapped. Any access to this region triggers an access violation — the famous “null pointer dereference.”

This exists to catch bugs. When a programmer forgets to check if a pointer is NULL and tries to dereference it, the crash makes the bug obvious. Without this protection, dereferencing NULL would silently read or write to address 0, corrupting memory in ways that are incredibly hard to debug.

From a security perspective, the NULL page also prevents a class of kernel exploits where an attacker maps data at address 0 and tricks a kernel-mode driver into dereferencing a NULL pointer. Modern Windows blocks user-mode allocations at low addresses to prevent this.

The Executable Image — PE Format

When you run a .exe, Windows loads it into memory starting at its preferred base address (traditionally 0x00400000 for 32-bit, though ASLR changes this). The file on disk is a PE (Portable Executable), and understanding its structure is essential.

PE Sections

The PE file is divided into sections, each with a specific purpose and permissions:

Section Contains Permissions Security Relevance
.text Compiled machine code RX Where ROP gadgets live
.rdata Read-only data, import tables, string constants R Contains IAT — a hooking target
.data Initialized global/static variables RW Writable — can store attacker data
.bss Uninitialized global/static variables RW Writable, initially zeroed
.rsrc Resources (icons, dialogs, embedded files) R Malware hides payloads here
.reloc Relocation entries (for ASLR) R Needed for base address randomization

You can inspect these with dumpbin (from Visual Studio) or WinDbg:

0:000> !dh notepad -f

SECTION HEADER #1
   .text name
    8C32 virtual size
    1000 virtual address
    8E00 size of raw data
     400 file pointer to raw data
    ...
  60000020 flags
           Code
           Execute Read

SECTION HEADER #2
  .rdata name
    3A4C virtual size
    A000 virtual address
    ...
  40000040 flags
           Initialized Data
           Read Only

The Import Address Table (IAT)

The IAT is one of the most security-relevant structures in a PE. It’s a table of function pointers — when your program calls CreateFileW, it doesn’t jump directly to the function’s code. Instead, it reads the address from the IAT and jumps there.

Your code:  call [IAT_entry_for_CreateFileW]
IAT entry:  0x00007FFA'12345678  →  points to CreateFileW in kernel32.dll

This indirection makes the IAT a prime target:

  • Malware hooks — Overwrite an IAT entry to redirect API calls through malicious code
  • API monitoring — Debuggers and analysis tools hook the IAT to log function calls
  • Exploitation — Overwriting an IAT entry with system() or a ROP gadget can redirect execution

You can list imports in WinDbg:

0:000> !imports notepad

  kernel32.dll
    00007FF6'B2F0A000  GetModuleHandleW
    00007FF6'B2F0A008  GetProcAddress
    00007FF6'B2F0A010  LoadLibraryW
    00007FF6'B2F0A018  VirtualAlloc
    ...

DLLs — Shared Libraries

Windows processes load dozens of DLLs. Some are always present:

DLL Role Why It Matters
ntdll.dll Lowest user-mode layer, contains syscall stubs The gateway to the kernel. Every syscall goes through here
kernel32.dll Core Win32 API (files, processes, threads) CreateProcess, VirtualAlloc, LoadLibrary — the functions exploits need
kernelbase.dll Implementation behind kernel32 (Win7+) Many kernel32 functions are forwarded here
user32.dll Window management, UI Loaded by any GUI application
msvcrt.dll C runtime library malloc, free, printf, system

DLLs are loaded at base addresses determined by ASLR. Each DLL has its own .text, .data, and .rdata sections, just like the main executable.

From a security research perspective, DLLs are where you find ROP gadgets — small instruction sequences ending in ret that can be chained together to build exploits when DEP prevents direct shellcode execution. Since ntdll.dll and kernel32.dll are loaded in every process, gadgets found in them are universally usable.

0:000> lm
start             end               module name
00007ff6'b2ea0000 00007ff6'b2edf000 notepad
00007ffa'4c8a0000 00007ffa'4ca9e000 ntdll
00007ffa'4b4a0000 00007ffa'4b5a0000 KERNEL32
00007ffa'49c10000 00007ffa'49f70000 KERNELBASE

The Stack

Each thread gets its own stack — typically 1MB by default. The stack is fundamental to how programs execute, and it’s where the most classic exploitation technique lives: the stack buffer overflow.

How the Stack Works

The stack grows downward — from high addresses to low addresses. Every function call pushes data onto the stack:

High Address
┌─────────────────────────────────────┐
│  ...caller's stack frame...          │
├─────────────────────────────────────┤
│  Function arguments (pushed by caller)│
├─────────────────────────────────────┤
│  Return address (pushed by CALL)     │  ◄── This is what buffer overflows target
├─────────────────────────────────────┤
│  Saved EBP/RBP (frame pointer)      │
├─────────────────────────────────────┤
│  Stack cookie / canary               │  ◄── Protection against overflows
├─────────────────────────────────────┤
│  Local variable: char buf[64]        │  ◄── Buffer overflow starts here
├─────────────────────────────────────┤
│  Local variable: int counter         │
├─────────────────────────────────────┤
│  ...                                 │
└─────────────────────────────────────┘
Low Address  (ESP/RSP points here)

A stack buffer overflow writes past the end of buf[64], overwriting the stack cookie, saved frame pointer, and ultimately the return address. When the function returns, it jumps to the attacker-controlled address instead of back to the caller.

Stack Guards

Between the local variables and the saved frame pointer, the compiler inserts a stack cookie (also called a canary or /GS protection in MSVC). This is a random value placed before the return address. Before the function returns, it checks if the cookie has been modified:

// Compiler-generated pseudocode:
void vulnerable_function() {
    int cookie = __security_cookie ^ (int)&cookie;  // Generate canary
    char buf[64];
    gets(buf);  // Overflow!
    if (cookie != (__security_cookie ^ (int)&cookie)) {
        __report_gsfailure();  // Abort — overflow detected!
    }
    return;  // Only reached if canary is intact
}

If an overflow overwrites the return address, it also corrupts the canary. The check fails, and the program terminates before the attacker’s address is used.

You can see the stack in WinDbg:

0:000> k
 # Child-SP          RetAddr           Call Site
00 00000034'fd4ff7e8 00007ffa'4c93a6e0 ntdll!NtWaitForSingleObject+0x14
01 00000034'fd4ff7f0 00007ff6'b2eb1234 ntdll!RtlpWaitOnCriticalSection+0xfc
02 00000034'fd4ff890 00007ff6'b2eb5678 notepad!WinMain+0x1a4
03 00000034'fd4ff920 00007ffa'4b4b7614 notepad!__mainCRTStartup+0x1a0

0:000> !teb
TEB at 00000034fd3fe000
    ExceptionList:        0000000000000000
    StackBase:            00000034fd500000
    StackLimit:           00000034fd4fb000
    ...

The Heap

The heap is where dynamic allocations live — every malloc(), new, HeapAlloc(), and VirtualAlloc() comes from here. Unlike the stack, which is structured and predictable, the heap is a complex, fragmented mess. And that complexity is what makes heap exploitation both powerful and difficult.

Heap Architecture

Windows has a layered heap architecture:

Application
    │
    ▼
malloc() / new / HeapAlloc()
    │
    ▼
NT Heap Manager (ntdll.dll)
    ├── Front End: Low Fragmentation Heap (LFH)
    │     └── For frequent, small allocations (< 16KB)
    └── Back End: Standard heap allocator
          └── For larger or less frequent allocations
    │
    ▼
VirtualAlloc() — for very large allocations (> 512KB)
    │
    ▼
Kernel (NtAllocateVirtualMemory)

Heap Metadata

Every heap allocation has metadata — hidden headers that the heap manager uses to track allocated and freed blocks. These headers are what heap exploits target.

A simplified view of a heap chunk:

┌──────────────────────────────┐
│  Heap chunk header (16 bytes)│  ◄── Size, flags, encoding
├──────────────────────────────┤
│  User data                   │  ◄── What malloc() returns a pointer to
│  (the bytes you requested)   │
├──────────────────────────────┤
│  Padding / alignment         │
└──────────────────────────────┘

In heap exploitation, corrupting these headers can lead to arbitrary write primitives — the ability to write any value to any address — which is typically enough to gain code execution.

Inspecting the Heap

0:000> !heap -s
LFH Key                   : 0x3a7f9d1e2b6c
Termination on corruption : ENABLED

  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR
  0000023a14230000 00000002  1024   512    1024   24    12     1
  0000023a14200000 00001002   64     4      64    2      1     1

0:000> !heap -a 0000023a14230000
    Segment at 0000023a14230000 to 0000023a14330000
    Flags:                00000002
    ForceFlags:           00000000
    Granularity:          16 bytes
    Segment Reserve:      00100000
    ...

Low Fragmentation Heap (LFH)

The LFH activates automatically when the heap manager detects a pattern of similarly-sized allocations (typically after 17+ allocations of the same size bucket). The LFH changes the allocation behavior significantly:

  • Allocations come from buckets of fixed sizes
  • Within a bucket, allocation order is randomized — you can’t predict which slot you’ll get
  • This randomization is a security feature, making heap feng shui (deterministic heap layout manipulation) much harder

This matters for exploitation because reliable heap exploits often depend on controlling the relative positions of allocations. The LFH’s randomization breaks those assumptions.

PEB and TEB — Process and Thread Metadata

These structures are goldmines for both malware and security researchers.

Thread Environment Block (TEB)

Every thread has a TEB — a per-thread data structure accessible via the GS segment register (64-bit) or FS register (32-bit).

// 64-bit: GS:[0x30] points to the TEB itself
// 32-bit: FS:[0x18] points to the TEB itself

TEB Structure (key fields):
┌──────────────────────────────────────────────┐
│  +0x000  ExceptionList         (SEH chain)    │
│  +0x008  StackBase                            │
│  +0x010  StackLimit                           │
│  +0x030  Self (pointer to this TEB)           │
│  +0x060  PEB pointer                          │  ◄── How you find the PEB
│  +0x068  LastErrorValue                       │
│  +0x1478 DeallocationStack                    │
└──────────────────────────────────────────────┘

On 32-bit systems, the Structured Exception Handler (SEH) chain at offset 0x000 was historically a popular exploitation target. Overwriting an SEH handler with a controlled address allowed code execution when an exception was triggered.

Process Environment Block (PEB)

The PEB is a per-process structure that contains critical information about the running process. Accessible from the TEB at offset 0x060 (64-bit) or 0x030 (32-bit).

PEB Structure (key fields):
┌───────────────────────────────────────────────────┐
│  +0x002  BeingDebugged                             │  ◄── Anti-debugging check
│  +0x010  ImageBaseAddress                          │  ◄── Base of the .exe
│  +0x018  Ldr (PEB_LDR_DATA*)                       │  ◄── Loaded module lists
│  +0x020  ProcessParameters                         │  ◄── Command line, env vars
│  +0x030  ProcessHeap                               │  ◄── Default heap handle
│  +0x0EC  NumberOfHeaps                             │
│  +0x0F0  MaximumNumberOfHeaps                      │
│  +0x0F8  ProcessHeaps (array of heap handles)      │
└───────────────────────────────────────────────────┘

Why malware loves the PEB:

Almost every piece of shellcode and malware needs to find the addresses of Windows API functions like LoadLibrary and GetProcAddress. But shellcode can’t use import tables — it’s injected code with no PE structure. So it walks the PEB’s module lists to find loaded DLLs, then parses their export tables to find function addresses.

The classic technique:

1. Access TEB via GS:[0x30] (64-bit)
2. Read PEB pointer at TEB+0x060
3. Read Ldr at PEB+0x018
4. Walk InMemoryOrderModuleList:
   - First entry: the .exe itself
   - Second entry: ntdll.dll
   - Third entry: kernel32.dll  ◄── This is what we want
5. Get kernel32.dll base address
6. Parse its export table to find GetProcAddress
7. Use GetProcAddress to find any other function

In WinDbg:

0:000> !peb
PEB at 0000002b7e4e5000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         00007ff6b2ea0000
    Ldr                       00007ffa4c9d53c0
    Ldr.InLoadOrderModuleList:
        00007ff6'b2ea0000  notepad.exe
        00007ffa'4c8a0000  ntdll.dll
        00007ffa'4b4a0000  KERNEL32.DLL
        00007ffa'49c10000  KERNELBASE.dll
        ...

The BeingDebugged flag at PEB+0x002 is the simplest anti-debugging check. Malware reads this byte — if it’s 1, a debugger is attached, and the malware changes behavior or exits. The Windows API IsDebuggerPresent() literally just reads this byte.

Security Mechanisms

Now let’s look at the protections that make exploiting these memory regions harder.

ASLR — Address Space Layout Randomization

ASLR randomizes the base addresses of:

  • The executable image
  • All loaded DLLs
  • The heap
  • The stack
  • The PEB and TEB

Each time the process starts, everything is at a different location. An exploit that hardcodes jmp 0x7FFA4C901234 will fail because that address is only valid for one specific run.

# Run 1:
kernel32.dll base: 0x00007FFA'4B4A0000

# Run 2:
kernel32.dll base: 0x00007FFA'51230000

# Run 3:
kernel32.dll base: 0x00007FFA'4E7F0000

Bypassing ASLR requires an information leak — a vulnerability that discloses a memory address. Once you know the actual address of even one module, you can calculate the addresses of everything else in that module (the internal offsets don’t change, only the base address does).

Common info leak sources:

  • Format string vulnerabilities (%p leaks stack pointers)
  • Uninitialized memory (stack/heap data leaking through output)
  • Out-of-bounds reads (reading past a buffer to reach adjacent pointers)

DEP — Data Execution Prevention

DEP (also called NX — No eXecute) marks memory pages as either executable or writable, but never both at the same time. The stack and heap are marked as non-executable. If you redirect execution to shellcode on the stack, the CPU raises an exception because the page doesn’t have execute permission.

Stack page:   RW  (read/write, no execute)    → Shellcode can't run here
Code page:    RX  (read/execute, no write)    → Can't write shellcode here

Bypassing DEP is done through code reuse attacks — primarily ROP (Return-Oriented Programming). Instead of executing injected code, the attacker chains together small snippets of existing code (called gadgets) that end in ret. Each gadget does one small operation, and the chain of return addresses on the stack sequences them together.

A ROP chain might look like:

Stack (attacker-controlled):
┌────────────────────────────────┐
│ Address of: pop rcx; ret       │  ← gadget 1: load RCX
│ 0x40 (PAGE_EXECUTE_READWRITE)  │  ← value for RCX (new page protection)
│ Address of: pop rdx; ret       │  ← gadget 2: load RDX
│ 0x1000 (size)                  │  ← value for RDX
│ Address of: VirtualProtect     │  ← make the stack page executable
│ Address of shellcode on stack  │  ← now shellcode can run!
└────────────────────────────────┘

The chain calls VirtualProtect to change the stack page to RWX, then jumps to the shellcode. DEP bypassed.

Control Flow Guard (CFG)

CFG protects indirect calls — function calls through pointers (like virtual function tables or function pointers in structs). Without CFG, an attacker who overwrites a function pointer can redirect execution anywhere. With CFG, each indirect call is validated against a bitmap of legitimate call targets:

// Without CFG:
call [rax]          // Jump wherever RAX points — no validation

// With CFG (compiler-generated):
call __guard_check_icall_fptr  // Validate that [RAX] is a valid target
call [rax]                      // Only reached if validation passes

If the address isn’t in the bitmap of valid targets, the process terminates. This makes ROP gadgets that use indirect calls much harder to leverage.

Heap Protections

Modern Windows heaps have multiple protections:

Protection What It Does What It Prevents
Safe Unlinking Validates forward/back pointers before unlinking a freed chunk Classic heap unlink exploits
Heap Cookies Random values encoded in chunk headers Metadata corruption detection
Guard Pages Unmapped pages at heap segment boundaries Heap overruns into adjacent segments
LFH Randomization Randomizes allocation order within buckets Deterministic heap layout manipulation
Encoded Headers Heap chunk headers are XOR-encoded with a per-heap key Direct metadata manipulation

Inspecting Memory with Tools

WinDbg — The Power Tool

WinDbg is the most powerful tool for memory analysis on Windows. Essential commands:

!address              — Full virtual memory map with permissions
!address -summary     — Memory usage summary
!vprot <addr>         — Protection flags for a specific address
lm                    — List loaded modules with base addresses
!dh <module> -f       — PE header details of a module
!peb                  — Process Environment Block
!teb                  — Thread Environment Block
!heap -s              — Heap summary
!heap -a <addr>       — Detailed heap info
k                     — Call stack (shows return addresses)
dps <addr>            — Display memory as pointers with symbols

A real !address -summary output:

0:000> !address -summary

                               Usage Summary
          TotSize (     KB)   Pct(Tots)  Pct(Busy)   Usage
        - - - - - - - - - - - - - - - - - - - - - - - - -
         1f9c000 (   32496)     0.00%    15.48%    Image
          5f8000 (    6112)     0.00%     2.91%    Stack
         1a14000 (   26704)     0.00%    12.73%    Heap
         e568000 (  234912)     0.00%    68.88%    Other
        ...

VMMap — Visual Memory Analysis

Microsoft’s VMMap gives you a visual, color-coded view of the entire address space. You can see at a glance how much memory is used by images, heaps, stacks, and other regions. It’s excellent for getting a high-level overview before diving into WinDbg for specifics.

Process Hacker / Process Explorer

These tools show per-process memory usage, loaded DLLs, handles, and threads. Process Hacker can also dump memory regions and search for patterns — useful for finding shellcode or unpacked malware in memory.

Practical Applications

Malware Analysis

Understanding memory layout is essential for analyzing:

Process Hollowing — Malware creates a suspended process, unmaps its image, maps a malicious image at the same address, then resumes execution. You detect this by comparing the in-memory image against the file on disk.

DLL Injection — Malware injects a DLL into another process using VirtualAllocEx + WriteProcessMemory + CreateRemoteThread. You spot this by looking for DLLs loaded from unusual paths or memory regions with RWX permissions that contain PE headers.

Manual Mapping — A stealthier version of DLL injection where the malware manually maps a DLL into memory without calling LoadLibrary, so it doesn’t appear in the PEB’s module lists. You can still find it by scanning for PE signatures (MZ / PE) in memory regions that don’t correspond to any known module.

Reflective Loading — The injected DLL contains its own loader and resolves imports itself. No file on disk, no module list entry, no LoadLibrary call. Detection requires scanning for anomalous executable pages.

Exploit Development

When developing exploits, your mental model of memory needs to be precise:

  1. Find the vulnerability — Buffer overflow, use-after-free, type confusion
  2. Control EIP/RIP — Overwrite a return address, function pointer, or virtual table entry
  3. Bypass ASLR — Find an information leak to disclose a module base address
  4. Bypass DEP — Build a ROP chain using gadgets from known modules
  5. Bypass CFG — Target valid call targets or find gadgets that don’t use indirect calls
  6. Achieve execution — Pivot the stack, allocate RWX memory, write and jump to shellcode

Every step requires knowing where things are in memory and how the protections interact.

Final Thoughts

Windows memory layout isn’t just a topic you study once and move on. It’s the foundation that underpins everything in offensive and defensive security research on the Windows platform. Every CVE advisory for a memory corruption vulnerability, every malware technique, every mitigation bypass — they all play out in the address spaces we’ve mapped out here.

The key takeaways:

  • Every process has its own virtual address space, divided into user mode and kernel mode
  • The PE format defines how executables and DLLs are mapped into memory, and the IAT is a critical structure for both hooking and exploitation
  • The stack grows downward and holds return addresses — the classic overflow target, now protected by canaries and ASLR
  • The heap is complex, fragmented, and protected by metadata encoding and safe unlinking
  • The PEB and TEB contain process/thread metadata that both malware and shellcode rely on to resolve API addresses
  • ASLR, DEP, CFG, and heap protections form layers of defense — breaking one isn’t enough, you need to bypass the entire chain

If you want to go deeper, fire up WinDbg, attach it to a process, and start exploring. Run !address, walk the PEB, inspect the heap. There’s no substitute for hands-on exploration.

Keep digging.

ALSO READ
Blockchain 0x000 – Understanding the Fundamentals
May 21, 2020 Web3 Development

Imagine a world where strangers can exchange money, share data, or execute agreements without ever needing to trust a central authority. No banks, no intermediaries, no single point of failure yet...

Identity and Access Management (IAM)
May 11, 2020 Identity & Access Management

Who are you — and what are you allowed to do? That's the fundamental question every secure system must answer. And it's exactly what Identity and Access Management (IAM) is built to solve.

How I built a web based CPU Simulator
May 07, 2020 Pet Projects

As someone passionate about computer engineering, reverse engineering, and system internals, I've always been fascinated by what happens "under the hood" of a computer. This curiosity led me to...

Writing a Shell Code for Linux
Apr 21, 2020 Exploit Development

Shellcode is a small piece of machine code used as the payload in exploit development. In this post, we write Linux shellcode from scratch — starting with a simple exit, building up to spawning a shell, and explaining every decision along the way.

Exploiting a Stack Buffer Overflow on Windows
Apr 12, 2020 Exploit Development

In a previous tutorial we discusses how we can exploit a buffer overflow vulnerability on a Linux machine. I wen through all theories in depth and explained each step. Now today we are going to jump...

Access Control Models
Apr 08, 2020 Identity & Access Management

Access control is one of the most fundamental concepts in security. Every time you set file permissions, assign user roles, or restrict access to a resource, you're implementing some form of access control. But not all access control is created equal...

Exploiting a  Stack Buffer Overflow  on Linux
Apr 01, 2020 Exploit Development

Have you ever wondered how attackers gain control over remote servers? How do they just run some exploit and compromise a computer? If we dive into the actual context, there is no magic happening....

Basic concepts of Cryptography
Mar 01, 2020 Cryptography

Ever notice that little padlock icon in your browser's address bar? That's cryptography working silently in the background, protecting everything you do online. Whether you're sending an email,...

Common Web Application Attacks
Feb 05, 2020 Application Security

Web applications are one of the most targeted surfaces by attackers. This is primarily because they are accessible over the internet, making them exposed and potentially vulnerable. Since these...

Remote Code Execution (RCE)
Jan 02, 2020 Application Security

Remote Code Execution (RCE) is the holy grail of application security vulnerabilities. It allows an attacker to execute arbitrary code on a remote server — and the consequences are as bad as it sounds. In this post, we'll go deep into RCE across multiple languages, including PHP, Java, Python, and Node.js.