| 06 May 2013
Most drive-by exploit kits use a minimal exploit shellcode that downloads and runs the final payload. This is akin to a two-stage ICBM (InterContinental Ballistic Missile) where the first stage, the exploit, puts the rocket in its trajectory and the second stage, the payload, inflicts the damage. In the cybercrime world, the de-coupling of the first stage from the payload is designed to make sure that an exploit kit is as generic as possible and can deliver all possible payloads, provided that the payloads only need native execution (either as a standalone executable – files with an “.exe” file extension, or DLL registration via RegSvr32 – files with a “.dll” extension).
Trusteer’s CTO Amit Klein said, “ We recently found that a Java exploit kit called ‘g01pack’ has added another ‘mid-course’ stage, turning the infection process into a multi-stage attack. The first stage of the attack, the exploit shellcode, executes a second stage, in which a Java class runs in a separate Java process. This second Java process then downloads and runs the final payload. We believe this discovery represents the first instance of an exploit kit delivering its payload via a multi-stage attack.”
Why would an attacker need a multi-staged exploit? To use the ICBM analogy; much like the way an ICBM uses multiple stages to obtain a longer range, the attacker uses multiple stages to distance the attack launch site from its final destination. By utilizing an extra stage, the attack is more likely to bypass some security products: the initially exploited process (Java) launches another Java process (second stage) that appears less suspicious, and only that second stage process runs the final, native payload (the persistent malware dropper).
This is supported by the analysis we performed using various security tools and the poor detection rate we observed: Out of 46 tools tested (in file scanning mode) only eight tools identified the first stage JAR as malicious, and only two identified the second stage class (cabOrgies.class) as malicious.
Klein continued, “We observed this multi-staged exploit approach in one of the vulnerabilities exploited by the ‘g01pack’ exploit kit - the well-known Java vulnerability CVE-2012-1723 (which dates back to mid-2012). This vulnerability allows the exploit to break out of the Java sandbox. It has long since been patched by Oracle, but apparently there are enough unpatched targets to make this attack worthwhile.
Figure 1: Exploit Kit 'g01pack' – Multi-Stage Attack
Although the Java exploit we researched is part of the g01pack exploit kit, it is interesting to note that some implementation details are similar to the exploit used by BlackHole for CVE-2012-1723, identified in mid-2012 (described in a Symantec blog). The BlackHole approach, however, was a typical “exploit-payload” scheme, not the “exploit-intermediate process-payload” scheme we see here.
The final payload is, of course, malware – we noticed many malware families being distributed by this specific exploit kit – Zeus, Torpig, Gozi, Shylock, and there are most likely many others. The exploit kit is used to infect targets globally, with the current infection rate estimated at 1:3,000 machines per month (payload executions from this exploit kit alone!). This very high infection rate proves the effectiveness of this multi-stage approach. Therefore, it is highly likely that other exploit kits will incorporate a similar approach.
Getting into the details
Stage One: Exploiting CVE-2012-1723
Stage one begins when the browser navigates to a webpage that contains HTML code and an Applet tag. When the browser renders the content of the webpage, the Applet tag instructs the browser to launch a Java class from a URL designated in the Applet tag using arguments given in the Applet tag. These arguments contain the encrypted URL of the final payload– this can be a Windows executable (parameter name is “date”) or a Windows DLL file (parameter name “guid”).
For example, the Applet tag would be:
<applet archive="[example].jar" code="critical.securityupdate.class">
This instructs the browser to launch Java (the “javaw.exe” process) with the JAR URL (in our example the “[example].jar” is located in the same host and folder originally accessed by the browser), the class name (package “critical”, class “securityupdate”), and the parameters (in our case “date” whose value is a long encrypted string, representing the URL of the final payload).
Java then retrieves the JAR URL and invokes the Applet class from the package.
The JAR file:
The malicious JAR file implements a Java package called “critical,” and contains 6 Java classes (.class files):
Applet implementation + exploit code for CVE-2012-1723
Exploit code for CVE-2012-1723
Post exploitation code
Stage two class
Small helper class
Small helper class
Java starts by running the init() method of the applet class “securityupdate.” This function first ensures that it is running on a Windows platform, and that the JRE version is not “1.7” (i.e. it ensures it does not run on Java 7; in fact the exploit will succeed only for Java versions 6u10-6u32 inclusive). Next, the function uses the Java class “entry” to exploit CVE-2012-1723 and escape out of the Java sandbox. A patch for this vulnerability is available, but apparently there are still enough unpatched Java 6 installations to make it a valuable target for exploit kit writers.
A successful exploitation results in running the method “JiXU” of class “keaVestAltho” with high privileges. This method contains a hard-coded encrypted string which represents the ‘in memory’ class “remoterEhPoplin.” The method decrypts the string, creates the class from it and invokes the class constructor with 3 arguments: the Applet’s “date” parameter, the Applet’s “guid” parameter, and a byte array representing the second stage class “cabOrgies” (which the method copied into memory from the corresponding JAR resource).
The constructor for class remoterEhPoplin (the “in memory” class) has the following flow:
- Retrieves the Java temporary directory (Java property “java.io.tmpdir”) into tmpdir (this defaults in Windows to %TEMP%).
- Looks for the Java executable in the following locations (first match is used):
- Creates a directory tmpdir\critical\
- Copies the second stage code from memory into file tmpdir\critical\cabOrgies.class
- If the second argument for the constructor (the Applet’s “guid” parameter) is non-null, it will launch the command:
cmd /c start "" /min "java" "critical/cabOrgies" main "guid" 1
- If the first argument for the constructor (the Applet’s “date” parameter) is non-null, it will launch:
cmd /c start "" /min "java" "critical/cabOrgies" main "date" 0
[Steps 5 and 6 launch the command with the current process environment, and with tmpdir as the current working directory]
- If step 5 or 6 fail (e.g. because the Java executable wasn’t located), it will continue to run the second stage logic by itself (see below).
As you can see, in steps 5 and 6, the Java process launches another new Java process with (a copy of) the second stage class. Note that the “date” and “guid” parameters of the Applet tag (which contain the payload URL in an encrypted form) are transferred as-is in the Java invocation command line. The EXE/DLL indicator becomes the third parameter (set to ‘0’ for EXE or ‘1’ for DLL).
For the example above, the following command will be executed:
cmd /c start "" /min "C:\ProgramFiles\Java\jre6\bin\javaw.exe" "critical/cabOrgies" main "0rDGkpLh3/XIHXCLuk;P/bpCPd-gE/ppLDGDtuGw;;bhOEzwbNDOwiNpbErXuiOQy%NbOqdqgg-11NCGw/COQvXNXOdgN3b/EbOSdrd1SN" 0
This launches Java (javaw.exe) in a new, minimized window with an empty title.
StageTwo: A New Java Process
A new Java process is launched with the working directory set to %TEMP%. This directory includes a package (folder) called “critical” which includes a class file called “cabOrgies.”
The Java process is launched with four command line arguments: "critical/cabOrgies", “main” (ignored), the encrypted URL and an EXE/DLL indicator. This instructs Java to invoke the main() method of the class cabOrgies found in %TEMP%\critical/cabOrgies.class with a string array containing the following three command line arguments (“main”, the encrypted URL, and the EXE/DLL indicator).
It follows this workflow:
1. The string is decrypted using a hard-coded one-character permutation (Caesar cipher).
2. The plaintext string contains a list of URLs separated by semicolons (in practice we saw only a single URL).
3. For each URL:
a. It computes a destination full path file for the payload:
i. Uses the Java temporary directory from the java.io.tmpdir Java property and appends a slash
ii. Appends a file name randomly selected from "alg", "jqs", "spoolsv", "skype", "icq", "mstsc", "teamviewer", "notepad", "conhost", "winlogon", "csrss", "rundll32", "java", "jucheck", "flashplayer", "googleupdate", "windowsupdate", "acrobat", "acrobatreader", "ctfmon", "vlcplayer", "firefox", "chrome", "iexplore", "msconfig", "opera"
iii. Appends “.dll” if the EXE/DLL indicator is set to ‘1’, otherwise appends “.exe”
iv. If the resulting file exists, go to (i) - unless this has been tried 100 times
v. Do steps i-iii but add 3-7 random digits after the file name (before the extension)
vi. If the resulting file exists, go to (v)
b. Prepends “http://” to the URL if necessary
c. Sends a GET request to the URL (use system proxy if such is defined)
d. Reads the first byte from the response body – this is a one byte XOR-key
e. Reads the remaining bytes from the response body and XOR each with the XOR-key
f. Writes the data from the above step to file
g. If the EXE/DLL Indicator is set to ‘1’ then runs
cmd /c start "" regsvr32 -s file
cmd /c start file
(Using the environment of the current stage two process)
As you can see, step 3.g runs the final payload.
In our example, the encrypted URL string is decrypted into:
But the host name no longer has a DNS resolution (hardly surprising).
The Java code in both stages is heavily obfuscated. Four different obfuscation methods are applied (some of them probably via an obfuscation tool):
- Using dummy code: dummy code is inserted, seemingly in a random fashion between “real” operations. The dummy code is mostly calling functions (with no argument, with a string argument, or with an integer argument) that immediately return.
- Function (method) names are randomized
- Most strings are encrypted at the class file and only get decrypted in runtime (the encryption scheme is a cyclic XOR with a hard coded key)
- Using Java reflection to bind to functions in runtime
The obfuscation instances change rapidly and it’s quite common to see two to three different versions in a single day, so, we don’t expect to see “cabOrgies” a few days from now. Some names change more slowly. For example, the package name used to be called “oracle” in early April, and for the last few weeks it’s called “critical.”
JAR file (stage one): size 35114, MD5 69d95811be96cda30f4c91d2450ebb59
cabOrgies.class (stage two): size 16447, MD5 984adfce8cb718f52c7aa7275ac3074c
Trusteer’s CTO Amit Klein said “‘g01pack’ is among the most successful exploit kits available today. It executes a ‘drive-by download’ attack that results in the silent installation of malware. Using the multi-staged attack the ‘g01pack’ exploit kit can effectively distribute advanced malware evading detection by existing security controls.
Trusteer Apex blocks this attack by stopping the exploit process and preventing the payload from compromising the endpoint.”
|< Prev||Next >|