Metasploit Addition Two – Electric Boogaloo

What about Linux? Why all the love for Windows? What is this crap?

The code for linux is a bit different in MSF. They use a modified ELF template that puts the shellcode directly into the end of the file which is built by nasm. Example:

; build with:
;   nasm elf_x86_template.s -f bin -o template_x86_linux.bin

BITS 32

org 0x08048000

ehdr:                            ; Elf32_Ehdr
  db    0x7F, "ELF", 1, 1, 1, 0  ;   e_ident
  db    0, 0, 0, 0,  0, 0, 0, 0  ;
  dw    2                        ;   e_type       = ET_EXEC for an executable
  dw    3                        ;   e_machine
  dd    1                        ;   e_version
  dd    _start                   ;   e_entry
  dd    phdr - $                ;   e_phoff
  dd    0                        ;   e_shoff
  dd    0                        ;   e_flags
  dw    ehdrsize                 ;   e_ehsize
  dw    phdrsize                 ;   e_phentsize
  dw    1                        ;   e_phnum
  dw    0                        ;   e_shentsize
  dw    0                        ;   e_shnum
  dw    0                        ;   e_shstrndx

ehdrsize equ  $ - ehdr

phdr:                            ; Elf32_Phdr
  dd    1                        ;   p_type       = PT_LOAD
  dd    0                        ;   p_offset
  dd    $                       ;   p_vaddr
  dd    $                       ;   p_paddr
  dd    0xDEADBEEF               ;   p_filesz
  dd    0xDEADBEEF               ;   p_memsz
  dd    7                        ;   p_flags      = rwx
  dd    0x1000                   ;   p_align

phdrsize equ  $ - phdr

global _start

_start:
; MSF puts the shellcode here

 

We would have to generate a new elf template file each time with our date check called prior to shellcode execution. From there, we would have to call our system call functions. Modification of this code however isn’t going very well. Metasploit uses a core class for setting these elf files and modifying the entire thing just to fit this one feature is…hard to say the least. I had considered first writing my stuff in C, then assembly, but this can all be made simpler in Linux with syscalls. The following code piece does the same as we did with windows, except its much smaller / easier to implement. Before we show off the assemblers, let’s go over syscalls. Everything in Linux is done via syscalls – everything from opening files to resetting the computer. Think of them as like interrupts for DOS (god I am OLD). As per the Linux man pages: “The system call is the fundamental interface between an application and the Linux kernel.”. Any time a program has to do anything special like read a read or write a file, or fork a new process, a syscall is made. Each architecture on linux will have the same system call table. You can find the syscall table for each architecture on github or the net. I used this one for x64 intel. For x86, I used the table here. The sys_time system call is used for obtaining the Unix epoch which is the number of seconds elapsed since 1970. An example would be 1545094801 in decimal or 0x‭5C184691‬ in hex. This result is stored in a register EAX on x86 or RAX on x64 intel. Our code calls his syscall and compares it against the time we have stored which is supposed to be one months from now or plus an additional 2592000 seconds. Finally we have an old assembly friend for crashing – EB FE – jump two bytes backward from the current position while also moving two spaces forward. An infinite loop in two instructions. And now without further ado, the code:

section .text
global _start

_start:

; use syscall for epoch, compare it 30 days in future, check if older, crash
;------------------------------------------------------------------------------
mov al,0x0D ;sys_time is 13 vvvv current epoch plus one month
int 0x80 ; only x64 uses syscall instruction, use int 0x80 instead
mov ebx, 0x58D15D5F
cmp eax, ebx
jge rockit
mov al, 1 ;exit
int 0x80
rockit:
db 0xEB
db 0xFE

All in all, I have the thing down to 18 bytes with no null bytes.

char *scode = "\xb0\x0d\xcd\x80\xbb\x5f\x5d\xd1\x58\x39\xd8\x7d\x04\xb0\x01\xcd\x80\xeb\xfe";

Here I have the same thing except with x64 code. Not much is different other than the use of the mnemonic ‘syscall’ instead of ‘int 0x80’ and the number of the syscall.

section .text
global _start

_start:

; use syscall for epoch, compare it 30 days in future, check if older, crash
;------------------------------------------------------------------------------

mov al,0xc9 ;sys_time 201 vvvv current epoch plus one month
syscall
mov ebx, 0x58D15D5F
cmp eax, ebx
jge rockit
mov al, 1 ;exit
syscall
rockit:
db 0xEB
db 0xFE

And here we have our shellcode again:

char scoder* = "\xb0\x0d\xcd\x80\xbb\x5f\x5d\xd1\x58\x39\xd8\x7d\x04\xb0\x01\xcd\x80\xeb\xfe";

Someone once asked me how the heck do you code assembly without the nulls and I said “use the smaller registers so there is no padding”. I could spend a whole blog post on that alone.

 

So how the hell do we take this and implement it in metasploit? We could always modify the template files by adding our check to the bottom just below ‘start’, and that would work for all files, but it would have to be done for EVERY SINGLE TEMPLATE, so its becomes a pain in the ass. Then someone (HD Moore) told me about the ‘PrependEncoder‘ option present in Metasploit when writing exploits.

Basically it allows us to prepend shellcode to the payload that is executed first. In this case, we are adjusting the size of the stack, but it doesn’t have to be that. Why not add our date check there instead? “\xb0\x0d\xcd\x80\xbb\x5f\x5d\xd1\x58\x39\xd8\x7d\x04\xb0\x01\xcd\x80\xeb\xfe”; would fit great right there.

This is basically where I am at with this. I need to figure out how to programmatically add my code via command line argument to new exploits and payloads. And before you ask, I did think about how I would dynamically add the epoch in hex to the assembly in ruby:

 

My commit is presently in limbo while I try and figure out how to make use of the PrependEncoder option programmatically so until then, this technique is in my posession and not the world’s.

 

Until next time, happy hacking!

 

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.