Skip to content

Add Quark malware analysis report for Sova - #957

Merged
haeter525 merged 7 commits into
ev-flow:masterfrom
pulorsok:add-sova-report
Jul 31, 2026
Merged

haeter525 merged 7 commits into
ev-flow:masterfrom
pulorsok:add-sova-report

Conversation

@pulorsok

@pulorsok pulorsok commented Jul 28, 2026 •

Copy link
Copy Markdown
Member

Sova Malware Family Analysis Report

This report analyses the Sova malware family using Quark's rule classification. Sova is an Android banking trojan first surfaced in mid-2021, distributed as trojanised carrier apps (fake BurgerKing, cryptocurrency wallets, delivery apps) that abuse Accessibility services to overlay banking / crypto exchange UIs, harvest credentials, intercept SMS one-time passwords, and — in the v5 branch — encrypt on-device files as ransomware. This run did not generate a new rule for Sova: the family's distinctive bytecode patterns (device-fingerprint queries and outbound-call intents from a single C2-message dispatcher) are already covered by Quark's existing rule set. Check here for the rule set details.

Quark's rule classification flagged 14 of 14 Sova samples as high-risk in this experiment (detection rate 100%). Benign-cohort false-positive rate was not measured here. See tested APKs below.

Identified Well-Known Threats

This section uses MITRE ATT&CK Mobile as its reference taxonomy, anchored to the S1062 S.O.V.A. software entry. Of the 19 techniques documented for the family, Quark's static bytecode analysis surfaces the 3 listed below; see the coverage-gap notes at the end of this section for why the other 16 are not demonstrated here.

MITRE Technique Real-world manifestation in Sova
T1426 System Information Discovery Reading device phone number and IMEI inside the C2 ping-response handler for victim profiling
T1582 SMS Control Dispatching SMS-send operations from a helper (ContexStartExtensionsKt.sendSMS) invoked by the C2 ping-response handler with an operator-supplied phone number and body
T1616 Call Control Constructing an Intent.ACTION_CALL intent with an operator-supplied phone number and invoking startActivity from the same C2 ping-response handler

All cluster representatives below were extracted from sample 724a56172f40177da76242ee169ac336b63d5df85889368d1531f593b658606b.apk (a fake BurgerKing carrier — package com.tapston.burgerking), chosen as the representative sample whose detected behaviors most fully cover the documented profile of Sova. The other 13 family samples were used to compute the detection-rate figure above.

Each section below corresponds to one technique from the table above. Within each section we first quote the MITRE definition, then walk through the call sequence and list the underlying rules.

1. T1426 System Information Discovery

T1426 System Information Discovery — attack.mitre.org

MITRE definition (T1426): Adversaries may attempt to get detailed information about a device's operating system and hardware, including versions, patches, and architecture.

T1426 System Information Discovery

Lcom/tapston/burgerking/service/worker/PingTasks;onPingReceived (an attacker-authored C2 ping-response handler inside the fake BurgerKing carrier app) is invoked whenever the operator's ping message arrives on the dispatcher; within this method the malware calls TelephonyManager.getLine1Number and getDeviceId to read the victim's phone number and IMEI, then ships them back over the C2 socket as part of the ping ACK payload.

Behaviors detected by Quark:

2. T1582 SMS Control

T1582 SMS Control — attack.mitre.org

MITRE definition (T1582): Adversaries may delete, alter, or send SMS messages without user authorization. This could be used to hide C2 SMS messages, spread malware via SMS, or various external effects.

T1582 SMS Control

The same Lcom/tapston/burgerking/service/worker/PingTasks;onPingReceived handler routes a subset of operator commands to an attacker-authored Kotlin extension helper Lcom/tapston/burgerking/extensions/context/ContexStartExtensionsKt;sendSMS, which wraps SmsManager.sendTextMessage to inject outbound SMS on behalf of the operator. The dispatcher also references a content-URI delete primitive on the SMS/call-log providers to remove traces after sending.

Behaviors detected by Quark:

3. T1616 Call Control

T1616 Call Control — attack.mitre.org

MITRE definition (T1616): Adversaries may make, forward, or block phone calls without user authorization. This could be used for adversary goals such as audio surveillance, blocking or forwarding calls from the device owner, or C2 communication.

T1616 Call Control

The same Lcom/tapston/burgerking/service/worker/PingTasks;onPingReceived handler also handles the "place-call" operator command: it constructs an Intent with the ACTION_CALL action, packs an operator-supplied phone number into the intent's URI via setData, and invokes startActivity — placing an outbound phone call without user consent.

Behaviors detected by Quark:

Coverage-gap notes

The 16 MITRE techniques documented for Sova that this report does NOT demonstrate, grouped by the reason Quark could not confirm them on these samples:

The two APIs share a caller, but it sits deeper than Quark searches (7) — While the techniques below are triggered by Sova's service dispatcher, the actual APIs are hidden in helper functions more than 3 layers deep. For performance reasons, Quark does not search beyond 3 layers by default. As a result, these techniques are currently not detected by Quark, but we are actively working on addressing this limitation.

Technique First API Second API Nearest shared caller
T1516 Input Injection AccessibilityNodeInfo.findAccessibilityNodeInfosByText (6 Sova call sites) AccessibilityNodeInfo.performAction (12 Sova call sites) AppAccessibilityService.onAccessibilityEvent
T1417.001 Keylogging AccessibilityEvent.getEventType AccessibilityEvent.getText AppAccessibilityService.onAccessibilityEvent
T1417.002 GUI Input Capture WindowManager.addView (TYPE_APPLICATION_OVERLAY) WebView.loadUrl activity / service lifecycle callbacks
T1517 Access Notifications StatusBarNotification.getPackageName StatusBarNotification.getNotification NotificationListenerService.onNotificationPosted
T1628.001 Suppress Application Icon Context.getPackageManager PackageManager.setComponentEnabledSetting reached only inside bundled libraries (AndroidX WorkManager, Xiaomi push, Taobao SDK)
T1629.001 Prevent Application Removal DevicePolicyManager.isAdminActive Intent.putExtra (device-admin request) device-admin setup flow
T1630.001 Uninstall Malicious Application Intent.<init> (ACTION_UNINSTALL_PACKAGE) Context.startActivity n/a — the pair is too generic to rule on, since every launcher and settings screen uses it

Runtime / network-only behavior (3) — bytecode analysis cannot capture these because the malicious intent lives in runtime C2 messages, not in distinct API pairs.

  • T1464 Network Denial of Service — DDoS traffic is issued via generic Socket.connect / HttpURLConnection, indistinguishable in bytecode from a legitimate app.
  • T1437.001 Web Protocols — C2 uses OkHttp / HttpURLConnection with runtime-supplied URLs.
  • T1638 Adversary-in-the-Middle — requires runtime network observation.

Sample cohort does not exercise the behavior (3)

  • T1471 Data Encrypted for Impact — Sova v5's ransomware module encrypts device files with a runtime-delivered AES key. The samples in this cohort are pre-v5 banking builds and do not carry the encryption module.
  • T1641.001 Transmitted Data Manipulation (clipboard) — ThreatFabric documents clipboard hijacking (crypto-address swap) in Sova v5+; the ClipboardManager references in this cohort all fire inside bundled utility libraries (WhatsApp clones, React Native / Flutter clipboard modules) rather than in attacker code, so the Sova-authored clipboard-swap logic is not present in these samples.
  • T1406.002 Software Packing — a distribution characteristic (how the APK is shipped), not a bytecode behavior visible after unpacking.

Behavior confirmed by Quark but attributed to bundled library (2)

  • T1418 Software Discovery — PackageManager.getInstalledApplications and getPackageInfo fire in Sova's samples but always inside the Getui push SDK (Lcom/igexin/push/…), which uses the same API to build push-targeting maps. Sova likely reuses the SDK's cache rather than calling the primitive itself.
  • T1513 Screen Capture — canvas / bitmap-compress pair fires only inside Lcom/horcrux/svg/SvgView (react-native-svg rendering), not attacker code. Sova's actual screen capture uses AccessibilityService.takeScreenshot, a single-API surface with the same limitation as the group above.

Runtime impersonation (1)

  • T1655.001 Match Legitimate Name or Location — impersonating a real app by icon / name / package similarity (e.g. Sova samples disguising as BurgerKing) requires cross-app comparison at install time; out of scope for static bytecode analysis of a single APK.

List of Tested APKs

The table below lists the APKs we tested.

index sha256
1 15EAE9134DAC9268CBF005C23299C88DD5C5176A240201DA751691A543375360
2 1981394E719BDFD9E29D57386D8CA05CEECC2DDD31F658255C068D6963DF17C1
3 2124777F710199D4051C9D67185DC4DBB55252D65B57642222EEE444C5C06D88
4 376D13AFFCBFC5D5358D39ABA16B814F711F2E81632059A4BCE5AF060E038EA4
5 3EB7EFA71648AE819F1BFF89399717805129487081E8261DD65BF596F2467054
6 6F7E57ED7239905FAFC3947160B5FC89AD615772D2A694299999D2FE080453F4
7 724A56172F40177DA76242EE169AC336B63D5DF85889368D1531F593B658606B
8 795B279F312A773F7F556A978387F1B682F93470DB4C1B5F9CD6CA2CAB1399B6
9 7C805F51EE3B2994E742D73954E51D7C2C24C76455B0B9A1B44D61CB4E280502
10 B01B74AAF249D0740F541C081C0C0DE4BF455B4B68F2634FAB6CF8AAFCD95D52
11 BBAF483C2B6F67F22EB6E1FA00F200E9C1E201B0110070ACAEFD416CF846B1AA
12 EC5B083C017570F846F6925B7C79D9E5886525A9B7BA7E514DABAD0325C0AF5E
13 EFB92FB17348EB10BA3A93AB004422C30BCF8AE72F302872E9EF3263C47133A7
14 F3FC80A8793E60A901DA44B9AB315931699E64A4F3EDDB8ABA839FE860DE46DC

