SLAE Assignment 3: Egg Hunter Shellcode Study

The 3rd assignment of the SLAE certification looks into egghunters work which essentially involves safely searching through the memory. The assignment requires the following:

  • Study the Egg Hunter shellcode
  • Create a working demo of the Egghunter shellcode
  • The created Egg hunter should be configurable for different payloads.

Egg Hunter Overview

An egg hunter is used to solve the problem of having very small amount of memory in which shellcode can be written. An ‘Egg Hunter’ is a form of staged shellcode where the shellcode is split into multiple parts. The first part is a small number of instructions which search for the ‘egg’ which is a larger set of instructions located somewhere in memory that the shellcode is able to access. Once the egg has been located the egg hunter shifts execution to the shellcode instructions contained within the egg.

There are a number of very good resources on the internet which give a lot of detail about the techniques used when writing an ‘Egghunter’.

Skape – Safelty Searching Virtual Address Space

The information I found to be most commonly referenced when searching for information about egghunters was the Skape paper. The paper contains a lot of very detailed analysis of three different Linux system calls which can be used to search the virtual addres space including the pros and cons of each option. The different system calls allow each memory address to be tested to see if it is valid memory and therefore be read before the contents are tested to see if they contain the Egg. The approach of testing the memory prior to using it is what the title of the paper refers to.

The egghunter shellcode I write will be based on the 3rd approach which uses the sigaction() system call.

sigaction() System Call Overview

The sigaction() system call has the following function prototype:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

When the sigaction() system call is used within the Egghunter shellcode the following registers must be initialised

Register Setting
EAX System Call ID
EBX NULL or ‘0x0’
ECX Memory Address to be checked

Return Value

sigaction() returns 0 on success; on error, -1 is returned, and errno is set to 
indicate the error.

sigation() Loop

The Egghunter must loop through the virtual address space memory performing two actions:

  • Check if the memory address valid?
  • If valid check to see if it contains the ‘egg’ signature.

The sigaction() system call returns either a zero or a non-zero value to the EAX register. After doing some testing I found that the non-zero value was ‘0xFFFFFFF2’. The instructions to test the return value in the EAX register is translated into the following machine language instructions:

804806d: 83 f8 f2              cmp    eax,0xfffffff2

However, if only the lowest Byte of the EAX register is tested the machine language instructions are 1-Byte shorter.

804806d: 3c f2                 cmp    al,0xf2

So after the system call the loop will test to see if the lower Byte of the EAX register contains ‘0xF2’.

The Egg Signature

Once the sigaction() system call has identified a valid memory address we need a way of testing to see if the location contains the Egg instructions. The way this is done is by prefixing the Egg shellcode instructions with a signature which can be tested for. The Egg signature will be 8-Bytes to avoid the issue of a 4-Byte signature finding the signature in the Egghunter shellcode and not the prefix to the ‘Egg’ shellcode.

Checking for the Egg Signature

Once a valid memory address has been found by the sigaction() system call the Egghunter shellcode needs to search for the Egg signature. The ‘SCAS’ instruction searches for a specified character of set of characters in a string. The Egg hunter will use will be SCASD version which searches for a DWORD sized string stored in the EAX register at the memory address located in the EDI register. When the SCASD instruction finds a match it increments the value stored in the EDI register by the size of the string it is searching for. When the 2nd egg is found the SCASD instruction will have incremented the EDI register by 8 Bytes, meaning EDI will point at the first instruction in the ‘Egg’ which has been found. As the EDI register now points at the first instruction in the ‘egg’ our shellcode will execute without any further changes to the registers.

Egg Hunter Shellcode

Lets step through the Egg hunter shellcode

_start:
 xor ecx, ecx        ; Zero ECX
page_inc:
 or  cx, 0xfff       ; Set the memory address to test with sigaction()
                     ; The 'or' instruction essentially increments 
                     ; the current value by 0xfff. 
                     ; Using 0xfff and then inc means there isn't a
                     ; NULL Byte in the shellcode. 
check_mem:
 inc ecx             ; Increment ECX so that lowest 2 Bytes of the 
                     ; EAX register is 0x1000
                    
