Trustwave SpiderLabs Uncovers Unique Cybersecurity Risks in Today's Tech Landscape. Learn More

Trustwave SpiderLabs Uncovers Unique Cybersecurity Risks in Today's Tech Landscape. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

New POS Malware Emerges - Punkey

During a recent United States Secret Service investigation, Trustwave encountered a new family of POS malware, that we named Punkey. It appears to have evolved from the NewPOSthings family of malware first discovered by Dennis Schwarz and Dave Loftus at Arbor Networks. While this malware shares some commonalities with that family, it departs from the standard operating procedure of the previous versions rather dramatically. In a blog post, TrendMicro also detailed recently compiled versions of the NewPOSthings family that bear a closer resemblance to NewPOSthings than Punkey. This suggests that multiple actors may be using similar source code, or the malware is being customized as a service for targeted campaigns. Because of the active investigation, I cannot reveal C&C domains used in the samples.

For the uninitiated (or those not old enough to remember), the name is a play on the 80's sitcom Punky Brewster.

Punkey

Versions

Punkey self-identifies its version. Three unique versions have been discovered:

BSL_12835_fb59acb3-1fcf-42aa-ab8c-1976190a7700

The difference between versions 18 and 19 is C&C information, and 18 and 19 are the primary versions described in this blog. The 2015 version slightly alters how the version is reported to the C&C server and will be discussed in the appropriate section below. Unless specifically noted, the description of the malware's operations should be assumed to be the same across all three versions.

Overview

Since a picture is worth a thousand words, and I'm going to use about 2,000 words to describe it--does that make this blog post worth three thousand words?

BSL_11275_b1280e60-3254-4da9-881d-1c1f7f687606

 

Injector

The first stage of Punkey is an injector that contains an obfuscated binary that is decoded to inject into another process. The injector gets a handle to the explorer process, performs the necessary functions to inject a binary into another process and writes the file into its process space. If the "-s" argument was not provided at startup, GetModuleFileName is used to get the path to the current malware, and it is added to the injected process. The injected process is then launched using CreateRemoteThread and the injector exits.

Startup

When the thread executes (stage 2), the process checks to see whether a path was provided to it by the injector (remember that "-s" argument? No? We just talked about it? Come on people, keep up…). If a path is provided, the malware executes its setup:

  1. The injector is copied from its drop location to %USERPROFILE%\Local Settings\Application Data\jusched\jusched.exe

  2. Persistence is established by adding "%USERPROFILE%\Local Settings\Application Data\jusched\jusched.exe –s" to HKCU\Software\Microsoft\Windows\CurrentVersion\Run key

  3. The original injector is deleted

If a path is not provided, then these steps are skipped. The first run of the malware occurs without any arguments which causes the setup function to run as described above. Once the malware is in place, it is ran with the "-s" argument, which prevents duplication of the setup process.

Punkey also has an embedded resource that it writes to disk as %USERPROFILE%\Local Settings\Application Data\jusched\Dllx64.dll. This DLL is actually a 32-bit DLL that exports two functions for installing and uninstalling window hooks for intercepting key presses.

C&C

Now that the environment is setup, Punkey can get down to business. A POST request is made to a C&C server. An embedded list of C&C domains and/or IP addresses are contacted in turn until successful communications are established. In this case it had a domain and an IP in the list.

BSL_12193_de51e0b3-e752-4e11-bce1-9f0b8e3d0997

The POST requests are just information for the server, and no response is checked.

In the 2015-01-12 version this operation is changed slightly. The client sends a GET request to the C&C server first:

BSL_7881_0d21309b-7a77-4cce-a8f9-4d6bd4d831c9

If the response to this is "ok", then a POST request is sent like the earlier versions. This is not to be confused with the 200 OK received from a webserver, but an actual string "ok" returned by the C&C code. An odd choice to be sure.

In one sample a completely broken IP address (with an extra period at the end) was included, which prevented it from ever establishing communications. Another sample had an extra space at the beginning of the domain, breaking the resolution of domain. In the second case the backup IP address worked and the malware could communicate.

Credit Card Scanning

Prior to beginning the scanning process, Punkey sends a POST request to the C&C server.

7667_02d2a35a-4221-4835-8e4c-dc3d173f0784

A thread is spawned to look for card holder data (CHD) data and a process blacklist is used to narrow down the search:

  • svchost.exe
  • iexplore.exe
  • explorer.exe
  • System
  • smss.exe
  • csrss.exe
  • winlogon.exe
  • lsass.exe
  • spoolsv.exe
  • alg.exe
  • wuauclt.exe

It also does not scan its own process space. The other processes are not so lucky and have their process space scanned for CHD. Punkey has its very own CHD-hunting algorithm (meaning it doesn't use regex), and any potential CHD is checked using the Luhn algorithm for validity. If the checks pass, then the data is encrypted and sent to the server. The thread continuously loops through the processes looking for more CHD.

Encryption

The author used AES encryption with an embedded key. Like anyone will tell you, no one should write their own encryption. So, like good developers, they went to the Internet to find some encryption code. I know because I found the same code. Thankfully they didn't bother changing a single digit of the key or the IV. The embedded keys match some example code and sure enough, after downloading and compiling a few changes I was successfully able to decrypt outgoing traffic. I wrote a decryption tool in Ruby that is available at Trustwave's Github page. Both CHD and keylogger data are encrypted with AES and sent to the C&C server with the "unkey=" POST variable. It looks like this:

10718_962d52f1-0f1b-41dc-bc57-d78f739f578b

This traffic is AES encrypted, base64 encoded, then URL encoded. After reversing the process the data sent looks like this (no, it's NOT a valid payment card number):

8456_2a3ed4dc-c8b0-4f25-9b8a-e4037e9e20ee

This is where the naming fun comes into play! The combination of P(OST)unkey and calling the malware author a punk was just too sweet to pass up.

Update

A second thread has spawned that handles downloading arbitrary payloads from the C&C server, as well as, checking for updates to Punkey itself. This gives Punkey the ability to run additional tools on the system such as executing additional reconnaissance tools or performing privilege escalation. This is a rare feature for POS malware.

First, two POST requests are sent to the C&C server.

8654_339df5f6-e9f2-45bc-9537-6495d36e39bf

Note: In the 2015-01-12 version, these POST requests are removed since they have already been sent to the C&C server.

A GET request is sent to the C&C server using the User-Agent: Example

BSL_12558_eebc1b81-1f8b-47b3-af8b-28fa0db4d1f4

There are two expected responses from the C&C server that define what happens next. A "no file" response causes the thread to sleep for 20 minutes (45 minutes in the 2015-01-12 version) and check again.

If the response contains "tempurl:", then either the C&C server has an update available, or an arbitrary payload needs to be executed. The response from the server looks like this:

9764_6b1b6d27-e115-420f-9ffe-7a4a95cc5b3c

The flags are considered set if they have a "1" in them. Temporary payloads are downloaded to %USERPROFILE%\Local Settings\Application Data\jusched\temp.exe and executed.

If the [Delete temp flag] is set, then temp.exe will be deleted on the next loop of this thread (20 or 45 minutes depending on the version).

If the [Terminate self flag] is set, then the uploaddate: field must also be set. The version contained in this field is compared to the hard-coded version stored in the sample. If the server version is newer, then a global variable is set, the new malware is downloaded and executed, and the current malware exits. A POST is sent to the C&C server letting it know the current action.

9668_660919fb-1e86-461e-966a-bfe4934b5af8

Here is a table showing the available commands and actions that occur to make it all a little clearer:

8012_12e79601-7a36-4c3f-abb2-68a5e543d7c9

However, the author made a programming error here. Pointer addition is used to move along the "uploaddate:" string, but they only added 8. My guess is that it used to say "update:" or something along those lines. This results in a comparison that looks like this:

BSL_11479_bb0dfeae-6a92-480b-94ee-1464cbc53443

The "te:" is what is left over after the first eight characters of "uploaddate:" are processed. This comparison will always be true since ASCII 't' will always be greater than any ASCII number. Depending on how the C&C panel is setup, this could cause a repeated update process. Or more likely, the author doesn't update often and didn't notice this bug.

Keylogger

In the section titled "Startup", I told you Punkey dropped the DLLx64.dll in the malware folder. Well, it finally gets around to using it. The DLL is loaded into memory using LoadLibrary and the InstallHooks and UninstallHooks exports are loaded. The thread ID of the current thread is passed to the InstallHooks export. The window message hooks are installed and any WH_KEYSTROKE message will be intercepted and sent back to this thread. The keylogger collects 200 characters, encrypts them with the same AES key it uses to encrypt CHD, and sends them back to the C&C server with a POST request.

BSL_9618_63b28986-7155-4a20-9e34-51409d05a985

If errors occur during the keylogger setup, Punkey can send a couple of error messages to the C&C server with a POST request containing "key=" followed by one of the following errors:

  • "An error occurred while loading dll file. Error Code: %lu"
  • "An error occurred while installing keyboard hook."

64-Bit and Beyond!!

The 2014-10-19 version had both a 32-bit version and a 64-bit version. With the exception of being compiled for different architectures, the two versions are functionally the same. They're so similar in fact that the erroneous space in front of the domain was found in the 64-bit version as well as the 32-bit version. The 64-bit version also contained an actual 64-bit DLL used for keylogging.

BSL_12576_ef760284-2a6e-45fc-a31d-0bd0fbb85f38

Variant Variations

Looking into the NewPOSthings samples discussed by TrendMicro and Arbor Networks and comparing them to Punkey, there is mounting evidence that multiple threads of development are occurring from the same code base. There are enough similarities in strings, tactics, and C&C information to show a relationship between these samples. However, Punkey shows quite a departure from the commonalities shared by all the other variants. The following table describes the differences in the operation of Punkey versus the other variants.

8530_2e347c8a-0dbe-402d-9cbb-807ee06edeb6

The glue tying all these samples together is the use of the keylogger. A very similar DLL is dropped by all of them in the current working directory and uses the same logic to intercept keystrokes. The use of some of the same C&C information as other variants (I didn't slip up. This C&C information hasn't been reported on ;)), the java theme, and a similar CHD-finding algorithm throughout all the variants tie them to a very similar code base. Additionally, the same process blacklist is used across variants as well.

Conclusion

Family definitions and version identification can be a difficult process. Malware authors don't always cooperate and provide distinct enough samples to easily classify exactly what malware was written by whom, and what version it is. Punkey shows more than enough uniqueness to earn a new name, but it is clear that there is heavy development occurring across different versions of a very similar code base. Attribution of the actors is less important than being able to identify the emerging threats and protecting your network data from attack.

In addition to the release of the decryption tool, you can find a YARA signature I've created for detecting all three versions on disk or in memory at Trustwave's Github page.

****UPDATE April 16, 2015****

Here are all of the hashes associated with Punkey that we've discovered:

32-bit Punkey

  • 1dd9e1e661070c0d90faeef75d5a487641a4bfb99c58841827ee5b97e6315eaf
  • 0a33332d200e52875c00ea98417b71621b77a9dc291e6a3bdbd69569aac670cf
  • e0c4696093c71a8bbcd2aef357afca6c7b7fbfe787406f6797636a67ae9b975d

64-bit Punkey

  • 6c7a26ac738c940cdce1e0fcbd9995994ce19332ea444c4ea87de52d2fe9713b

32-bit Dropped DLLs

  • e06f57b984d52153d28bdf9e2629feb16e2dbdea617702fb3397c959ee70ed68
  • 04678de7a93ca1fd7fc7eba1672ec04c9855160b4cace440cfcd3c66d8543026

64-bit Dropped DLL

  • 5ce1e0f1883d13561f9a1cef321db13c4fefddf4fed1d40e7e31f3b04595f527

Latest SpiderLabs Blogs

Why We Should Probably Stop Visually Verifying Checksums

Hello there! Thanks for stopping by. Let me get straight into it and start things off with what a checksum is to be inclusive of all audiences here, from Wikipedia [1]:

Read More

Agent Tesla's New Ride: The Rise of a Novel Loader

Malware loaders, critical for deploying malware, enable threat actors to deliver and execute malicious payloads, facilitating criminal activities like data theft and ransomware. Utilizing advanced...

Read More

Evaluating Your Security Posture: Security Assessment Basics

This is Part 4 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More