SharkBot is an Android banking trojan that targets credentials and access to crypto wallets. It’s capable of ATS (Automatic Transfer System) attacks, overlay attacks, keylogging, and SMS/MMS interception. The sample here was obfuscated with Allatori.

SHA256: 9701bef2231ecd20d52f8fd2defa4374bffc35a721e4be4519bda8f5f353e27a

Tools: dex2jar, CFR Decompiler, Java Deobfuscator, CyberChef, JoeSandbox, Visual Studio Code


Initial Triage

Detonated the sample in JoeSandbox first. The malware immediately drops itself to establish persistence:

/data/app/com.agoxgljzqbdi.gwuaspmli-8SXhUqtOS-AbO5jLsdYFlw==/base.apk

JoeSandbox overview showing MALICIOUS / SharkBot classification, C&C IP 185.219.221.99, hardcoded C&C URLs, and dropped files

Sandbox classification confirms this is a trojan / spyware — not destructive, focused on monitoring and credential theft.

Threat classification radar showing malicious rating across Trojan, Banker, Spyware, and Evader categories

Network & URLs

Network analysis from the sandbox IDS shows the malware repeatedly hammering the same IP — 185.219.221.99 is the C&C server.

Snort IDS alerts showing repeated CTRO SharkBot Android C2 Check-In connections to 185.219.221.99

Permissions & Receivers

Permissions requested by the APK reveal capabilities before even looking at the code:

Full list of Android permissions requested by the APK including SMS, MMS, overlay, accessibility, and network state

The registered receivers show how the malware survives reboots and intercepts messages:

Android receivers showing bootReceiver (BOOT_COMPLETED, QUICKBOOT_POWERON, WiFi state), receiverMMS, and receiverSMS

  • bootReceiver — restarts the malware on boot and screen-on events (priority 99999)
  • receiverMMS / receiverSMS — intercepts incoming SMS and MMS

APK Unpacking

Unpacked with dex2jar:

$ d2j-dex2jar task4.apk
dex2jar task4.apk -> ./task4-dex2jar.jar

dex2jar extracting task4.apk in Kali terminal alongside the resulting jar file in the file manager

This produces a .jar with all the compiled Java classes. The jar structure contains standard Android libraries alongside the malware’s own com.agoxgljzqbdi.gwuaspmli package:

Jar archive structure showing android, androidx, com, kotlin, okhttp3, okio, and org top-level directories


Deobfuscation

The Java Deobfuscator detect config:

nano editor showing detect.yml with input: task4.jar and detect: true

Running detection identified Allatori string encryption:

$ java -jar deobfuscator.jar --config detect.yml
[main] RuleStringDecryptor: Allatori's string decryption is very simple,
       accepting an encrypted string and outputting a decrypted string
[main] Found possible string decryption class com/agoxgljzqbdi/gwuaspmli/x
[main] Recommend transformers:
[main]   com.javadeobfuscator.deobfuscator.transformers.allatori.StringEncryptionTransformer

Java Deobfuscator running in Kali terminal alongside file manager showing the deobfuscated jar artifacts

The transform config to apply the Allatori transformer:

nano editor showing config.yml with StringEncryptionTransformer configured as the transformer

Running this produces interpretable Java. Some sections didn’t deobfuscate cleanly, but nothing critical was blocked.


Hardcoded RSA Public Key

Searching for RSA across the deobfuscated code:

grep -Hirn RSA results showing matches in x.java:130 and x.java:131 for KeyFactory and Cipher RSA operations

$ grep -Hirn RSA
x.java:130: object = KeyFactory.getInstance("RSA").generatePublic((KeySpec)object2);
x.java:131: object2 = Cipher.getInstance("RSA/ECB/PKCS1Padding");

x.java loads a hardcoded Base64 blob and uses it as an RSA public key to encrypt network traffic (via RC4 underneath). The key:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2R7nRj0JMouviqMisFYt
0F2QnScoofoR7svCcjrQcTUe7tKKweDnSetdz1A+PLNtk7wKJk+SE3tcVB7KQS/W
rdsEaE9CBVJ5YmDpqGaLK9qZhAprWuKdnFU8jZ8KjNh8fXyt8UlcO9ABgiGbuyuz
XgyQVbzFfOfEqccSNlIBY3s+LtKkwb2k5GI938X/4SCX3v0r2CKlVU5ZLYYuOUzD
LNl6KSToZIx5VSAB3VYp1xYurRLRPb2ncwmunb9sJUTnlwypmBCKcwTxhsFVAEvp
z75opuMgv8ba9Hs0Q21PChxu98jNPsgIwUn3xmsMUl0rNgBC3MaPs8nSgcT4oUXa
VwIDAQAB

The relevant code section from x.java:

public String L(String string2) {
    try {
        Object object = Base64.decode(
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2R7nRj0JMouviqMisFYt..."
            .getBytes(StandardCharsets.UTF_8), 2);
        Object object2 = new X509EncodedKeySpec((byte[])object);
        object = KeyFactory.getInstance("RSA").generatePublic((KeySpec)object2);
        object2 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        ((Cipher)object2).init(1, (Key)object);
        string2 = Base64.encodeToString(
            ((Cipher)object2).doFinal(string2.getBytes(StandardCharsets.UTF_8)), 2);
        return string2;
    } catch (Exception exception) {
        return "";
    }
}

Source: SharkBot: A New Generation Android Banking Trojan — NCC Group


C&C and Domain Generation Algorithm (DGA)

Two hardcoded C&C domains show up in w.java:

$ grep -Hirn mja
w.java:62: public String e = "http://n3bvakjjouxir0zkzmd.xyz/,http://mjayoxbvakjjouxir0z.xyz/";

The malware also generates additional domains dynamically. The DGA generates one domain per TLD across .top, .xyz, .cc, .info, .com, .ru, and .net — visible in the sandbox URL list:

Sandbox URL list showing both hardcoded C&C domains and DGA-generated domains across multiple TLDs

The DGA code in w.java:

private /* synthetic */ String B() {
    StringBuilder stringBuilder = new StringBuilder();
    Calendar calendar = Calendar.getInstance();
    String[] stringArray = ".top,.xyz,.cc,.info,.com,.ru,.info,.net".split(",");
    int n = stringArray.length;
    int n2 = 0;
    while (n2 < n) {
        String string2 = stringArray[n2];
        try {
            stringBuilder.append(",http://");
            String seed = String.valueOf(calendar.get(3) + calendar.get(1))
                               + "pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf";
            stringBuilder.append(
                Base64.encodeToString(seed.getBytes(), 2).substring(0, 19)
            ).append(string2);
        } catch (Exception exception) {}
        ++n2;
    }
    return stringBuilder.toString().toLowerCase();
}

The seed is built from:

  • calendar.get(3) → ISO week number
  • calendar.get(1) → year
  • Hardcoded salt: pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf

The result is Base64-encoded and truncated to 19 characters, then combined with each TLD. This generates 8 unique domains per week — if the hardcoded servers get blocked, the DGA keeps the malware connected.


Summary — Key Questions Q&A

Q1 — Which obfuscator and which obfuscation techniques are used?

A — Allatori Java Obfuscator, primarily string encryption. Detected and partially reversed with com.javadeobfuscator.deobfuscator.transformers.allatori.StringEncryptionTransformer.

Q2 — Reverse the obfuscation (at least partially). Describe your approach.

A — Ran Java Deobfuscator in detect mode to identify the obfuscator, then applied the matching Allatori transformer. Deobfuscation was incomplete in some areas but sufficient for the analysis.

Q3 — Which functionality does the malware support?

A — SharkBot’s capability set:

  • C&C — remote control via 185.219.221.99
  • SMS/MMS interception — read, write, send, receive
  • Overlay attacks — fake UI over banking apps to steal credentials
  • Keylogging
  • Permission abuse — harvests device info and status
  • Anti-emulation — detects and resists sandbox environments

It’s a banking trojan targeting credentials and crypto wallets, specifically capable of ATS (Automatic Transfer System) attacks.

Q4 — What are the C&C servers?

A —

  • Hardcoded: http://n3bvakjjouxir0zkzmd.xyz/, http://mjayoxbvakjjouxir0z.xyz/
  • IP: 185.219.221.99:80/tcp (Sweden)
  • DGA-generated: 8 domains per week across .top, .xyz, .cc, .info, .com, .ru, .net
Q5 — How does the domain generation algorithm work? Keep it high level.

A — Seeds a string from the current ISO week number + year, appended to a hardcoded salt. The result is Base64-encoded, truncated to 19 characters, and combined with each supported TLD. Rotates weekly, giving the malware resilient C&C connectivity even after domain takedowns.

Q6 — What’s the RSA public key?
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2R7nRj0JMouviqMisFYt0F2QnScoofoR7svCcjrQcTUe7tKKweDnSetdz1A+PLNtk7wKJk+SE3tcVB7KQS/WrdsEaE9CBVJ5YmDpqGaLK9qZhAprWuKdnFU8jZ8KjNh8fXyt8UlcO9ABgiGbuyuzXgyQVbzFfOfEqccSNlIBY3s+LtKkwb2k5GI938X/4SCX3v0r2CKlVU5ZLYYuOUzDLNl6KSToZIx5VSAB3VYp1xYurRLRPb2ncwmunb9sJUTnlwypmBCKcwTxhsFVAEvpz75opuMgv8ba9Hs0Q21PChxu98jNPsgIwUn3xmsMUl0rNgBC3MaPs8nSgcT4oUXaVwIDAQAB

Used to encrypt C&C traffic with RSA/ECB/PKCS1Padding, with RC4 underneath. Hardcoded in x.java.