first_check:                
 push byte 0x43      ; Store 0x43 on the stack
 pop eax             ; Set sigaction() system call ID
 int 0x80            ; Execute system call
 cmp al, 0xf2        ; Test to see if the memory location is valid. 
 jz page_inc         ; If memory isn't valid loop again to next memory location
                     ; Program execution only reaches this point when valid 
                     ; memory is found
 mov eax, 0x41414141 ; Set the Egg signature in the EAX register
 mov edi, ecx        ; Move the valid memory address to EDI
 scasd               ; Scan the memory address in EDI to see if it 
                     ; contains the 1st 4 Bytes of Egg
 jnz check_mem       ; If no match, loop back to check another address
 scasd               ; Scan the memory address in EDI to see if it 
                     ; contains the 2nd 4 Bytes of Egg 
 jnz check_mem       ; If no match, loop back to check another address
 jmp edi             ; When the code reaches this instruction the 
                     ; 8 Byte Egg signature has been found. 
                     ; The shellcode jumps execution to the start of 
                     ; the Egg instructions.

Extracting the machine code instructions.

Once the shellcode has been assembled the machine instructions must be extracted. I put together the following commands which extracts the machine instructions from shellcode. Its slightly different to the one used in the SLAE lecture and doesn’t need to be altered to account for different numbers of columns as it uses objdump with the -s switch.

objdump -s  ./egghunter | grep -v '^ [0-9a-f][0-9a-f][0-9a-f][0-9a-f] \b' | grep -v 'Contents' | grep -v '^./' 
| cut -d' ' -f 3-6| sed 's/ //g' | sed '/./!d' | tr -d '\n'| sed 's/.\{2\}/&\\x/g' | sed 's/^/\\x/'|sed 's/..$//'|
sed 's/^/"/;s/$/"/g'

The extracted machine instructions from the egghunter shellcode are:

"\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xf1\xb8\x41"
"\x41\x41\x41\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7"

The Egghunter shellcode is inserted into the shellcode.c template and is executed in the same way as in assignment 1 and 2.

The Egg

The egg is the shellcode which will be executed by the egghunter. The egg which will be hunted for will write the string “Egg Found!” to the console.

SECTION .data
SECTION .bss
SECTION .text 
global _start
_start:
 xor ebx, ebx            ; Zero the EBX register
 mul ebx                 ; Zero the EAX and EDX registers
 
 ; setup write system call
 mov al, 0x4             ; Set the write() system call ID
 mov bl, 0x1             ; Set write() arg#1 file descriptor to stdout
 jmp short variabledef   ; JMP-call-pop: Get the string address
 
set_string:
 pop ecx                 ; jmp-call-POP: 
                         ; Set write() arg#2 Pop the string address
                         ; into the ECX register
 mov dl, 0xC             ; Set write() arg#3
 int 0x80
 
 ; Exit gracefullly
 xor eax, eax
 mov ebx, eax
 mov al, 0x1
 mov bl, 0x5
 int 0x80
 
variabledef:
 call set_string         ; jmp-CALL-pop: Call set_string
 message: dw "Egg Found!", 0xA  ; String to be printed

Extract the Egg instructions

The egg machine instructions are extracted using the same commands as the Egghunter shellcode, which gives:

"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x0f\x59\xb2\x0c\xcd\x80\x31\xc0\x89\xc3"
"\xb0\x01\xb3\x05\xcd\x80\xe8\xec\xff\xff\xff\x45\x67\x67\x20\x46\x6f\x75\x6e"
"\x64\x21\x0a\x00"

Setting up shellcode.c

I have the machine instructions for the ‘egghunter’ and the ‘egg’. They are used to construct a ‘C’ program using the shellcode.c template.

  • The egg signature is declared as EGGSIG using ‘define’
  • The actual egg signature is constructed using the format below which gives an 8 Byte egg signature
EGGSIG EGGSIG

The shellcode.c source code below shows the two strings

  • code: The egghunter instructions
  • egg: The egg instructions.
