The usual pattern we see when dealing with exploit kits starts with a legitimate website that gets compromised and used to automatically redirect its visitors to the actual malicious content.
The usual pattern we see when dealing with exploit kits starts with a legitimate website that gets compromised and used to automatically redirect its visitors to the actual malicious content. Techniques such as iFrame injection and HTTP redirections are frequently observed.
This week though, we found an interesting variation while doing research on some exploit kit traffic. We noticed that the compromised website contained code that actually interacts with the user by presenting a fake message about some script slowing down the browser.
The code responsible for this interaction is an injected HTML form that is shown only when the visiting browser is Internet Explorer. We can also see that some data is sent along with the POST request, we will come back to this in a moment.
Now let’s go back to the data sent along with the POST request. We can see that it is encoded with Base64, but decoding it yields random-looking data.
>>> ua_base64 =
We can guess from the parameter name ‘ua’ that it contains the User-Agent string of the browser, which we know in our test was :
“Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET4.0C; .NET4.0E; BOIE8;ENUSMSCOM)”.
What if the parameters were all XOR’ed with the same keystream? Let’s use this plaintext knowledge to obtain the keystream by XOR’ing the base64-decoded encrypted User-Agent string with our known plaintext (in lower case). If our theory is correct, using the keystream obtained this way to XOR the value of the ‘furl ‘ parameter would yield the URL of the Angler EK landing page…
def xor(message, key):
decrypted = “”
for i in range(0, len(message)):
decrypted += chr(ord(message[i]) ^ ord(key[i%len(key)]))
ua = “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET4.0C; .NET4.0E; BOIE8;ENUSMSCOM)”
ua_plaintext = ua.lower()
ua_base64 = “tlP7Vt89hmr1vjdAW8YqmDT/sGFiyxROsPBX45R6HxinEeZC+YGrgEA0mmA3NDEJUYzgWm29EKShU2QPqxBXzVNMJvpfJN3QcVGGehPCNNXOlxo0JE94z0RTBgCq0VubolrWHmAexV14+cqx6qILC6z1EZDl4JFYd32wrMZrhNinl47lzpnvXwPluNsmh0CA”
furl_base64 = “s0j1T4l+yCai5DANXd0gmz38sX5pwRVb/vhQpcU9Qlj8G6tQ5Nc=”
keystream = xor(base64.b64decode(ua_base64), ua_plaintext)
print “Decrypted furl:”
$ python angler-dexor.py
Typically the visitors are automatically redirected to the exploit kit when they visit a compromised website, so why bother with displaying a message first? It might be to prevent automated systems (malware analysis sandboxes, search-engine bots etc.) from reaching the exploit kit, making it harder for researchers to track and investigate such a threat.
The malware that was being distributed at the time we performed our research was Win32/PSW.Papras.CX (SHA1: 7484063282050af9117605a49770ea761eb4549d).