Adds a report-only entry for Sova (S1062), an Android banking trojan
first surfaced in mid-2021 and now known to have rebranded to Nexus
in early 2023.  Quark flagged 14 of 14 Sova samples as high-risk
(detection rate 100%).

Three MITRE ATT&CK Mobile techniques were confirmed with attacker-
namespace evidence, all reached via the same C2 ping-response handler
Lcom/tapston/burgerking/service/worker/PingTasks;onPingReceived
inside a fake BurgerKing carrier sample:

- T1426 System Information Discovery — reading phone number + IMEI
- T1582 SMS Control — dispatching outbound SMS through
  ContexStartExtensionsKt.sendSMS
- T1616 Call Control — placing outbound calls via ACTION_CALL intent

The 16 remaining MITRE techniques documented for S1062 are classified
in coverage-gap notes: 7 same-parent-method structural limits (each
tested with a candidate two-API rule), 3 runtime / network-only
behaviours, 3 sample-cohort gaps (v5 ransomware / clipboard hijack /
packing), 2 library-attributed patterns, 1 install-time impersonation.

No new Quark rule is generated in this run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.29%. Comparing base (5d619ce) to head (709cbdd).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #957   +/-   ##
=======================================
  Coverage   80.29%   80.29%           
=======================================
  Files          82       82           
  Lines        7190     7192    +2     
=======================================
+ Hits         5773     5775    +2     
  Misses       1417     1417           
Flag Coverage Δ
unittests 80.29% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@haeter525
haeter525 self-requested a review July 28, 2026 17:23
@haeter525 haeter525 added the documentation Improvements or additions to documentation label Jul 28, 2026
pulorsok and others added 2 commits July 29, 2026 20:17
Three review-driven fixes:

1. The T1582 SMS Control image URL was a hand-typed placeholder
   returning 404.  Re-upload the local behavior-map PNG to imgbb and
   point the report at the new URL.

2. Use "Sova" as the family name in the narrative for consistency;
   keep "S.O.V.A." only inside the official MITRE link text where it
   is the S1062 canonical name.

3. Rewrite the coverage-gap group heading from "Same-parent-method
   structural limit (Quark's Stage-3 requirement)" into plain
   language.  The prior wording could read as if the APIs were not
   called at all, and used a Quark internal-stage term readers do
   not necessarily know.  New wording explains that the two APIs
   ARE both called, but from different helper methods, and states
   in one sentence why Quark's rule matching insists on one shared
   parent function (register-passing between the two calls has to
   be traceable within a single method).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prior wording claimed Quark only matches rules when both APIs are
called from a single method.  That is inaccurate: Quark's
method_recursive_search (quark/core/quark.py, MAX_SEARCH_LAYER = 3)
walks up the call graph looking for a mutual parent that transitively
reaches both APIs.  The reason Sova's accessibility / notification
techniques do not match is that Sova's dispatcher-plus-tasks pattern
puts the two APIs in separate Task.executeTaskOn methods whose shared
parent (AccessibilityService.onAccessibilityEvent) sits more than 3
layers above the API sites, so Quark's bounded traversal hits its
depth limit first.

Rewrite the group heading to name the actual mechanism, cite the
MAX_SEARCH_LAYER constant so readers can locate it, and back one
technique (T1516 Input Injection) with the empirically observed
caller-site list from sample 724a5617... .

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pulorsok and others added 4 commits July 31, 2026 20:54
The paragraph explaining Quark's 3-layer traversal limit ran eight
lines, and the seven bullets under it each restated the same point in
different words. Cut the paragraph to three lines and replace the
bullets with a table listing only what differs per technique: the two
APIs and their nearest shared caller.

Also correct the T1516 call-site counts. The earlier text said 5 and
14; re-running the caller lookup on sample 724a5617 gives 6 and 12
Sova-authored call sites, since one findAccessibilityNodeInfosByText
site and two performAction sites are in AndroidX support code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The sentence describing why the call-depth limit blocks these rules
was hard to follow. State it directly: each API sits in a different
Task helper, and the only method calling both is the dispatcher at
the top, more than 3 layers up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the paragraph with the maintainer's wording. It states the
limitation from the reader's point of view: the dispatcher triggers
the techniques, the APIs sit in helpers more than 3 layers down,
Quark stops at 3 layers for performance, and the limitation is being
worked on.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@haeter525 haeter525 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pulorsok.

@haeter525
haeter525 merged commit 5facb9d into ev-flow:master Jul 31, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants