BOF攻击场景下可执行栈与NX栈的核心差异是什么?
Executable Stack vs. NX Stack in Buffer Overflow (BOF) Scenarios
Let's break down the key differences between these two memory configurations, especially how they shape buffer overflow attack outcomes and techniques:
1. Core Memory Permission Distinction
The root difference boils down to whether the stack region is allowed to execute code:
- Executable Stack: The stack has read/write and execute permissions. Any data written to the stack (like attacker-supplied shellcode) can be directly run as machine code by the CPU.
- NX Stack: The stack is marked as read/write only—execute permissions are explicitly disabled. If the CPU tries to run code stored here, it triggers a memory access fault (e.g.,
SIGSEGVon Linux, Access Violation on Windows) immediately.
2. Impact on Traditional BOF Attack Paths
Executable Stack: Direct Shellcode Execution
With an executable stack, classic BOF attacks are straightforward:
- Overflow a vulnerable buffer to overwrite the function's return address (EIP/RIP).
- Replace the return address with the memory location of shellcode you've already stuffed into the stack via the overflow.
- When the function returns, the CPU jumps to the stack-based shellcode and runs it—this could spawn a shell, modify system files, or carry out other malicious actions.
NX Stack: Blocks Raw Shellcode Execution
NX completely breaks the above attack flow:
- Even if you successfully write shellcode to the stack and overwrite the return address to point to it, the CPU will crash the program as soon as it tries to execute that stack-resident code.
- To bypass NX, attackers must use techniques like Return-Oriented Programming (ROP): instead of running their own code, they chain together tiny pre-existing code fragments (called "gadgets") from the program's executable segments (e.g., the
.textsection). Each gadget ends with aretinstruction, letting attackers string them together to perform actions like callingsystem("/bin/sh")without ever executing code from the stack.
3. Attack Complexity & Requirements
- Executable Stack: Attacks are low-effort. You just need to craft a payload with your shellcode and correctly overwrite the return address to target it. No deep knowledge of the target program's existing code is required beyond finding the overflow vulnerability.
- NX Stack: Attacks get much more complex. You’ll need to:
- Reverse-engineer the target binary to identify useful gadgets.
- Build a ROP chain that sequences these gadgets to achieve your goal.
- Often bypass additional protections like ASLR (Address Space Layout Randomization) to know the exact addresses of those gadgets.
4. Why You Might Not Have Observed a Difference
If enabling NX didn’t seem to change behavior, it’s probably because you were testing a traditional shellcode payload:
- On an executable stack, the payload would run (e.g., spawn a shell if that’s what your shellcode does).
- On an NX stack, the program would crash immediately with a segmentation fault—that’s the critical observable difference. To see a successful attack on an NX stack, you’d need to switch to a ROP-based payload instead of raw shellcode.
内容的提问来源于stack exchange,提问作者Henok Tesfaye
相关产品推荐
相关产品推荐

