Hacking - The Art of Exploitation, 2nd Edition

(Romina) #1
Shellcode 287

In shellcode, the bytes for the string "Hello, world!" must be mixed


together with the bytes for the assembly instructions, since there aren’t


definable or predictable memory segments. This is fine as long as EIP doesn’t


try to interpret the string as instructions. However, to access the string as data


we need a pointer to it. When the shellcode gets executed, it could be any-


where in memory. The string’s absolute memory address needs to be calcu-


lated relative to EIP. Since EIP cannot be accessed from assembly instructions,


however, we need to use some sort of trick.


0x521 Assembly Instructions Using the Stack


The stack is so integral to the x86 architecture that there are special instruc-


tions for its operations.


Stack-based exploits are made possible by the call and ret instructions.


When a function is called, the return address of the next instruction is pushed


to the stack, beginning the stack frame. After the function is finished, the ret


instruction pops the return address from the stack and jumps EIP back there.


By overwriting the stored return address on the stack before the ret instruc-


tion, we can take control of a program’s execution.


This architecture can be misused in another way to solve the problem of


addressing the inline string data. If the string is placed directly after a call


instruction, the address of the string will get pushed to the stack as the return


address. Instead of calling a function, we can jump past the string to a pop


instruction that will take the address off the stack and into a register. The


following assembly instructions demonstrate this technique.


helloworld1.s


BITS 32 ; Tell nasm this is 32-bit code.


call mark_below ; Call below the string to instructions
db "Hello, world!", 0x0a, 0x0d ; with newline and carriage return bytes.


mark_below:
; ssize_t write(int fd, const void *buf, size_t count);
pop ecx ; Pop the return address (string ptr) into ecx.
mov eax, 4 ; Write syscall #.
mov ebx, 1 ; STDOUT file descriptor


Instruction Description
push <source> Push the source operand to the stack.
pop <destination> Pop a value from the stack and store in the destination operand.
call <location> Call a function, jumping the execution to the address in the location
operand. This location can be relative or absolute. The address of the
instruction following the call is pushed to the stack, so that execution can
return later.
ret Return from a function, popping the return address from the stack and
jumping execution there.
Free download pdf