#define EGGSIG "\x41\x41\x41\x41"
#include
#include
unsigned char egg[] = \
EGGSIG EGGSIG
"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x12\x59\xb2\x0a\xcd\x80\x5f\xff"
"\xe7\x31\xc0\x89\xc3\xb0\x01\xb3\x05\xcd\x80\xe8\xe9\xff\xff\xff\x45"
"\x67\x67\x20\x46\x6f\x75\x6e\x64\x21\x0a\x00";
     
unsigned char code[] = \
"\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74
"\xf1\xb8\x41\x41\x41\x41\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7";

int main()
{
 printf("Shellcode Length:  %d\n", strlen(code));
  int (*ret)() = (int(*)())code;
 ret();
}
The shellcode.c source code is compiled using the following command:
gcc -ggdb -fno-stack-protector -z execstack shellcode.c -o shellcode

Testing the Egghunter

The Egghunter is ready test and see how it works. So I’ll start it running in gdb. Once gdb is up and running I need to set a breakpoint. I can get the memory address at the start of the egghunter instructions which are stored in the code variable by using:

disassemble code

The output below is an extract from the command:

Dump of assembler code for function code:
   0x0804a080 <+0>: xor    ecx,ecx
   0x0804a082 <+2>: or     cx,0xfff
   0x0804a087 <+7>: inc    ecx
   0x0804a088 <+8>: push   0x43
   0x0804a08a <+10>: pop    eax
   0x0804a08b <+11>: int    0x80
   0x0804a08d <+13>: cmp    al,0xf2
   0x0804a08f <+15>: je     0x804a082 <code+2>
   0x0804a091 <+17>: mov    eax,0x41414141
   0x0804a096 <+22>: mov    edi,ecx
   0x0804a098 <+24>: scas   eax,DWORD PTR es:[edi]
   0x0804a099 <+25>: jne    0x804a087 <code+7>
   0x0804a09b <+27>: scas   eax,DWORD PTR es:[edi]
   0x0804a09c <+28>: jne    0x804a087 <code+7>
   0x0804a09e <+30>: jmp    edi
   0x0804a0a0 <+32>: add    BYTE PTR [eax],al
End of assembler dump.

Set breakpoints for the final jump instructions at <code+30> using:

b *0x0804a09e

When the Egghunter is run it stops at the breakpoint it will have found both eggs. We can then view the 1st and 2nd eggs by using the ECX and ECX+4 memory addresses which are 4 Bytes apart both contain the EGGSIG.

slae_a2_gdb_view_eggs

I can view the instructions that the Egghunter shellcode will jump to by using the disassemble command on the value in the EDI register. The EDI register points to the memory address 0x0804A048 which is the located at <egg+8> and is the first instruction of the egg shellcode.

slae_a2_gdb_jump_to_egg_shellcode

As I continue execution the egg is executed as expected, the ‘Egg Found!’ string is highlighted in yellow below. The egg then exits gracefully and gdb informs us that the program is no longer running.

slae_a2_gdb_execute_egg_prints_egg_found

Configuring the Egg to use

The final part of the assignment is to provide a way of being able to configure the egg shellcode that will be executed by the egg hunter. For this assignment I’m going to do this using a simple bash shell. The script will have two versions and perform the following steps:

  1. Extract the machine instructions for the egg executable/Assemble the egg shellcode depending on which version of the script is used
  2. Construct a shellcode.c source file
  3. Compile the shellcode.c source file.

The script will require an assembled version of the shellcode from which to extract the machine code instructions.

Script 1: egg _asm_config.sh

The script takes the assembly source file as input and produces an executable called ‘egghunter’. The assembly source file is the ‘egg’ shellcode that will be executed by the egghunter. The argument for the script is the name of the assembly file for example egg.asm without the file extension i.e. egg. The script is run using the following format:

./egg_asm_config.sh egg

The script itself performs the following steps:

  • Assembles the source file usng nasm and ld
  • A number of echo commands are used to pipe the C source file to tmp.c
  • The command I’ve used earlier in the assignment to extract the machine code instructions and pipe the to the tmp.c file
  • gcc is used to compile the tmp.c program
  • The tmp. program is deleted so that no residual files are left behind after the script is run.
#!/bin/bash
echo '[+] Assembling with Nasm..... '
nasm -f elf32 -o $1.o $1.asm

