Source: Python "Grey Hat"
After you have obtained EIP control, you have to transfer execution to your shellcode. Typically, you will have a register or an offset from a register that points to your shellcode, and it’s your job to find an instruction somewhere in the executable or one of its loaded modules that will transfer control to that address. ======== from immlib import * def main(args): imm = Debugger() search_code = "".join(args) search_bytes = imm.Assemble( search_code) search_results= imm.Search( search_bytes ) for hit in search_results: # Retrieve the memory page where this hit exists # and make sure it's executable code_page = imm.getMemoryPagebyAddress( hit ) access = code_page.getAccess( human = True ) if "execute" in access.lower(): imm.log( "[*] Found: %s (0x%08x)" % ( search_code, hit ), address = hit ) return "[*] Finished searching for instructions, check the Log window." ========
0 Comments
Integer overflows (see [Blexim], [Koziol]) are a special type of overflow bug where incorrect treatment of integers can lead to a numerical overflow which eventually results in a buffer overflow.
The common case in which this happens is when an application receives the length of some data block from the outside world. Except for really extreme cases of recklessness, programmers typically perform some sort of bounds checking on such an integer. Unfortunately, safely checking an integer value is not as trivial as it seems, and there are numerous pitfalls that could allow bad input values to pass as legal values. Source: Eldad Eilam-Reversing "Secrets of Reverse Engineering Wiley(2005)" A Simple Stack Vulnerability The most trivial overflow bugs happen when an application stores a temporary buffer in the stack and receives variable-length input from the outside world into that buffer. The classic case is a function that receives a null-terminated string as input and copies that string into a local variable. Here is an example that was disassembled using WinDbg. Chapter7!launch: 00401060 mov eax,[esp+0x4] 00401064 sub esp,0x64 00401067 push eax 00401068 lea ecx,[esp+0x4] 0040106c push ecx 0040106d call Chapter7!strcpy (00401180) 00401072 lea edx,[esp+0x8] 00401076 push 0x408128 0040107b push edx 0040107c call Chapter7!strcat (00401190) 00401081 lea eax,[esp+0x10] 00401085 push eax 00401086 call Chapter7!system (004010e7) 0040108b add esp,0x78 0040108e ret In C, an array is simply a list of n elements of a specific data type. Arrays are also referred to as buffers
The GCC compiler can also be given the -o switch to define the output file to compile to. This switch is used below to compile the program into an executable binary called char_array char_array.c reader@hacking:~/booksrc $ gcc -o char_array char_array.c Notice that the number begins at 0, as opposed to 1. Also notice that the last character is a 0. (This is also called a null byte.) Notice that the number begins at 0, as opposed to 1. Also notice that the last character is a 0. (This is also called a null byte.) The strcpy() function will copy a string from a source to a destination, iterating through the source string and copying each byte to the destination (and stopping after it copies the null termination byte). char_array2.c #include <stdio.h> #include <string.h> int main() { char str_a[20]; strcpy(str_a, "Hello, world!\n"); printf(str_a); } reader@hacking:~/booksrc $ gcc -g -o char_array2 char_array2.c reader@hacking:~/booksrc $ gdb -q ./char_array2 (gdb) list (gdb) break 6 (gdb) break strcpy Make breakpoint pending on future shared library load? (y or [n]) y (gdb) break 8 (gdb) run (gdb) i r eip (gdb) x/5i $eip (gdb) continue (gdb) i r eip (gdb) continue 0x252 The x86 Processor
Debuggers are used by programmers to step through compiled programs, examine program memory, and view processor registers. reader@hacking:~/booksrc $ gdb -q ./a.out (gdb) break main (gdb) run (gdb) info registers (gdb) nexti A breakpoint is set on the main() function so execution will stop right before our code is executed Set Intel For GDB:
reader@hacking:~/booksrc $ gdb -q (gdb) set dis intel (gdb) quit reader@hacking:~/booksrc $ echo "set dis intel" > ~/.gdbinit reader@hacking:~/booksrc $ cat ~/.gdbinit set dis intel Source: Hacking: The Art of Exploitation, Jon Erickson
#include <stdio.h> int main() { int i; for(i=0; i < 10; i++) { printf("Hello, world!\n"); } return 0; } gcc -o firstprog.out firstprog.c objdump -D a.out | grep -A20 main.: objdump -M intel -D a.out | grep -A20 main.: x86 General Purpose Registers
EIP - instruction pointer ESP - stack pointer EBP - base pointer ESI - source index EDI - destination index EAX - accumulator EBX - base ECX - counter EDX - data EAX, ECX, EDX, and EBX-> Accumulator, Counter, Data, and Base registers [They are used for a variety of purposes, but they mainly act as temporary variables for the CPU when it is executing machine instructions] ESP, EBP, ESI, and EDI ->Stack Pointer, Base Pointer, Source Index, and Destination Index, respectively. The first two registers are called pointers because they store 32-bit addresses, which essentially point to that location in memory. These registers are fairly important to program execution and memory management; we will discuss them more later. The la st two registers are also technically pointers, which are commonly used to point to the source and dest ination when data needs to be read from or written to. The EIP register is the Instruction Pointer register, which points to the current instruction the processor is reading. The remaining EFLAGS register actually consists of several bit flags that are used for comparisons and memory segmentations. |