/SLAE32: Assignment 3

# Introduction

For assignment 3 I needed to study about egghunters and create a working demo which could be easily configured for different payloads. I found this paper by skape which describes three different approaches to egghunters on linux and a few for windows as well. This paper is from 2004, but the approach still worked.

# Egghunter ASM

What an egghunter does exactly, is search through the memory of a program for a unique "egg" which is some predefined DWORD repeated twice, for example 0x50905090. The idea is that this is prepended to your payload and once it is found the egghunter will jump to your payload for it to be executed. This is useful when the exploit buffer space is not particularily large, but it is possible to place larger payloads into a programs memory space before memory corruption.

This is the code from the original paper, in the section "access(2) - revised". I added a bunch of inline comments explaining what each command does. Basically it sweeps through pages until it finds one that is accessible (won't throw an EFAULT error) when it is accessed with SYS_access. Once found, it will search through this page and see if it can find the egg. If it does it will run the shellcode, otherwise it will keep searching. The whole process will take a couple of seconds (around 7 according to the paper).
global _start
section .text
    xor ecx, ecx            ; ECX = 0 (required to avoid a SEGFAULT that occurs during scasd
                            ;          in the original shellcode)
    xor edx, EDX            ; EDX = 0

    or dx, 0xfff            ; Set EDX to the last address in a page

    inc edx                 ; EDX += 1 (next address in the page)
    lea ebx, [edx + 0x4]    ; const char *pathname = [edx + 0x4]
    push byte +0x21
    pop eax                 ; EAX = 0x21 = SYS_ACCESS
    int 0x80                ; access()

    cmp al, 0xf2            ; Checks if return value of access() is 0xfffffff2 (EFAULT)
    jz next_page            ; If it is, then keep searching through the pages (address is not accessible)

    mov eax, <EGG>          ; Otherwise load the egg into EAX
    mov edi, edx            ; Load the address into EDI
    scasd                   ; Compared the "string" in EDI to EAX (bytes in memory to egg)
    jnz next_addr           ; If the first 4 are not equal, keep searching)
    scasd                   ; Otherwise check the next 4
    jnz next_addr           ; If the second 4 are not equal, keep searching)

    jmp edi                 ; If the 8 bytes are equal to the egg, then we have most probably
                            ; found the payload and can jump to it to execute

# Wrapper

I wrote a wrapper script in Python3 which takes care of generating shellcode for the egghunter with whichever egg you want to use (you may provide a DWORD or 4 character string). For demonstration purposes I wrote a C program which loads arbitrary shellcode into memory, as well as the egghunter. It then runs the egghunter which will scan the programs memory for this egg and run the shellcode once found.

All the code for this exercise is available on my Github repository, as mentioned below.

# SLAE32 Exam Statement

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: PA-25640

All my code for the exam is available in my SLAE32 exam Github repository.