76

I can't find a good source that answers this question. I know that a nop sled is a technique used to circumvent stack randomization in a buffer overflow attack, but I can't get my head around how it works.

What's a simple example that illustrates this method?

What do terms like 128-byte nop sled mean?

halfer
  • 19,824
  • 17
  • 99
  • 186
amorimluc
  • 1,661
  • 5
  • 22
  • 32

2 Answers2

108

Some attacks consist of making the program jump to a specific address and continue running from there. The injected code has to be loaded previously somehow in that exact location.

Stack randomization and other runtime differences may make the address where the program will jump impossible to predict, so the attacker places a NOP sled in a big range of memory. If the program jumps to anywhere into the sled, it will run all the remaining NOPs, doing nothing, and then will run the payload code, just next to the sled.

The reason the attacker uses the NOP sled is to make the target address bigger: the code can jump anywhere in the sled, instead of exactly at the beginning of the injected code.

A 128-byte NOP sled is just a group of NOP intructions 128 bytes wide.

NOTE #1: NOP (No-OPeration) is an instruction available in most (all?) architectures that does nothing, other than occupying memory and some runtime.

NOTE #2: in architectures with variable length instructions, a NOP instruction is usually just one byte in length, so it can be used as a convenient instruction padding. Unfortunately, that also makes it easy to do a NOP sled.

GDP2
  • 1,948
  • 2
  • 22
  • 38
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Ok, I think I get the gist of nop-sleds. Is there somewhere you could point to that shows an assembly-code example of a nop-sled? – amorimluc Feb 07 '13 at 20:58
  • Nop-sleds are still a little abstract for me. An example would really help. – amorimluc Feb 07 '13 at 21:10
  • Lol, maybe the nop-block could be shortened with (...) – amorimluc Feb 07 '13 at 21:12
  • 28
    In the class I took, a NOP-sled wasn't necessarily a sequence of literal NOPs but could also be a sequence of instructions that look like real code but have no net effect. Add one to a register and then subtract one from a register has no significant side effect, but it's a lot harder for a scanner to recognize than a bunch of literal NOP instructions in a row. – Adrian McCarthy Feb 07 '13 at 21:18
  • 4
    @PascalCuoq Modern nop slides do not include a large sequence of nop's. Why? Security has been buffed up to detect these "large quantities" of nop's. Blackhats include random commands to fake "real" memory and to lure such protective software. – basickarl Oct 16 '14 at 19:17
  • @amorimluc: In NASM, `times 128 nop` to assemble 128 single-byte NOP instructions (opcode 0x90). x86 also has multi-byte NOP instructions which any good assembler uses for padding in `ALIGN` directives. This is important for perf of normal code (not injected) when used inside functions to align branch targets (e.g. the top of a loop) because the NOPs will actually run once, and it's faster to decode one long NOP than many short NOPs of the same length. (And lots of short NOPs can even cause indirect performance effects like preventing that 32B block of code from going in the uop cache). – Peter Cordes Oct 09 '17 at 07:04
6

To add to rodrigo's explanation - Even with a NOP sled, the approximate location of the buffer in memory must be predicted in advance. One technique for approximating the memory location of is to use nearby stack location as a frame of reference. By subtracting an offset from this location, the relative address of any variable can be obtained.

SIDE NOTE: on x86 architecture the NOP instruction is equivalent to the hex byte 0x90 therefore a completed exploit buffer could look something like this:

| NOP sled | Shellcode | Repeated return address|

Seeing as if the EIP register points to any address found in the NOP sled, it would increment while executing each NOP instruction, one at a time, untill it finally reaches the shellcode

halfer
  • 19,824
  • 17
  • 99
  • 186
Boschko
  • 367
  • 5
  • 14
  • Is it possible to explain your technique to find the approximating memory location of the buffer? I'm not sure it could be possible without using memory leak information (from a vulnerability or whatever)... – Duke Nukem Aug 17 '18 at 12:04