We look in detail about Angler Exploit pack’s fileless infection. Thanks to friends at malware-traffic-analysis.net who provided captures of two different instances of Angler exploit pack delivery. You can download the samples and captures from these links Link1, Link2. There is one technical blog about this infection chain. I am going to add in some more information about this particular instance.

The original malware delivery chain looks like this:

The binary file is downloaded immediately after the first URL visit. No other payloads are downloaded in between. So it is clearly an IE exploit.

The initial exploit payload is obfuscated using a string replacement technique.

After De-obfuscating this, we can see the original logic applied to deliver the exploit.

It looks for various AV vendor’s windows driver filename to see whether any AV running in the victim machine. We see this check regularly in Exploit packs in recent days. It looks for vulnerable Flash, Silverlight, JRE and IE. If it finds a vulnerable IE then it will execute the CVE-2013-2551 Exploit. The IE vulnerability is found by Vupen. You can read more about this in Vupen blog and in my previous blog. The exploit is obfuscated to some level. After de-obfuscating and renaming, it looks like this.

The Javascript code has a “string obfuscator” to encode few variables in the shellcode part. The parameter passed to the exploitme() function is the final shellcode executed after setting up the “environment” once triggering the vulnerability. The “Javascript escaped” strings stored in ‘shellcodeFirstPart’ , ‘shellcodeSecondPart’, ‘shellcodeThirdPart’, ‘shellcodeFourthPart’ are encoded using the simple logic shown below.

The shellcode that includes executing the initial ROP and setting up the stack and register and final shellcode is constructed in retShellcodeStartAddress() function. retShellcodeStartAddress() constructs the full shellcode and return the address to the caller.

retShellcodeStartAddress() uses returnShellcode() to build the second stage shellcode. That includes saving all the registers and calling a “decoder” that decodes the third stage shellcode (‘shellcodeFirstPart’ , ‘shellcodeSecondPart’, ‘shellcodeThirdPart’, ‘shellcodeFourthPart’).

The variable ‘DAC5cw’ is the original decoder that decodes the third stage shellcode. Check the comparison below.

Once the control reaches third stage shellcode, it finds the kernel32.dll base and it start resolving few API’s by parsing PE format.

It resolves these functions:

WinExec

LoadLibraryA

GetProcAddress

GetTempPathA

VirtualAlloc

VirtualFree

CreateFileA

WriteFile

CloseHandle

CreateThread

WaitForSingleObject

InternetOpenA

InternetReadFile

InternetCloseHandle

Once resolving these functions, it will download the binary file from the target URL and save that in-memory. The download binary is in encoded form.

The third stage shellcode decodes the download binary using a static key “adR2b4nh”.

All the decision on whether to save and execute the downloaded binary or execute in-memory is all depends on the first two bytes of the download binary. If the first two bytes of the payload is “MZ” then it will write it into disk and registers the file using regsvr and continue execution. Otherwise if the first two bytes is 0x9090 then it will continue executing that buffer.

The binary blog following 0x9090 is actually a shellcode that does the loading of this DLL in-memory using “Reflective-DLL” loading technique. It starts resolving kernel32.dll and other exported API’s using API hashing technique.

Once it finish resolving DLL’s and API’s, it will start doing the operations related to the “Reflective DLL” loading technique. The steps it takes to load the DLL is very similar to the code shown here. I see one small difference in this malware sample. In the original code, it used PE parsing technique to relocate the DLL but this sample using windows undocumented API’s RtlImageDirectoryEntryToData() and LdrProcessRelocationBlock() to do that.

The loaded DLL has many export functions:

ATrailingAllTo()

DefiningSFirstIs()

FileBoth()

IsInformationPreservedSyntax()

IsLineValueMust()

MatterTrailingLeast()

SameAreWhich()

StartingASyntax()

ThereTruthAPair()

ValueLinesThe()

The in-memory payload is a nightmare for detection technologies that depends mostly on the file system activities.