echo '[+] Linking ...'
ld -z execstack -o _$1 $1.o

echo '[+] Construct Shellcode.c.....'

echo '[+] Create C Program.....'
echo  '
#define EGGSIG "\x41\x41\x41\x41"
#include
#include

unsigned char egg[] = \
EGGSIG EGGSIG' >> tmp.c

objdump -s  ./_$1 | grep -v '^ [0-9a-f][0-9a-f][0-9a-f][0-9a-f] \b' | grep -v 'Contents' | grep -v '^./' | cut -d' ' -f 3-6| sed 's/ //g' | sed '/./!d' | tr -d '\n'| sed 's/.\{2\}/&\\x/g' | sed 's/^/\\x/'|sed 's/..$//'|sed 's/^/"/;s/$/"/g' >> tmp.c

echo ';

unsigned char code[] = \
"\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74"
"\xf1\xb8\x41\x41\x41\x41\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7";

int main()
{

 printf("Shellcode Length:  %d\n", strlen(code));

 int (*ret)() = (int(*)())code;

 ret();
}' >> tmp.c

echo '[+] Compile egghunter C program.....'
gcc -fno-stack-protector -z execstack tmp.c -o egghunter
rm tmp.c

echo '[+] Done!'

Script 1: egg _exe_config.sh

The 2nd script is the same as the first script but with the section containing the assembly commands removed. The script takes an executable file name as input and produces another executable called ‘egghunter’. The argument required by the script is the name of the executable ‘egg’ file name. The script is run using the following format:

./egg_asm_config.sh egg

The script is as follows:

#!/bin/bash
echo '[+] Create C Program.....'
echo  '
#define EGGSIG "\x41\x41\x41\x41"
#include
#include

unsigned char egg[] = \
EGGSIG EGGSIG' >> tmp.c
objdump -s  ./$1 | grep -v '^ [0-9a-f][0-9a-f][0-9a-f][0-9a-f] \b' | grep -v 'Contents' | grep -v '^./' | cut -d' ' -f 3-6| sed 's/ //g' | sed '/./!d' | tr -d '\n'| sed 's/.\{2\}/&\\x/g' | sed 's/^/\\x/'|sed 's/..$//'|sed 's/^/"/;s/$/"/g' >> tmp.c
echo ';
unsigned char code[] = \
"\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74"
"\xf1\xb8\x41\x41\x41\x41\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7";

int main()
{
 printf("Shellcode Length:  %d\n", strlen(code));
 int (*ret)() = (int(*)())code;
 ret();
}' >> tmp.c

echo '[+] Compile egghunter .....'
gcc -ggdb -fno-stack-protector -z execstack tmp.c -o egghunter
rm tmp.c

echo '[+] Done!'

Assignment Review

When I was working through the assignment I found it very difficult to create the ‘egghunter’ shellcode in a way which was significantly original as there are very few system calls and instructions required to write it. When reading about the egg hunter I came across the concept of an omelette hunter which searches for multiple eggs. So I thought it would be fun to have a go at writing an omelette hunter which would also mean I had some original code for the assignment.

Return of the Egg hunter, arise Omelette hunter

The omelette hunter I’ve written is a little more complex than the original egg hunter shellcode. My omelette hunter also has a limitation which is that the stack must be executable as the eggs which are being searched for are copied to the stack and then executed.

Omelette hunter Overview

The omelette hunter has 4 main sections:

  1. calc_stack_addr: Calculate the stack location to start storing each ‘egg’ as it is found
  2. find_egg: Locates the current egg
  3. copy_shellcode: Copies the egg instructions to the stack location calculated in step 1
  4. run_shellcode: Gets the location of the constructed omelette on the stack and jumps to it.

Omelette Initialisation

In the omelette hunter there are a couple of constants defined using the ‘EQU’ instruction. They are relatively self explanatory.

omlette_size equ 0x2      ; Number of eggs required to make omelette 
egg_size equ 0x26         ; Size of each egg instructions
egg_extra equ 0x20        ; Extra padding on the stack
egg_marker equ 0x41414101 ; Egg signature used to find each 'egg'

calc_stack_addr

calc_stack_addr: Notes

  • The space on the stack required for each egg is increased by 32-Bytes per egg to ensure there no overlap of the combined eggs which could cause the top of the stack to be overwritten when the shellcode is copied onto the stack. The top being the lowest stack memory address.
    • The padding size is set using egg_pad
  • The start of the stack location which will be used to store the eggs is stored twice on the stack as it is used in the copy_shellcode and the run_shellcode sections.

calc_stack_addr: Execution steps

  • Calculates the size required for each egg including the padding
  • Subtracts the total amount from the current stack location ESI
  • Stores the calculated memory address on the stack twice

calc_stack_addr: Instructions

The ‘calc_stack_addr’ instructions are as follows:

calc_stack_addr:
 XOR ebx, ebx          ; Zero EAX, EBX and EDX registers
 MUL ebx               ; Zero EAX, EBX and EDX registers
 mov al, egg_size      ; Set Egg Size
 add eax, egg_pad      ; Add additional space to ensure the stack location will
                       ; be able to hold the eggs
                       ; The EAX register now contains the egg_size + egg_pad 
                       
 mov bl, omlette_size  ; Set the omlette size, i.e. the number of eggs used
 XOR ebp, ebp          ; Zero the EBP register which will be used as the 
                       ; egg counter
 mul ebx               ; Calculate the total space required for the shellcode
                       ; Multiply omelette_size * (egg_size + egg_pad)
                       ; EAX contains required space
 mov edi, esp          ; Store the current stack address
 sub edi, eax          ; Calculate the start address for the reassembled 
                       ; shellcode. Subtract Total Bytes required from the
                       ; current stack pointer address.     
 push edi              ; Save stack address where the start of the eggs shellcode 
                       ; instructions will be copied. It is used to jump to the
                       ; egg shellcode in the run_shellcode section
 push edi              ; Save again. It is used in the copy_shellcode section

find_egg

The find_egg section iterates through the virtual address space searching for the Egg signature, it’s very similar to the egg hunter shellcode.

find_egg: Execution Steps

  • Setup the ECX register to store the memory location to be checked
  • Call the sys_sigaction() system call to test if the memory address can be safely accessed
  • Using the scasd system call compare the value at the memory location to the 1st 4 Bytes of the egg signature
    • The egg signature is incremented by the loop counter to account for the number of the Egg being hunted for.
  • Repeat the scasd system call to check for the 2nd 4 Bytes of Egg signature
    • When the Egg signature is found twice the location of the Egg has been found the scasd() call increments the memory address, as a result after the 2nd call the memory location of the Egg is stored in EDI
  • Store the memory location of the Egg which has been located.

find_egg: Instructions

The ‘find_egg’ instructions are as follows:

find_egg:
 xor ecx, ecx      ; Zero EAX, ECX and EDX registers
page_inc:
 or  cx, 0xfff     ; Set the memory address to test with sigaction()
                   ; The 'or' instruction essentially increments 
                   ; the current value by 0xfff. 
                   ; Using 0xfff and then inc means there isn't a
                   ; NULL Byte in the shellcode. 
check_mem:
 inc ecx           ; Increment ECX so that lowest 2 Bytes of the 
                   ; EAX register is 0x1000
 push byte 0x43    ; Store 0x43 on the stack
 pop eax           ; Set sigaction() system call ID
 int 0x80          ; Execute system call
 cmp al, 0xf2      ; Test to see if the memory location is valid. 
 jz page_inc       ; If memory isn't valid loop again to next memory location
                   ; Program execution only reaches this point when valid 
                   ; memory is found 
 mov eax, egg_sig  ; Set the Egg signature in the EAX register 
 add eax, ebp      ; Increment the shellcode market to match the 
                   ; Egg being hunted for
 mov edi, ecx      ; Move the valid memory address to EDI
 scasd             ; Scan the memory address in EDI to see if it 
                   ; contains the 1st 4 Bytes of the egg
 jnz check_mem     ; If no match, loop back to check another address
 scasd             ; Scan the memory address in EDI to see if it 
                   ; contains the 2nd 4 Bytes of the Egg 
 jnz check_mem     ; If no match, loop back to check another address
 push edi          ; Store the memory location of the egg shellcode
                   ; on the stack.

