Security Code Review of a Banking Trojan — Cerberus

Security Code Review of a Banking Trojan — Cerberus

Over a year ago, I started hearing about this new Banking Trojan called Cerberus. The author of this malware reportedly used to ridicule security researchers on social media as per article. The malware was sold as a complete package:

  • MySQL seed data with payloads and logos to masquerade several popular banking apps
  • React.js based admin panel with a PHP-based Rest API for a modern C2 experience
Cerberus Admin Panel (Source:

Malware, as one would expect, are usually quite obfuscated making it difficult to analyze and understand the original source code. As a next gen static analysis company, our tools rely on the availability of source code and a buildable environment.

Recently, the source code for Cerberus got leaked on GitHub providing me an opportunity to review them and perform static analysis using the tools we build at ShiftLeft.

This blog summarizes some of my findings from this analysis.

Rudimentary C2 server hardening

The installation script use torsocks to download the server components. However, the actual C2 server PHP code simply runs behind nginx and serves over http. The client android app also communicates back with the server over http. The server panel could also be accessed without any authentication over public IP in default setting.

Lack of secrets management is requesting a root password via the command line during installation.

echo “Enter root password:”
read password

This password is then:

  • Stored in /var/www/config.php as define(‘passwd’ , ‘$password’); in plain-text
  • Create a non-root user with all privileges sharing the same password
mysql -uroot — password=”$password” -e “CREATE USER ‘non-root’@’localhost’ IDENTIFIED BY ‘$password’;”
mysql -uroot — password=”$password” -e “GRANT ALL PRIVILEGES ON *.* TO ‘non-root’@’localhost’;”

Sensitive data leaks

Any software should not leak sensitive data openly in log files. A malware in fact should not reveal its existence and should mask any signs of presence.

Cerberus strangely is full of logging code. A good deal of sensitive information that gets collected or retrieved from server are openly logged.

Some examples:

public String string_80 = “EnCryptResponce: “;
public String string_81 = “CheckBotRESPONCE: “;
public String string_82 = “||youNeedMoreResources||”;

Given the above obfuscated strings, it was possible to identify various sensitive data leaks using ShiftLeft Next Gen.

utl.Log(TAG_LOG, consts.string_80 + response);
response = utl.trafDeCr(response);
utl.Log(TAG_LOG, consts.string_81 + response);

And another.

response = utl.trafDeCr(context, response);
utl.Log(TAG_LOG, “RESPONCE: “ + response);

Over 20 instances of such leaks were discovered by our tool.

Lack of a formal API contract

Even though there is a REST api server most of the communication with the android app in fact use primitive strings for triggering various functionalities over http.

Plain-text strings such as ||youNeedMoreResources|| are used as a signal to download additional payloads.

if (response.contains(“||youNeedMoreResources||”)
&& (!utl.SettingsRead(context, consts.statDownloadModule).equals(consts.str_1))) { //downloading module
utl.downloadModuleDex(this, idbot);

By looking for method calls containing response.contains I could collect all such strings for various operations such as capture keystrokes, take screenshot, disable play protect and so on.

Cerberus Trojan screen overlay (Source:

Weak Encryption Algorithm

Weak algorithms such as RC4 Encryption is used in a number of places.

return base64_encode(bin2hex(RC4Crypt::encrypt_($key, $string)));

RCE vulnerabilities in the panel app

The admin panel uses vulnerable eval functions.

export function try_eval(command) {
  //console.log(“Called: “ + command);
  eval(‘try {‘ + command + ‘} catch (err) { console.log(“Error: “ + err ) } ‘);

There were more instances of RCE since no payload or image data that could get uploaded are ever validated or sanitized.

The developer in fact is aware of this.

console.log(‘%c Do not use this console! ‘, ‘font-size:18px; background: #002b36; color: #a7a89b’);

Vulnerable dependencies (a9)

Many outdated dependencies are used:

Dependency Scan Summary (nodejs)
║ Severity │ Count │ Status    ║
║ UNSPECIFIED │ 0 │ ✅         ║
║ LOW         │ 3 │ ✅         ║
║ MEDIUM      │ 2 │ ✅         ║
║ HIGH        │ 3 │ ❌         ║
║ CRITICAL    │ 0 │ ✅         ║

XSS Vulnerabilities in C2 panel

The panel was a goldmine for XSS vulnerabilities.

  other: <textarea type=”text” name=”other” cols=”40" rows=”5"><?php echo $userdata[‘other’]; ?></textarea>
  end_subscribe: <input type=”text” name=”end_subscribe” value=”<?php echo $userdata[‘end_subscribe’]; ?>”>

Almost all text fields were vulnerable as if the developer wanted things to vulnerable. Even some static blocks were vulnerable to Reflected XSS.

echo “<tr><td>”.
$data[“ID”] . “</td><td>” .
“<textarea readonly>”.$data[“privatekey”] . “</textarea></td><td>” .
$data[“contact”] . “</td><td>” .
“<textarea readonly>” . $data[“serverinfo”] . “</textarea></td><td>” .
$data[“domain”] . “</td><td>” .

Closing thoughts

Performing security code review of a malware is definitely out of the ordinary for me. However, this exercise highlighted a known reality – even malware authors are not perfect developers who think about security while coding. The kind of security flaws seen in this malware indicate that the product was either rushed through or the developer behind Cerberus simply didn’t bother about security or lacks experience.

Security Code Review of a Banking Trojan — Cerberus was originally published in ShiftLeft Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

*** This is a Security Bloggers Network syndicated blog from ShiftLeft Blog - Medium authored by Prabhu Subramanian. Read the original post at: