reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
201
reverse-engineering-android-malware-with-jadx/LICENSE
Normal file
201
reverse-engineering-android-malware-with-jadx/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. Please do not remove or change
|
||||
the license header comment from a contributed file except when
|
||||
necessary.
|
||||
|
||||
Copyright 2026 mukul975
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
353
reverse-engineering-android-malware-with-jadx/SKILL.md
Normal file
353
reverse-engineering-android-malware-with-jadx/SKILL.md
Normal file
@@ -0,0 +1,353 @@
|
||||
---
|
||||
name: reverse-engineering-android-malware-with-jadx
|
||||
description: 'Reverse engineers malicious Android APK files using JADX decompiler to analyze Java/Kotlin source code, identify
|
||||
malicious functionality including data theft, C2 communication, privilege escalation, and overlay attacks. Examines manifest
|
||||
permissions, receivers, services, and native libraries. Activates for requests involving Android malware analysis, APK reverse
|
||||
engineering, mobile malware investigation, or Android threat analysis.
|
||||
|
||||
'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware
|
||||
- Android
|
||||
- reverse-engineering
|
||||
- JADX
|
||||
- mobile-malware
|
||||
version: 1.0.0
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
nist_csf:
|
||||
- DE.AE-02
|
||||
- RS.AN-03
|
||||
- ID.RA-01
|
||||
- DE.CM-01
|
||||
---
|
||||
|
||||
# Reverse Engineering Android Malware with JADX
|
||||
|
||||
## When to Use
|
||||
|
||||
- A suspicious Android APK has been reported as malicious or flagged by mobile threat detection
|
||||
- Analyzing Android banking trojans, spyware, SMS stealers, or adware samples
|
||||
- Determining what data an app collects, where it sends it, and what permissions it abuses
|
||||
- Extracting C2 server addresses, encryption keys, and configuration data from Android malware
|
||||
- Understanding overlay attack mechanisms used by banking trojans
|
||||
|
||||
**Do not use** for analyzing obfuscated native (.so) libraries within APKs; use Ghidra or IDA for native ARM binary analysis.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- JADX 1.5+ installed (download from https://github.com/skylot/jadx/releases)
|
||||
- Android SDK with `aapt2` and `adb` tools for APK inspection
|
||||
- apktool for full APK disassembly including smali code and resources
|
||||
- Python 3.8+ with `androguard` library for automated APK analysis
|
||||
- Frida for dynamic instrumentation (optional, for runtime analysis)
|
||||
- Isolated Android emulator (Genymotion or Android Studio AVD) without Google services
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Extract APK Metadata and Permissions
|
||||
|
||||
Examine the APK structure and AndroidManifest.xml:
|
||||
|
||||
```bash
|
||||
# Get APK basic info
|
||||
aapt2 dump badging malware.apk
|
||||
|
||||
# Extract AndroidManifest.xml
|
||||
apktool d malware.apk -o apk_extracted/ -f
|
||||
|
||||
# Analyze permissions with androguard
|
||||
python3 << 'PYEOF'
|
||||
from androguard.core.apk import APK
|
||||
|
||||
apk = APK("malware.apk")
|
||||
|
||||
print(f"Package: {apk.get_package()}")
|
||||
print(f"App Name: {apk.get_app_name()}")
|
||||
print(f"Version: {apk.get_androidversion_name()}")
|
||||
print(f"Min SDK: {apk.get_min_sdk_version()}")
|
||||
print(f"Target SDK: {apk.get_target_sdk_version()}")
|
||||
|
||||
# Dangerous permissions
|
||||
dangerous_perms = {
|
||||
"android.permission.READ_SMS": "SMS theft",
|
||||
"android.permission.RECEIVE_SMS": "SMS interception",
|
||||
"android.permission.SEND_SMS": "Premium SMS fraud",
|
||||
"android.permission.READ_CONTACTS": "Contact harvesting",
|
||||
"android.permission.READ_CALL_LOG": "Call log theft",
|
||||
"android.permission.RECORD_AUDIO": "Audio surveillance",
|
||||
"android.permission.CAMERA": "Camera surveillance",
|
||||
"android.permission.ACCESS_FINE_LOCATION": "Location tracking",
|
||||
"android.permission.READ_PHONE_STATE": "Device fingerprinting",
|
||||
"android.permission.SYSTEM_ALERT_WINDOW": "Overlay attacks",
|
||||
"android.permission.BIND_ACCESSIBILITY_SERVICE": "Full device control",
|
||||
"android.permission.REQUEST_INSTALL_PACKAGES": "Sideloading apps",
|
||||
"android.permission.BIND_DEVICE_ADMIN": "Device admin abuse",
|
||||
}
|
||||
|
||||
print("\nDangerous Permissions:")
|
||||
for perm in apk.get_permissions():
|
||||
if perm in dangerous_perms:
|
||||
print(f" [!] {perm}")
|
||||
print(f" Risk: {dangerous_perms[perm]}")
|
||||
elif "android.permission" in perm:
|
||||
print(f" [*] {perm}")
|
||||
|
||||
# Components
|
||||
print("\nActivities:")
|
||||
for act in apk.get_activities():
|
||||
print(f" {act}")
|
||||
|
||||
print("\nServices:")
|
||||
for svc in apk.get_services():
|
||||
print(f" {svc}")
|
||||
|
||||
print("\nReceivers:")
|
||||
for rcv in apk.get_receivers():
|
||||
print(f" {rcv}")
|
||||
PYEOF
|
||||
```
|
||||
|
||||
### Step 2: Decompile with JADX
|
||||
|
||||
Open the APK in JADX for Java/Kotlin source analysis:
|
||||
|
||||
```bash
|
||||
# Open in JADX GUI
|
||||
jadx-gui malware.apk
|
||||
|
||||
# Command-line decompilation for scripted analysis
|
||||
jadx -d jadx_output/ malware.apk --show-bad-code
|
||||
|
||||
# Decompile with all options
|
||||
jadx -d jadx_output/ malware.apk \
|
||||
--deobf \
|
||||
--deobf-min 3 \
|
||||
--deobf-max 64 \
|
||||
--show-bad-code \
|
||||
--threads-count 4
|
||||
|
||||
# The output directory structure:
|
||||
# jadx_output/
|
||||
# sources/ <- Decompiled Java source code
|
||||
# com/malware/app/
|
||||
# MainActivity.java
|
||||
# C2Service.java
|
||||
# SMSReceiver.java
|
||||
# resources/ <- Decoded resources (layouts, strings, assets)
|
||||
# AndroidManifest.xml
|
||||
# res/
|
||||
# assets/
|
||||
```
|
||||
|
||||
### Step 3: Identify Malicious Functionality
|
||||
|
||||
Search for suspicious code patterns in decompiled sources:
|
||||
|
||||
```bash
|
||||
# Search for network communication
|
||||
grep -rn "HttpURLConnection\|OkHttpClient\|Retrofit\|Volley\|URL(" jadx_output/sources/
|
||||
|
||||
# Search for SMS operations
|
||||
grep -rn "SmsManager\|getDefault().sendTextMessage\|SMS_RECEIVED" jadx_output/sources/
|
||||
|
||||
# Search for overlay attack code
|
||||
grep -rn "SYSTEM_ALERT_WINDOW\|TYPE_APPLICATION_OVERLAY\|WindowManager.LayoutParams" jadx_output/sources/
|
||||
|
||||
# Search for accessibility service abuse
|
||||
grep -rn "AccessibilityService\|onAccessibilityEvent\|performAction" jadx_output/sources/
|
||||
|
||||
# Search for data exfiltration
|
||||
grep -rn "getDeviceId\|getSubscriberId\|getSimSerialNumber\|getLine1Number" jadx_output/sources/
|
||||
|
||||
# Search for crypto operations (key storage, encryption)
|
||||
grep -rn "SecretKeySpec\|Cipher.getInstance\|AES\|DES\|RSA" jadx_output/sources/
|
||||
|
||||
# Search for dynamic code loading
|
||||
grep -rn "DexClassLoader\|PathClassLoader\|loadDex\|loadClass" jadx_output/sources/
|
||||
|
||||
# Search for obfuscated strings and decryption
|
||||
grep -rn "Base64.decode\|decrypt\|decipher\|xor" jadx_output/sources/
|
||||
```
|
||||
|
||||
### Step 4: Analyze C2 Communication
|
||||
|
||||
Trace the network communication logic:
|
||||
|
||||
```python
|
||||
# Automated C2 extraction from decompiled code
|
||||
import os
|
||||
import re
|
||||
|
||||
jadx_dir = "jadx_output/sources"
|
||||
|
||||
# Patterns for C2 URLs and IPs
|
||||
url_pattern = re.compile(r'https?://[^\s"\'<>]+')
|
||||
ip_pattern = re.compile(r'"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"')
|
||||
base64_pattern = re.compile(r'"([A-Za-z0-9+/]{20,}={0,2})"')
|
||||
|
||||
urls = set()
|
||||
ips = set()
|
||||
b64_strings = set()
|
||||
|
||||
for root, dirs, files in os.walk(jadx_dir):
|
||||
for fname in files:
|
||||
if fname.endswith('.java'):
|
||||
filepath = os.path.join(root, fname)
|
||||
with open(filepath, 'r', errors='ignore') as f:
|
||||
content = f.read()
|
||||
|
||||
for match in url_pattern.finditer(content):
|
||||
urls.add(match.group())
|
||||
for match in ip_pattern.finditer(content):
|
||||
ips.add(match.group(1))
|
||||
for match in base64_pattern.finditer(content):
|
||||
b64_strings.add(match.group(1))
|
||||
|
||||
print("URLs found:")
|
||||
for u in urls:
|
||||
print(f" {u}")
|
||||
|
||||
print("\nIP addresses:")
|
||||
for ip in ips:
|
||||
print(f" {ip}")
|
||||
|
||||
# Decode Base64 strings
|
||||
import base64
|
||||
print("\nDecoded Base64 strings:")
|
||||
for b64 in b64_strings:
|
||||
try:
|
||||
decoded = base64.b64decode(b64).decode('utf-8', errors='ignore')
|
||||
if any(c.isprintable() for c in decoded) and len(decoded) > 3:
|
||||
print(f" {b64[:30]}... -> {decoded[:100]}")
|
||||
except:
|
||||
pass
|
||||
```
|
||||
|
||||
### Step 5: Examine Native Libraries
|
||||
|
||||
Check for native code that may contain additional malicious logic:
|
||||
|
||||
```bash
|
||||
# List native libraries in the APK
|
||||
unzip -l malware.apk | grep "\.so$"
|
||||
|
||||
# Extract native libraries
|
||||
unzip malware.apk "lib/*" -d apk_native/
|
||||
|
||||
# Check native library properties
|
||||
file apk_native/lib/armeabi-v7a/*.so
|
||||
readelf -d apk_native/lib/armeabi-v7a/*.so | grep NEEDED
|
||||
|
||||
# Strings from native libraries
|
||||
strings apk_native/lib/armeabi-v7a/libpayload.so | grep -iE "(http|url|key|encrypt|password)"
|
||||
|
||||
# For deep native analysis, import into Ghidra:
|
||||
# File -> Import -> Select .so file -> Select ARM architecture
|
||||
```
|
||||
|
||||
### Step 6: Document Analysis and Extract IOCs
|
||||
|
||||
Compile a comprehensive Android malware analysis report:
|
||||
|
||||
```
|
||||
Analysis documentation should include:
|
||||
- APK metadata (package name, version, signing certificate)
|
||||
- Permission analysis with risk assessment
|
||||
- Component analysis (activities, services, receivers, providers)
|
||||
- Decompiled code walkthrough of malicious functions
|
||||
- C2 communication protocol and endpoints
|
||||
- Data exfiltration methods and targeted data types
|
||||
- Persistence mechanisms (device admin, accessibility service)
|
||||
- Evasion techniques (emulator detection, root detection)
|
||||
- Extracted IOCs (C2 URLs, domains, IPs, signing certificate hash)
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **APK (Android Package)** | Android application package format containing compiled DEX bytecode, resources, manifest, and native libraries |
|
||||
| **DEX Bytecode** | Dalvik Executable format containing compiled Java/Kotlin code; JADX converts this back to readable Java source |
|
||||
| **Overlay Attack** | Banking trojan technique displaying a fake UI layer over a legitimate banking app to steal credentials using SYSTEM_ALERT_WINDOW permission |
|
||||
| **Accessibility Service Abuse** | Malware registering as an accessibility service to capture screen content, perform actions, and prevent uninstallation |
|
||||
| **Smali** | Human-readable representation of DEX bytecode; intermediate representation between bytecode and Java used by apktool |
|
||||
| **Dynamic Code Loading** | Loading additional DEX code at runtime using DexClassLoader to hide malicious functionality from static analysis |
|
||||
| **Device Admin Abuse** | Malware requesting device administrator privileges to prevent uninstallation and perform device wipe threats |
|
||||
|
||||
## Tools & Systems
|
||||
|
||||
- **JADX**: Open-source DEX to Java decompiler providing GUI and CLI for Android APK analysis with deobfuscation support
|
||||
- **apktool**: Tool for reverse engineering Android APK files to smali code and decoded resources
|
||||
- **androguard**: Python framework for automated Android APK analysis including permission, component, and code analysis
|
||||
- **Frida**: Dynamic instrumentation toolkit for hooking Java methods and native functions at runtime on Android
|
||||
- **MobSF (Mobile Security Framework)**: Automated mobile application security testing framework for static and dynamic analysis
|
||||
|
||||
## Common Scenarios
|
||||
|
||||
### Scenario: Analyzing an Android Banking Trojan
|
||||
|
||||
**Context**: A banking trojan APK is distributed via SMS phishing targeting customers of a specific bank. The sample needs analysis to identify targeted banks, C2 infrastructure, and data theft mechanisms.
|
||||
|
||||
**Approach**:
|
||||
1. Extract APK metadata and identify requested permissions (SMS, accessibility, overlay, device admin)
|
||||
2. Decompile with JADX and search for overlay activity classes that mimic banking app UIs
|
||||
3. Identify the list of targeted banking apps by searching for package name lists in the code
|
||||
4. Trace the SMS interception receiver to understand how 2FA codes are stolen
|
||||
5. Follow the C2 communication code to extract server URLs and command protocol
|
||||
6. Check for web injection configuration files in assets/ directory
|
||||
7. Extract all IOCs and document the complete attack chain
|
||||
|
||||
**Pitfalls**:
|
||||
- Not deobfuscating class and method names before analysis (use JADX --deobf flag)
|
||||
- Missing dynamically loaded DEX files downloaded after installation
|
||||
- Ignoring native .so libraries that may contain the actual C2 logic or encryption routines
|
||||
- Overlooking assets/ directory which may contain encrypted configuration or web injects
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
ANDROID MALWARE ANALYSIS REPORT
|
||||
==================================
|
||||
APK File: update_bank.apk
|
||||
Package: com.android.systemupdate
|
||||
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
|
||||
Version: 1.2.3
|
||||
Min SDK: 21 (Android 5.0)
|
||||
Signing Cert: SHA-256: abc123... (self-signed)
|
||||
|
||||
CLASSIFICATION
|
||||
Family: Anubis Banking Trojan
|
||||
Type: Banking Trojan / SMS Stealer / Keylogger
|
||||
|
||||
DANGEROUS PERMISSIONS
|
||||
[!] RECEIVE_SMS - Intercepts incoming SMS (2FA theft)
|
||||
[!] READ_SMS - Reads SMS messages
|
||||
[!] SEND_SMS - Sends premium SMS
|
||||
[!] SYSTEM_ALERT_WINDOW - Overlay attacks on banking apps
|
||||
[!] BIND_ACCESSIBILITY - Full device control
|
||||
[!] BIND_DEVICE_ADMIN - Prevents uninstallation
|
||||
|
||||
MALICIOUS COMPONENTS
|
||||
Service: com.android.systemupdate.C2Service (C2 communication)
|
||||
Receiver: com.android.systemupdate.SmsReceiver (SMS interception)
|
||||
Activity: com.android.systemupdate.OverlayActivity (credential overlay)
|
||||
|
||||
TARGETED APPS (23 banking apps)
|
||||
com.bank.example1, com.bank.example2, ...
|
||||
|
||||
C2 INFRASTRUCTURE
|
||||
Primary: hxxps://c2-server[.]com/api/bot
|
||||
Fallback: hxxps://backup-c2[.]net/api/bot
|
||||
Protocol: HTTPS POST with JSON body
|
||||
Bot ID: MD5(IMEI + Build.SERIAL)
|
||||
|
||||
EXTRACTED IOCs
|
||||
Domains: c2-server[.]com, backup-c2[.]net
|
||||
IPs: 185.220.101[.]42
|
||||
URLs: hxxps://c2-server[.]com/api/bot
|
||||
hxxps://c2-server[.]com/api/injects
|
||||
Cert Hash: abc123def456...
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
# API Reference: Android Malware Reverse Engineering with JADX Agent
|
||||
|
||||
## Overview
|
||||
|
||||
Reverse engineers Android APKs using apktool for manifest extraction, JADX for Java decompilation, and regex-based source code analysis for malicious patterns (C2 URLs, SMS interception, overlay attacks).
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| hashlib | stdlib | APK hash computation |
|
||||
| xml.etree | stdlib | AndroidManifest.xml parsing |
|
||||
|
||||
## External Tools Required
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| apktool | APK disassembly and manifest extraction |
|
||||
| jadx | DEX to Java decompilation with deobfuscation |
|
||||
|
||||
## Core Functions
|
||||
|
||||
### `compute_apk_hashes(apk_path)`
|
||||
Generates MD5 and SHA-256 hashes for APK identification.
|
||||
|
||||
### `extract_manifest(apk_path, output_dir)`
|
||||
Extracts AndroidManifest.xml and parses permissions, activities, services, receivers.
|
||||
- **Returns**: `dict` with `package`, `permissions`, `activities`, `services`, `receivers`
|
||||
|
||||
### `analyze_permissions(permissions)`
|
||||
Classifies permissions against a list of 16 dangerous Android permissions.
|
||||
- **Risk**: CRITICAL if SMS/accessibility/device-admin, HIGH if >5 dangerous
|
||||
- **Returns**: `dict` with categorized permission lists and risk level
|
||||
|
||||
### `decompile_with_jadx(apk_path, output_dir)`
|
||||
Runs JADX with `--deobf` flag for deobfuscated Java source output.
|
||||
- **Timeout**: 300 seconds
|
||||
|
||||
### `search_source_code(source_dir, patterns)`
|
||||
Searches decompiled Java source for 10 malicious pattern categories.
|
||||
- **Returns**: `dict[str, list[dict]]` - pattern name to file/match pairs
|
||||
|
||||
### `analyze_apk(apk_path, output_base)`
|
||||
Full pipeline: hashes -> manifest -> permissions -> decompile -> code analysis.
|
||||
|
||||
## Malicious Code Patterns
|
||||
|
||||
| Pattern | Indicator |
|
||||
|---------|-----------|
|
||||
| urls | HTTP/HTTPS C2 server addresses |
|
||||
| ips | Hardcoded IP addresses |
|
||||
| exec_commands | Runtime.exec() shell command execution |
|
||||
| reflection | Class.forName() dynamic class loading |
|
||||
| dex_loading | DexClassLoader for loading additional code |
|
||||
| overlay_attack | TYPE_APPLICATION_OVERLAY for phishing overlays |
|
||||
| accessibility_abuse | AccessibilityService for keylogging/automation |
|
||||
| sms_intercept | SMS_RECEIVED broadcast interception |
|
||||
|
||||
## Dangerous Permissions Checked
|
||||
|
||||
READ_SMS, SEND_SMS, RECEIVE_SMS, READ_CONTACTS, CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_PHONE_STATE, BIND_ACCESSIBILITY_SERVICE, BIND_DEVICE_ADMIN, REQUEST_INSTALL_PACKAGES
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python agent.py malware.apk
|
||||
```
|
||||
196
reverse-engineering-android-malware-with-jadx/scripts/agent.py
Normal file
196
reverse-engineering-android-malware-with-jadx/scripts/agent.py
Normal file
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Android malware reverse engineering agent using jadx and androguard subprocess wrappers."""
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import hashlib
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
def compute_apk_hashes(apk_path):
|
||||
"""Compute hashes for APK identification."""
|
||||
with open(apk_path, "rb") as f:
|
||||
data = f.read()
|
||||
return {
|
||||
"md5": hashlib.md5(data).hexdigest(),
|
||||
"sha256": hashlib.sha256(data).hexdigest(),
|
||||
"size": len(data),
|
||||
}
|
||||
|
||||
|
||||
def extract_manifest(apk_path, output_dir):
|
||||
"""Extract and parse AndroidManifest.xml using apktool."""
|
||||
subprocess.run(
|
||||
["apktool", "d", apk_path, "-o", output_dir, "-f"],
|
||||
capture_output=True, text=True, timeout=120
|
||||
)
|
||||
manifest_path = os.path.join(output_dir, "AndroidManifest.xml")
|
||||
if not os.path.exists(manifest_path):
|
||||
return {"error": "Manifest extraction failed"}
|
||||
tree = ElementTree.parse(manifest_path)
|
||||
root = tree.getroot()
|
||||
ns = {"android": "http://schemas.android.com/apk/res/android"}
|
||||
permissions = []
|
||||
for perm in root.findall(".//uses-permission"):
|
||||
name = perm.get(f"{{{ns['android']}}}name", "")
|
||||
permissions.append(name)
|
||||
activities = []
|
||||
for act in root.findall(".//activity"):
|
||||
name = act.get(f"{{{ns['android']}}}name", "")
|
||||
exported = act.get(f"{{{ns['android']}}}exported", "false")
|
||||
activities.append({"name": name, "exported": exported})
|
||||
services = []
|
||||
for svc in root.findall(".//service"):
|
||||
name = svc.get(f"{{{ns['android']}}}name", "")
|
||||
services.append(name)
|
||||
receivers = []
|
||||
for rcv in root.findall(".//receiver"):
|
||||
name = rcv.get(f"{{{ns['android']}}}name", "")
|
||||
intents = []
|
||||
for intent in rcv.findall(".//intent-filter/action"):
|
||||
intents.append(intent.get(f"{{{ns['android']}}}name", ""))
|
||||
receivers.append({"name": name, "intents": intents})
|
||||
package = root.get("package", "")
|
||||
return {
|
||||
"package": package,
|
||||
"permissions": permissions,
|
||||
"activities": activities,
|
||||
"services": services,
|
||||
"receivers": receivers,
|
||||
}
|
||||
|
||||
|
||||
DANGEROUS_PERMISSIONS = [
|
||||
"android.permission.READ_SMS", "android.permission.SEND_SMS",
|
||||
"android.permission.RECEIVE_SMS", "android.permission.READ_CONTACTS",
|
||||
"android.permission.CAMERA", "android.permission.RECORD_AUDIO",
|
||||
"android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE",
|
||||
"android.permission.CALL_PHONE", "android.permission.READ_CALL_LOG",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.SYSTEM_ALERT_WINDOW", "android.permission.BIND_ACCESSIBILITY_SERVICE",
|
||||
"android.permission.REQUEST_INSTALL_PACKAGES", "android.permission.BIND_DEVICE_ADMIN",
|
||||
]
|
||||
|
||||
|
||||
def analyze_permissions(permissions):
|
||||
"""Classify permissions by risk level."""
|
||||
dangerous = [p for p in permissions if p in DANGEROUS_PERMISSIONS]
|
||||
sms_related = [p for p in permissions if "SMS" in p]
|
||||
accessibility = [p for p in permissions if "ACCESSIBILITY" in p]
|
||||
admin = [p for p in permissions if "DEVICE_ADMIN" in p or "BIND_ADMIN" in p]
|
||||
risk = "LOW"
|
||||
if len(dangerous) > 5:
|
||||
risk = "HIGH"
|
||||
if sms_related or accessibility or admin:
|
||||
risk = "CRITICAL"
|
||||
return {
|
||||
"total": len(permissions),
|
||||
"dangerous": dangerous,
|
||||
"sms_related": sms_related,
|
||||
"accessibility": accessibility,
|
||||
"device_admin": admin,
|
||||
"risk": risk,
|
||||
}
|
||||
|
||||
|
||||
def decompile_with_jadx(apk_path, output_dir):
|
||||
"""Decompile APK to Java source using JADX."""
|
||||
result = subprocess.run(
|
||||
["jadx", "-d", output_dir, "--deobf", apk_path],
|
||||
capture_output=True, text=True, timeout=300
|
||||
)
|
||||
return {
|
||||
"output_dir": output_dir,
|
||||
"returncode": result.returncode,
|
||||
"stdout": result.stdout[-500:] if result.stdout else "",
|
||||
}
|
||||
|
||||
|
||||
def search_source_code(source_dir, patterns=None):
|
||||
"""Search decompiled source for suspicious patterns."""
|
||||
if patterns is None:
|
||||
patterns = {
|
||||
"urls": r'https?://[^\s"\'<>]+',
|
||||
"ips": r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b',
|
||||
"crypto_keys": r'(?:AES|DES|RSA|key|secret|encrypt).*?["\']([^"\']{8,})["\']',
|
||||
"base64_strings": r'[A-Za-z0-9+/]{40,}={0,2}',
|
||||
"exec_commands": r'Runtime\.getRuntime\(\)\.exec|ProcessBuilder',
|
||||
"reflection": r'Class\.forName|getMethod|getDeclaredMethod',
|
||||
"dex_loading": r'DexClassLoader|PathClassLoader|InMemoryDexClassLoader',
|
||||
"overlay_attack": r'TYPE_APPLICATION_OVERLAY|SYSTEM_ALERT_WINDOW',
|
||||
"accessibility_abuse": r'AccessibilityService|onAccessibilityEvent',
|
||||
"sms_intercept": r'SmsReceiver|SMS_RECEIVED|sendTextMessage',
|
||||
}
|
||||
findings = {p: [] for p in patterns}
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for filename in files:
|
||||
if not filename.endswith(".java"):
|
||||
continue
|
||||
filepath = os.path.join(root, filename)
|
||||
try:
|
||||
with open(filepath, "r", errors="ignore") as f:
|
||||
content = f.read()
|
||||
for pattern_name, regex in patterns.items():
|
||||
matches = re.findall(regex, content)
|
||||
if matches:
|
||||
findings[pattern_name].extend([
|
||||
{"file": filepath, "match": m[:100]} for m in matches[:5]
|
||||
])
|
||||
except (OSError, UnicodeDecodeError):
|
||||
pass
|
||||
for key in findings:
|
||||
findings[key] = findings[key][:20]
|
||||
return findings
|
||||
|
||||
|
||||
def analyze_apk(apk_path, output_base="/tmp/apk_analysis"):
|
||||
"""Full APK analysis pipeline."""
|
||||
os.makedirs(output_base, exist_ok=True)
|
||||
report = {"apk": apk_path}
|
||||
report["hashes"] = compute_apk_hashes(apk_path)
|
||||
apktool_dir = os.path.join(output_base, "apktool")
|
||||
report["manifest"] = extract_manifest(apk_path, apktool_dir)
|
||||
if "permissions" in report["manifest"]:
|
||||
report["permission_analysis"] = analyze_permissions(report["manifest"]["permissions"])
|
||||
jadx_dir = os.path.join(output_base, "jadx_output")
|
||||
report["decompilation"] = decompile_with_jadx(apk_path, jadx_dir)
|
||||
if os.path.exists(jadx_dir):
|
||||
source_dir = os.path.join(jadx_dir, "sources")
|
||||
if os.path.exists(source_dir):
|
||||
report["code_analysis"] = search_source_code(source_dir)
|
||||
return report
|
||||
|
||||
|
||||
def print_report(report):
|
||||
print("Android Malware Analysis Report")
|
||||
print("=" * 50)
|
||||
print(f"APK: {report['apk']}")
|
||||
print(f"SHA-256: {report['hashes']['sha256']}")
|
||||
print(f"Size: {report['hashes']['size']} bytes")
|
||||
manifest = report.get("manifest", {})
|
||||
print(f"\nPackage: {manifest.get('package', 'N/A')}")
|
||||
perm = report.get("permission_analysis", {})
|
||||
print(f"Permissions: {perm.get('total', 0)} (Risk: {perm.get('risk', 'N/A')})")
|
||||
if perm.get("dangerous"):
|
||||
print(f" Dangerous: {', '.join(p.split('.')[-1] for p in perm['dangerous'][:8])}")
|
||||
print(f"Activities: {len(manifest.get('activities', []))}")
|
||||
print(f"Services: {len(manifest.get('services', []))}")
|
||||
print(f"Receivers: {len(manifest.get('receivers', []))}")
|
||||
code = report.get("code_analysis", {})
|
||||
if code:
|
||||
print("\nCode Analysis Findings:")
|
||||
for pattern, matches in code.items():
|
||||
if matches:
|
||||
print(f" {pattern}: {len(matches)} match(es)")
|
||||
for m in matches[:3]:
|
||||
print(f" -> {m['match'][:80]}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python agent.py <apk_file>")
|
||||
sys.exit(1)
|
||||
result = analyze_apk(sys.argv[1])
|
||||
print_report(result)
|
||||
Reference in New Issue
Block a user