How MobileAudit Checks for Malware Domains Using MalwareDB and Maltrail Databases

MobileAudit detects malicious URLs during APK analysis by cross-referencing extracted domains against a locally stored Malware table populated from MalwareDB and Maltrail feeds.

MobileAudit is an open-source Android security analysis platform maintained in the mpast/mobileaudit repository. When scanning APK files, the tool automatically extracts URLs embedded in code and checks them against known malicious domain databases. This malware domain verification operates entirely offline after initial data import, ensuring fast analysis without external API latency.

How the Malware Domain Detection Works

The malware domain check follows a four-stage pipeline: feature flag validation, URL pattern extraction, substring database lookup, and finding correlation. This architecture enables MobileAudit to flag suspicious domains discovered during static analysis without requiring internet connectivity during the scan itself.

The process relies on Django ORM queries against a pre-populated Malware model, using case-insensitive substring matching to identify domains listed in the Malware Domain List and Maltrail threat feeds.

Step-by-Step Domain Verification Process

Enabling the Feature Flag

Malware domain checking is controlled by the MALWARE_ENABLED setting in app/config/settings.py. By default, this feature is active:


# app/config/settings.py

MALWARE_ENABLED = env('MALWARE_ENABLED', True)   # toggle via env var

When this setting is False, MobileAudit skips all malware database queries during analysis, improving performance for scans where domain reputation checks are unnecessary.

URL Extraction from APKs

During static analysis in app/analysis.py, MobileAudit identifies URL patterns using pattern ID 9. When the scanner encounters a match, it parses the string using Python's urllib.parse module to isolate the domain:


# app/analysis.py – find_patterns()

if p.id == 9:                     # URL pattern

    type = 'URL'
    url = urllib.parse.urlsplit(match_str)

The urlsplit operation returns a SplitResult object where url.netloc contains the extracted domain (e.g., example.com).

Database Lookup Logic

If malware checking is enabled, MobileAudit queries the local Malware table using a case-insensitive substring search against the domain:


# app/analysis.py (excerpt)

if settings.MALWARE_ENABLED:
    # look for a Malware record whose URL field contains the domain part of the match

    m = Malware.objects.get(url__icontains=url.netloc)

The url__icontains lookup performs a case-insensitive SQL LIKE query, matching if the domain appears anywhere within the stored malware URL entries. This catches both exact matches and subdomains listed in the threat feeds.

Storing Results with Domain Associations

After lookup, MobileAudit creates a Domain object linked to the current scan. If malware was detected, the code attaches the matching Malware record via foreign key:


# app/analysis.py – after creating a Finding

if type == 'URL':
    if m:   # malicious domain was found

        u = Domain(scan=scan, domain=url.netloc,
                   finding=finding, malware=m)
    else:
        u = Domain(scan=scan, domain=url.netloc,
                   finding=finding)
    u.save()

The Domain model includes a malware foreign key that references the specific threat intelligence entry, allowing the UI to display detailed context about why the domain was flagged.

Data Sources and Feed Configuration

The Malware table is populated from two public threat intelligence feeds defined in app/config/settings.py:

  • MalwareDB: https://www.malwaredomainlist.com/mdlcsv.php (CSV format containing known malicious domains)
  • Maltrail: https://raw.githubusercontent.com/stamparm/aux/master/maltrail-malware-domains.txt (plain-text list of suspicious domains)

A separate import routine (external to the analysis flow) downloads these files periodically and creates Malware objects storing the URL, description, IP address, and discovery date. Once imported, the analysis engine performs fast local lookups without hitting remote services for every APK scan.

Code Implementation Details

Malware Model Structure

The Malware model in app/models.py stores entries from both feeds with the following schema:


# app/models.py

class Malware(models.Model):
    date = models.CharField(max_length=255, null=True)
    url = models.TextField(blank=True, null=True)
    ip = models.TextField(blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    # … other metadata fields …

Malware Database Browser

The /malware/ endpoint in app/views.py renders all stored malware entries, allowing users to browse the threat intelligence database that powers the domain checks:


# app/views.py

def malware(request):
    malwares = Malware.objects.all()
    return render(request, 'malware.html', {'malwares': malwares})

Summary

  • Feature toggle: Malware domain checking is controlled by settings.MALWARE_ENABLED and defaults to True.
  • Pattern matching: URLs are identified using pattern ID 9 and parsed with urllib.parse.urlsplit() to extract domains.
  • Database query: Domains are checked against the Malware table using url__icontains for case-insensitive substring matching.
  • Data sources: The local database is populated from MalwareDB and Maltrail URLs defined in app/config/settings.py.
  • Result storage: Detected domains are saved as Domain objects with optional foreign key links to matching Malware records.
  • Offline operation: After initial import, all malware checks run locally in app/analysis.py without external API calls.

Frequently Asked Questions

How does MobileAudit determine if a URL is malicious?

MobileAudit extracts the domain from URLs found in APK code using urllib.parse.urlsplit(), then queries the local Malware database with a case-insensitive substring search (url__icontains). If the domain appears in the pre-loaded MalwareDB or Maltrail feeds, the URL is flagged as malicious.

What databases does MobileAudit use for malware domain detection?

MobileAudit leverages two public threat intelligence feeds: the Malware Domain List (MalwareDB) and the Maltrail project. These are configured via MALWAREDB_URL and MALTRAILDB_URL in app/config/settings.py, and their data is imported into the local Django database for offline querying.

Can I disable malware domain checking in MobileAudit?

Yes. Set the environment variable MALWARE_ENABLED=False or modify app/config/settings.py to disable the feature. When disabled, MobileAudit skips the Malware.objects.get() query in app/analysis.py, improving scan performance while omitting domain reputation checks.

Where does MobileAudit store the malware domain data?

The malware data is stored in the Malware Django model defined in app/models.py, which includes fields for URL, IP address, description, and discovery date. This table is queried during analysis in app/analysis.py and browsable via the /malware/ view in app/views.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →