杀死你漏洞的单个字节:理解字节序
The Single Byte That Kills Your Exploit: Understanding Endianness

原始链接: https://pwnforfunandprofit.substack.com/p/the-single-byte-that-kills-your-exploit

## 字节序:无声的漏洞终结者 字节序定义了字节在内存中的存储顺序,对漏洞利用至关重要。**小端序 (LE)**,被大多数现代计算机(x86/x64)使用,先存储最低有效字节。**大端序 (BE)**,常见于网络和一些嵌入式系统,先存储最高有效字节。 不正确的字节序会导致崩溃 (SIGSEGV),因为目标程序会错误解释漏洞利用中的地址。当目标架构不是x86,例如MIPS或PowerPC时,这种情况尤其常见。 **漏洞利用开发的关键点:** * **确认目标架构和字节序:** 不要假设是x86!使用 `file`、`readelf` 或 GDB 进行验证。 * **使用正确的打包:** 使用像 `pwntools` 或 `struct.pack` 这样的工具来正确格式化地址 (p32/p64)。 * **验证有效载荷字节:** 比较发送的数据与目标接收的数据及其内存表示形式。 * **网络协议:** 除非另有说明,否则以网络字节序(大端序)编码网络中的多字节字段。 理解打包过程中字节被反转的原因对于调试至关重要。虽然现代工具可以处理大部分工作,但了解底层概念可以防止静默失败并加速漏洞利用开发。

相关文章

原文

If you’ve ever crafted a perfect shellcode and ROP chain only to have your exploit immediately crash with a SIGSEGV(a signal sent by the operating system to a program when it attempts to access a protected or invalid memory location) or EIP(a 32-bit CPU register in the x86 architecture that holds the memory address of the next machine instruction to be executed) pointing to garbage, you’ve likely met the silent killer of beginners: Endianness.

Endianness is fundamental; it defines the order in which a multi-byte value (like a 4-byte integer or an 8-byte memory address) is stored in a machine’s memory. For us in the pwn game, this translates directly to whether the addresses we pack into our exploit payloads are interpreted correctly by the target program. A single misplaced byte means the difference between a shell and a stack smash(stack buffer overflow).

There are two primary byte orders

Little-Endian (LE): The Least Significant Byte (LSB) is stored first, at the lowest memory address. This is the byte order used by the vast majority of personal computers, including all modern Intel/AMD (x86/x64) architectures.

Big-Endian (BE): The Most Significant Byte (MSB) is stored first, at the lowest memory address. This is often called Network Byte Order (NBO) and is common in network protocols, as well as some older or embedded architectures like PowerPC, MIPS, and SPARC.

If you’re attacking an embedded device, router, or IoT target, it might be Big-Endian. Always confirm the target architecture and ABI. Common mistakes when cross-compiling or reusing gadgets:

Using x86/x86_64 gadgets and packers on a MIPS/PowerPC target (different endianness and instruction set) will not work.

pwntools and other frameworks allow you to set context.arch and context.endian So packers and disassemblers behave correctly.

Run the small C program above on the target if you have code execution. Use readelf, file, or objdump On binaries from the target filesystem, some formats indicate endianness.

In GDB, examine the memory representation of a known constant or pointer. Put a known value in a register or memory, and inspect the byte order with x/4xb address.

(gdb) p/x 0x41424344
$1 = 0x41424344
(gdb) set {int}0x601000 = 0x41424344
(gdb) x/4xb 0x601000
0x601000: 0x44 0x43 0x42 0x41  # little-endian: ‘DCBA’

Print the raw payload bytes you are sending, compare with what the target receives (packet capture or logging), and what the target’s memory shows in a debugger.

Verify pointer size. Are you packing 32-bit or 64-bit addresses?

Check alignment and padding. Are there extra bytes inserted by the protocol or scanf/fgets behavior?

Confirm endianness on the target; don’t assume x86 for embedded devices.

Use tool packing (struct.pack, pwntools) instead of hand-reversing where possible.

If attacking over the network, confirm whether fields are consumed in network byte order.

  • Confirm target architecture (x86, x86_64, MIPS, ARM, PowerPC).

  • Confirm endianness (LE or BE).

  • Use correct pointer width (p32 vs p64) and pack accordingly.

  • Use library packing (struct, pwntools) to avoid manual reversal mistakes.

  • For network services, encode multi-byte protocol fields in network (big-endian) byte order unless the protocol documentation says otherwise.

  • Check struct padding and alignment on the target.

  • Inspect the target’s memory with a debugger to verify the actual byte layout.

Endianness is simple in concept but vital in practice. For most modern exploit work, you’ll be on x86_64 (Little-Endian), so make it a habit to pack addresses in reverse byte order relative to how you read them in a disassembler. Use pwntools, struct, or equivalent to do the packing for you, but keep in mind why bytes are reversed; that understanding is what will let you debug the next crash quickly and confidently.

Support my work

Recommended reading:

Disclaimer: This article was written with AI assistance, for a bit of brainstorming and proofreading.

联系我们 contact @ memedata.com