copy_shellcode

The copy_shellcode section copies the egg shellcode from the memory address located in the find_egg section onto the stack.

copy_shellcode: notes

The egg instructions are copied onto the stack using movsb. The movsb instructions works in the following way:

  • movsb copies byte by byte from the memory location in ESI to the memory location in EDI
    • Source Memory Address: ESI – The Egg location
    • Destination Memory Address: EDI – The stack location must be in EDI
    • Number of Bytes to move: ECX, Size will be ‘egg_size + egg_extra’

copy_shellcode: Execution Steps

  • Restore the memory location of the egg into the ESI register, the source location for movsb
  • Restore the location on the stack to copy the Egg to.
  • Copy the egg using the sys_movsb() system call
  • Save the location to store the next Egg on the stack
  • Increment the Egg counter value
  • Test to see if anymore Eggs are needed for the ‘omelette’

copy_shellcode: Instructions

The ‘copy_shellcode’ instructions are as follows:

copy_shellcode:
 pop esi               ; movsb source: Restore memory location of the egg
 pop edi               ; movsb destination: Restore location on stack to store
                       ; the shellcode. 
 xor ecx, ecx          ; Zero ECX
 mov cl, egg_size      ; Set the egg_size in the CL register
 rep movsb             ; Increments source and destination for each Byte copied.  
 push edi              ; Save the location where to copy next egg onto the stack. 
 inc ebp               ; Increment Egg counter 
 cmp ebp, omlette_size ; Test loop counter for number of eggs
 jne find_egg          ; If there are more eggs to find, jump to find_egg 
                       ; to search for the next egg

exec_omelette

The final section of the omelette hunter is very straight forward, it just moves program execution to the omelette instructions. It does this by popping the start location of the omelette from the stack. The address was stored on the stack at the end of very first section.

exec_omelette: Instructions

The ‘exec_omellete’ instructions are as follows:

 pop edi     ; Discard address stored on the stack in copy_shellcode, need to 
             ; get to the next memory address
 pop edi     ; Restore the memory address of the start of the omelette on the 
             ; stack, which was stored in the calc_stack_addr section
 jmp edi     ; Execute the omelette shellcode by jumping to the memory address on 
             ; the stack.

Extracting the Omelette Hunter machine code Instructions

I’ll use the same process as the egg hunter to extract the machine code.

objdump -s  ./omelette | grep -v '^ [0-9a-f][0-9a-f][0-9a-f][0-9a-f] \b' | grep -v 'Contents' | grep -v '^./' 
| cut -d' ' -f 3-6| sed 's/ //g' | sed '/./!d' | tr -d '\n'| sed 's/.\{2\}/&\\x/g' | sed 's/^/\\x/'|sed 's/..$//'|
sed 's/^/"/;s/$/"/g'

The extracted machine instructions from the omlette hunter shellcode are:

"\x31\xdb\xf7\xe3\xb0\x26\x83\xc0\x20\xb3\x02\x31\xed\xf7\xe3\x89\xe7\x29\xc7\x57"
"\x57\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xf1\xb8\x01"
"\x41\x41\x41\x01\xe8\x89\xcf\xaf\x75\xea\xaf\x75\xe7\x57\x5e\x5f\x31\xc9\xb1\x26"
"\xf3\xa4\x57\x45\x83\xfd\x02\x75\xd0\x5f\x5f\xff\xe7"

Setting up the omelette hunter

The omelette hunter shellcode is ready and as with the egg hunter it needs to be setup so that it can be tested. For the omelette hunter I need two different eggs so that I can demonstrate that the eggs are being found and executed.

Egg1 and Egg2

The two eggs are identical apart from the message variable which identifies the Egg number.

global _start
_start:
 xor ebx, ebx
 mul ebx 
 ; write() system call
 mov al, 0x4
 mov bl, 0x1
 jmp short variabledef 
set_string:
 pop ecx
 mov dl, 0xD
 int 0x80
  ; Exit gracefully
 xor eax, eax
 mov ebx, eax
 mov al, 0x1
 mov bl, 0x5
 int 0x80
variabledef:
 call set_string
 message: dw "Eggx Found!", 0xA

Extracting the egg machine code Instructions

The machine code instructions for egg1 are:

"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x0f\x59\xb2\x0d\xcd\x80\x31\xc0\x89\xc3"
"\xb0\x01\xb3\x05\xcd\x80\xe8\xec\xff\xff\xff\x45\x67\x67\x31\x20\x46\x6f\x75"
"\x6e\x64\x21\x00\x0a\x00"

The machine code instructions for egg2 are:

"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x0f\x59\xb2\x0d\xcd\x80\x31\xc0\x89\xc3"
"\xb0\x01\xb3\x05\xcd\x80\xe8\xec\xff\xff\xff\x45\x67\x67\x32\x20\x46\x6f\x75"
"\x6e\x64\x21\x00\x0a\x00"

Setting up shellcode.c

I have the machine instructions for the ‘omelette hunter’ and the two eggs. They are used to construct a ‘C’ program using the shellcode.c template.

  • The egg signatures are declared as EGGSIG1 and EGGSIG2 using ‘define’
  • The actual egg is constructed using the format blow which gives an 8 Byte egg signature
EGGSIG1 EGGSIG1

The shellcode.c source code below shows the three strings

  • code: The egghunter instructions
  • egg1: The first set of egg instructions.
  • egg2: The second set of egg instructions
#define EGGSIG1 "\x01\x41\x41\x41"
#define EGGSIG2 "\x02\x41\x41\x41"
#include
#include
unsigned char egg1[] =\
EGGSIG1
EGGSIG1
"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x07\x59\xb2\x0b\xcd\x80\xeb\x10"
"\xe8\xf4\xff\xff\xff\x45\x67\x67\x31\x20\x46\x6f\x75\x6e\x64\x21\x90"
"\x90\x90\x90\x90";

unsigned char egg2[] =\
EGGSIG2
EGGSIG2
"\x31\xdb\xf7\xe3\xb0\x04\xb3\x01\xeb\x0c\x59\xb2\x0b\xcd\x80\x31\xc0"
"\x40\x31\xdb\xcd\x80\xe8\xef\xff\xff\xff\x45\x67\x67\x32\x20\x46\x6f"
"\x75\x6e\x64\x21";

unsigned char code[] = \
"\x31\xdb\xf7\xe3\xb0\x26\x83\xc0\x20\xb3\x02\x31\xed\xf7\xe3\x89\xe7"
"\x29\xc7\x57\x57\x31\xc9\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80"
"\x3c\xf2\x74\xf1\xb8\x01\x41\x41\x41\x01\xe8\x89\xcf\xaf\x75\xea\xaf"
"\x75\xe7\x57\x5e\x5f\x31\xc9\xb1\x26\xf3\xa4\x57\x45\x83\xfd\x02\x75"
"\xd0\x5f\x5f\xff\xe7";

int main()
{
 printf("Code Length:  %d\n", strlen(code));
 printf("egg1 Length:  %d\n", strlen(egg1));
 printf("egg2 Length:  %d\n", strlen(egg2));
    int (*ret)() = (int(*)())code;
 ret();
}

The omelette hunter is compiled using the following gcc command:

gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Testing the omelette hunter

Once compiled the omelette hunter can be tested by simply running the program.

slae_a2_omelette_hunter_egg_found

As can be seen in the screenshot above the shellcode program gives the size of the shellcode, egg1 and egg2. Once printed the two eggs are executed and print out the string they contain.

Assignment Overview

The assignment has been a very interesting exercise and I have learnt a lot from completing it. The omelette hunter was certainly a more complex than the other assignments and took a little bit of time to debug some aspects of the program. In my view certifications like this which are practical in nature really do provide significantly more learning those which are jut fact based or theoretical.

Source Code

The source code for the egg hunter, egg config and omelette hunter applications can be found in the following Git Hub repository

https://github.com/raidersofthelostarg/slae/tree/master/assignment-3

SLAE Student Details

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE-793

Advertisements
This entry was posted in SLAE and tagged , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s