Methodology

Random general tips and notes I need to remind myself of.

Document the attack surface:
    Recon:
        Review the applications memory protections (DEP/ASLR/Etc)
    
        Do your research before doing any reverse engineering:
            Read any relevant RFCs for the protocols used. 
            Read any technical documentation of file formats used.
            Read the docs.
        
        Locate an entrance point to the application via ProcMon/Netstat/etc
    
    Enumeration:
        Do an intial pass with both dynamic and static analysis to get a very broad idea of what the application is doing with your data. 
            Note any DLLs called and repeat step 2 for them as necessary.
       
        Start with several full fast passes to get a general understanding.
            Don't commit to in depth RE until you are relatively sure you understand the basic flow of the application.
            Note suspicious code for later review.
        
RE:

    Just because there are no obviously vulnerable system calls doesn't mean you should skip over a function. For example loops and rep movs as well as a single mov r32, r32 can lead to an overflow or write primitive.
    Always send the largest possible buffer to every new path.
    Follow calls to other DLLs and put them in IDA for analysis.
    Note every opcode tested and go through them in numerical order so you don't miss any. Can use alt+t in IDA to search for cases.
    If a function requires some specific input like a filename attempt adding another buffer after the file seperated by a nullbyte/newline/CR


Exploitation:

    Check various buffer sizes
        In the case where a read is being preformed on user controlled data attempt to increase both the read and the write buffer sizes.
            This includes when attempting to cause a crash for SEH overflows.

    ROP selection:
    
        Locate write gadget: mov [write], read
            gadgets write register must
                receive a writable staging area address 
                increment
                decrement by ~0x18
            gadgets read register must
                receive staging area address 
                receive dereferenced function address 
                recieve shellcode address 
                receive arbitrary small values (ideally pop + neg/sub)
           

Commonly Vulnerable Calls

(As well as the various derivates of the below functions)

  • gets

  • scanf

  • memcpy

  • wctomb

  • mbtowc

  • strcpy

  • strcat

  • sprintf

  • MultiByteToWideChar

https://www.proggen.org/doku.php?id=security:memory-corruption:protection:stdlib

Suspicious Assembly

From The Shellcoder's Handbook chapter 21:

Variable Indexed write 
    mov [ecx+edx], al
    
Write to pointer followed by increment of pointer
    mov cl, [edx]
    movsx eax, cl
    
Add/sub from a register containing controlled data:
    mov eax, [edi]
    add eax, 2
    cp eax, 256
    jae error
    
Value truncation as a result of being stored as a 16- or 8-bit integer
    push edi
    call strlen
    add esp, 4
    mov word ptr [ebp-4], ax

Vulnerability Classes

The Shellcoder's Handbook chapter 18

Generic Logic Errors

Unbounded Memory Copy Functions (mostly extinct)
    strcpy
    sprintf
    strcat
    gets
    
Format Strings
    See Format String Attack notes

Incorrect Bounds-Checking

Loop Bugs
    loops introduce complexity especially in edge cases

Off-by-One
    Often occur when working with strings such as incorrectly calculating the length of a strncat which includes an extra nullbyte by default.
        OpenBSD ftp Daemon Example (off by one when the string ends in a "):
            char npath[MAXPATHLEN];
            int i;
            for (i = 0; *name != β€˜\0’ && i < sizeof(npath) - 1; i++, name++)
            {
            npath[i] = *name;
            if (*name == β€˜β€œβ€˜)
            npath[++i] = β€˜β€œβ€˜;
            }
            npath[i] = β€˜\0’;
        
Non-Null Termination/Skipping Null Termination:
    If a string fails to contain a nullbyte subsequent function calls may include large amounts of additional data from the buffer location (ie strcpy).
    
    Skip example from Apache mod_rewrite:
        else if (is_absolute_uri(r->filename)) {
        /* it was finally rewritten to a remote URL */
        /* skip β€˜scheme:’ */
        for (cp = r->filename; *cp != β€˜:’ && *cp != β€˜\0’; cp++)
        ;
        /* skip β€˜://β€˜ */
        cp += 3;
    
    Works for https:// but ldap:a will lead to the nullbyte being skipped.
    
Signed Comparison:
    Negative numbers for length specifiers provided by a user (such as within a packet) may lead to unintended behavior.
    
    Example from Apache chunk-encoding vulnerability:
        //r->remaining is user supplied, providing a negative number leads to a buffer overflow
        len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
        len_read = ap_bread(r->connection->client, buffer, len_to_read);
        
Integer Overflows:

    16 bit (short) signed integar 
        max value: 0x7fff
        min value: 0x8000
    16 bit unsigned integar
        max value: 0xffff
    
    32 bit (long) signed integar
        max value: 0x80000000
        min value: 0x7fffffff
    32 bit unsigned integar
        max value: 0xffffffff
        
    Example:
        //if n is user supplied and less than HEADER_SIZE
        memcpy(dest,data+HEADER_SIZE,n – HEADER_SIZE);
        
Integer Conversions:
    " ... if a signed 32-bit integer with a negative value of –65,535 were changed to a 16-
    bit integer, the resulting 16-bit integer would have a value of +1 due to the
    truncation of the highest 16 bits of the integer."
    
        
Table 18-1: The Shellcoder's Handbook Chapter 18 Source Code Auditing
Table 18-1: The Shellcoder's Handbook Chapter 18 Source Code Auditing (cont.)
Double Free:
    When a heap chunk is freed more than once. Difficult to exploit in practice.
    https://sensepost.com/blog/2017/linux-heap-exploitation-intro-series-riding-free-on-the-heap-double-free-attacks/
    
Uninitialized Variable Usage

Use After Free 

Last updated

Was this helpful?