- String conversion code
- Initial payload fetcher
- AES decryption code
- Filename generator
- Storing and Execution code
"I'm a... Splo-o-o-it for you..."
The idea behind any exploit is to elevate the execution privileges. This particular RedKit sample attempts to exploit CVE-2012-1723. Vulnerability exists in some HotSpot bytecode verifier versions that allow a condition called "type confusion". There are two types of variables involved here - 'class variable' (static field) and 'instance variable' (non-static field). It is possible to craft a method that takes a static field and returns a non-static field. JIT will get 'confused' about the field type if this method is called a lot of times. Further, combining this method with 'ClassLoader' class will allow for RCE. Michael 'mihi' Schierl put together an article describing this vulnerability in great details.
Core code of the exploit:
Combining the exploit with ClassLoader:
Once 'strkks' object is called it will load "Lotos.class"
The next step is to instantiate the class
And finally 'drop' the restrictions
These are the key steps involved in the exploit. The best indicator for CVE-2012-1723 is the 'Core code' illustrated above.
There is a small piece of code that is called after a successful exploit. It takes a parameter value(string of characters) from the landing page and converts it into URL. The link leads to the initial payload location. The decoding algorithm is relatively simple. Short list of operations performed on the string:
- The order of the characters is reversed (last --> first, 2nd last --> 2nd, etc.)
- 'Padding pattern' is removed from the string
- Every 3rd character is taken and stored in a new string
Part of the string passed from the landing page
By the time of writing this post, the algorithm for decoding the string has changed. More details can be found here.
Fetch it boy!
The fetcher code is almost as the one you'll find in many Java tutorials. These are the steps it follows:
- Creates ByteArrayOutputStream
- Opens InputStream
- Writes stream data into ByteArrayOutputStream
- Closes ByteArrayOutputStream
- Closes InputStream
- Returns ByteArrayOutputStream as a byte array
Fetcher's core code:
To be able to grab the initial payload with tools, like, 'wget', certain conditions have to be met. Specific header, referrer and IP are required to get it. Denis Laskov covered this anti-forensic feature in one of his blog posts.
These zeros and ones look familiar...
The byte array received via decoded URL is passed to AES decryptor. Java code used here for working with crypto cipher is quite 'standard' and can be broken into following steps:
- Assigning 'Secret Key' and 'Initialization Vector' values
- Instantiating an AES cipher
- Creating 'Secret Key' and 'IvParameterSpec'
- Creating the cipher
- Decrypting the byte array
The method that decrypts the initial payload also has some 'preparation' code for storing the file. It detects Java Temp folder location and calls a method to generate a random filename.
"Name me, master!..."
5 to 10 character long filename is generated using random capital letters and numbers.
"Let's do some damage..."
Initial payload delivered by this RedKit sample will be stored in the folder specified in 'java.io.tmpdir' system property. However, before decrypted byte array is stored it's checked for the presence of some pattern. The pattern is serving as a splitter for the data in the array. 2 payloads can be delivered in a single encrypted data stream.
The array is splitted if the pattern is found. Another random filename will be generated for the second payload and both arrays are passed to the method that will save them to the disk and execute.
The very last step
In most of the cases, the initial payload is a 'dropper' that pulls down other malware.
The key points of this particular RedKit sample:
- Initial payload location is stored encoded on the landing page
- Exploits CVE-2012-1723 and CVE-2010-0188
- Anti-forensic measures prevent direct payload download
- Initial payload is delivered as a data-stream and encrypted with AES
- 2 payloads can be delivered in a single data-stream
- Initial payload is stored in the folder specified in 'java.io.tmpdir'
Update May 2013
Fraser Howard put together similar article: