Detecting CronRAT Crontab Malware on Linux

Malware Linux Security Linux Forensics

Date
November 28, 2021
Author
The Sandfly Security Team

Security researchers recently discovered a new kind of Linux malware that was hiding its payload as part of an illegal crontab entry on Linux. The malware is being used to insert card skimming malware into Magecart enabled e-commerce sites. Card skimming (sometimes called Formjacking) allows bypassing browser based encryption and security by enabling credit card and customer data theft directly from the server.

Novel Crontab Payload Storage and Hiding

The malware was novel in that it was using a bogus date of February 31st inside of crontab to hide payload data as base64 encoded blobs. This allowed an obfuscated shell script to run and connect to a command and control server using a custom encrypted protocol. The cron system was not meant to run the entries so the invalid date didn't matter. The cron entries were just being used to hold the malware data from observation by system administrators. The invalid date therefore was not meant to be parsed by the cron system but was just used for payload storage.

Detecting CronRAT with Agentless Sandfly

Finding CronRAT is pretty straightforward for Sandfly as we have a built-in crontab forensic analysis engine. The built-in engine is already used to look at Linux cron for a variety of threats and is easily modified with new signatures to find CronRAT. You can quickly make custom detections and check your systems immediately. Let's go over two approaches to do this.

Protect Your Hosts Now, Get Sandfly Today

Get 500 Hosts Free

Detection Approach One: Search for Bogus February Day/Date

The first approach to finding CronRAT is to search your systems for a bogus cron entry using the date "February 31st", which is invalid. Sandfly has built in templates to allow searching for cron days, months, hours, minutes, days of week and even what command is being run. We'll use the built-in template called process_persistence_cron_day_match. This template does pretty much what it's called: You put in the day(s) you want it to match and if Sandfly sees them it will generate an alert.

We'll first find the template under the master sandfly list:

Sandfly Template to Hunt for Crontab Malware

Now click the clone button in the upper right.

Cloning will open the custom sandfly into the editor mode. We're going to edit some areas below. First, we'll change the name to something meaningful. We'll call it process_persistence_cron_cronrat in the "name" area. Also, we'll update the description to something useful.

Editing Custom Sandfly to Hunt for CronRAT

Now we'll update the search criteria. We'll want to go under the "cron" area and update the "day" REGEX to search for our suspicious days. Instead of looking just for the 31 entry, we'll use a wider REGEX to search for any date over 29 for February as they would all be suspicious. We'll also add in a "month" section and pin it to only look for "2" for February.

For "explanation" you can tweak the text keeping in the template fields. These fields are filled in by Sandfly with specific forensic data for security teams to quickly see what the problem is in plain English like below:

"explanation": "The cron file '{cron.path}' is running the command ('{cron.command}') as '{cron.username}' with an illegal day for February matching day value '{cron.day}'. This is associated with the cronRAT malware and this system should be investigated for compromise."

Under the "tags" and "type" field you'll need to convert them from template to "process" type. Also change the severity from default of 0 to 3 (highest severity). This will ensure the UI flags these alerts as critical.

The completed edits are below. Sandfly customers can simply copy this JSON into the custom editor and save it:

{
  "active": true,
  "custom": true,
  "description": "Searches for suspicious date associated with CronRAT malware.",
  "format": "3.0",
  "max_cpu_load": 1,
  "max_disk_load": 1,
  "max_timeout": 360,
  "name": "process_persistence_cron_cronrat",
  "options": {
    "cron": {
      "day": [
        "^\\b([3-9][0-9])\\b"
      ],
      "month": [
        "^2$"
      ],
      "search_paths": [
        "/var/spool/cron",
        "/var/spool/cron/crontabs",
        "/var/spool/cron/tabs",
        "/etc/cron.d"
      ],
      "search_paths_individual": [
        "/etc/crontab"
      ],
      "search_paths_patterns": [
        ".*"
      ],
      "search_paths_patterns_ignore": []
    },
    "engines": [
      "sandfly_engine_cron"
    ],
    "explanation": "The cron file '{cron.path}' is running the command ('{cron.command}') as '{cron.username}' with an illegal day for February matching day value '{cron.day}'. This is associated with the cronRAT malware and this system should be investigated for compromise.",
    "response": {}
  },
  "os_compat": {
    "linux": []
  },
  "severity": 0,
  "tags": [
    "attack.id.T1053.003",
    "attack.tactic.execution",
    "attack.tactic.persistence",
    "process"
  ],
  "type": "process"
}

When you're done, simply hit Save in the upper right.

Better Detection: Search for Excessively Long Cron Commands

While an out of spec date is an OK way to detect this immediate problem, the real issue is that payload data could show up again under different formats in cron. To cast a wider net, we'll use a better approach just in case variants of this malware have changed bogus dates.

The better approach we'll use is to check the cron command and alert if we see anything over 100 characters. One hundred characters is pretty long for a Linux cron command and would warrant taking a look. But, if you are concerned about false alarms you can move it to 200 or more characters. Any command over 200 characters would be extremely suspicious even under optimistic scenarios for Linux.

Just like before, Sandfly already has a template for this task. Instead of using the template to look for days in cron, we'll use the one to match command lines called:

process_persistence_cron_command_match

This check allows us to match for any command using REGEX which is pretty powerful.

Searching Linux for Malicious Crontab Command

Again, we'll clone this check . Then, we'll modify it so our command field uses a REGEX pattern to look for any character pattern more than 100 length long (^.{100,}). You can simply paste the JSON below and save:

{
  "active": true,
  "custom": true,
  "description": "Searches for cron command entries that are an excessive length.",
  "format": "3.0",
  "max_cpu_load": 1,
  "max_disk_load": 1,
  "max_timeout": 360,
  "name": "process_persistence_cron_command_excessive_length_custom",
  "options": {
    "cron": {
      "command": [
        "^.{100,}"
      ],
      "search_paths": [
        "/var/spool/cron",
        "/var/spool/cron/crontabs",
        "/var/spool/cron/tabs",
        "/etc/cron.d"
      ],
      "search_paths_individual": [
        "/etc/crontab"
      ],
      "search_paths_patterns": [
        ".*"
      ],
      "search_paths_patterns_ignore": []
    },
    "engines": [
      "sandfly_engine_cron"
    ],
    "explanation": "The cronfile '{cron.path}' contains a command ('{cron.command}') that has an excessive length. The command should be investigated to be sure it is legitimate and not malicious.",
    "response": {}
  },
  "os_compat": {
    "linux": []
  },
  "severity": 3,
  "tags": [
    "attack.id.T1053.003",
    "attack.tactic.execution",
    "attack.tactic.persistence",
    "process"
  ],
  "type": "process"
}

Verify Sandflies are Active

After you save both of these, go to the master sandfly list and make sure you see they are active. You can use the preset filter to show only custom types and make sure they are not grayed out. If they are, simply click the active column to turn them on:

Check Custom Sandflies Are Active

Simulate Attack

If you want to simulate what the attack would look like you can edit the crontab for the root user on a test system and put in the following entries:

crontab -e
<editor starts>
<insert following test commands>

52 23 31 2 3 base_64_encoded_payload_test_string
52 23 31 2 3 really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command

<save and exit>

The above tests both conditions we have above. The first entry should only activate the bogus date check. The second will activate both the bogus date and the excessive command length.

After you make the above entries you can run the crontab list command (crontab -l) to see your handiwork:

root@sandflysecurity:/root# crontab -l
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 

...

# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command

52 23 31 2 3 base_64_encoded_payload_test_string
52 23 31 2 3 really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command_really_long_command
...
root@sandflysecurity:/root# 

Scan with Custom Sandflies

Now you can scan your hosts with the new sandfly checks and get results back in seconds. Go to your scan menu and select the hosts you want to check. Then click Next and use the preset selector to choose Custom Sandflies to see your new custom checks. Select the two we just put in like below and initiate your scan:

Scan Systems Agentlessly for CronRAT Linux Malware

Get Results

In a few seconds you'll begin to get results back. Systems without problems will show as Passed like below. This lets you know that an audit took place and the system looked clean.

CronRAT Malware Not Found

If you have a problem though your dashboard will show like the following with Alert results:

CronRAT Malware Found

Individual results will be shown below. Here we see two alerts from our custom checks. The date specific alert and one with excessive length.

CronRAT Found Alert Listing

In our simulated attack above, you'll see results like below complete with raw forensic data:

CronRAT Bogus Date

CronRAT Bogus Date Raw Forensic Data

CronRAT Excessive Crontab Command Length Found

CronRAT Excessive Crontab Command Length Found Raw Forensic Data

Any systems with alerts you can quickly view and triage forensic data to take further action.

Conclusion

CronRAT used crontab in a new way to hide payload data from typical observation. However the attack is easily found once you know where to look. Sandfly customers have access to the custom feature to quickly check their hosts for signs of CronRAT malware today.

You can contact us for a free trial of our full featured product to get the same capability, or try our Free version to search for other signs of compromise on your Linux systems today.

Let Sandfly keep your Linux systems secure.

Learn More