MediumEagleSpy. Scenario | by Yufan Limbu | Medium
Sitemap
Yufan Limbu

Yufan Limbu

EagleSpy

6 min readAug 1, 2026

--

Scenario

EagleSpy is a malware family that emerged from the SpyNote source code leak. Your task as a malware analyst is to identify key characteristics of this sample and answer the questions below

Question 1

What is the name of the file used to define the essential structures and metadata of an Android application?

AndroidManifest.xml
Every Android application (APK) must contain a `AndroidManifest.xml`
file in its root directory. This file is the application's "ID card"
and is parsed by the Android framework at install time and at runtime.
It declares:

- The **package name** (application ID) and unique identifier of the app.
- All **components** of the app: Activities, Services, Broadcast Receivers, and Content Providers.
- **Permissions** the app requires, and permissions it grants to other apps.
- The **entry point** of the application (the launcher activity) via intent filters.
- Required hardware/software features and the minimum SDK version.
- Metadata about the app, e.g. `android:name` attributes pointing to classes.
Press enter or click to view image in full size

Question 2

What is the package ID name of this sample?

com.appd.instll.load
The **package ID** (also called application ID or package name) is the
unique identifier of the application, formatted like `com.example.app`.
It is the primary location where the package name lives:

- **Primary location:** `AndroidManifest.xml` — attribute
`package="com.appd.instll.load"` on the root `<manifest>` element.
- Also referenced in the DEX code (e.g., `BuildConfig.APPLICATION_ID`)
and the file paths of the decompiled project.
Press enter or click to view image in full size

Question 3

How many permissions are declared by this sample?

4
Press enter or click to view image in full size

Question 4

What is the name of the class used in the main activity used as the entry point?

splash
```xml
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
```

- `android.intent.action.MAIN` — marks this activity as the entry p
oint of the application.
- `android.intent.category.LAUNCHER` — tells Android to show this
activity's icon in the launcher.

Reading the `android:name` attribute of the activity that holds this
intent filter gives the entry-point class. In this sample:

```
android:name="com.apdd.install.Splash" → the Splash activity is the entry point
Press enter or click to view image in full size

Question 5

What is the method used to validate if an application is already installed on the device?

isAppAvailable
The method `isAppAvailable` is a custom helper routine in the malware's code that checks whether a given application is already installed on the device.

A typical implementation queries the PackageManager:

```java
public boolean isAppAvailable(Context context, String packageName) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
return true; // app is installed
} catch (PackageManager.NameNotFoundException e) {
return false; // app is NOT installed
}
}
```

- `PackageManager.getPackageInfo()` throws `NameNotFoundException`
when the package does not exist on the device.
- Wrapping it in a try/catch lets the malware distinguish between
"installed" and "not installed" reliably.
Press enter or click to view image in full size

Question 6

What is the name of the application package that is checked by the previous method?

com.found.hentai
The package name contains the word **"hentai"** —
a tactic used by some malware authors to hide the malicious app
in a "browsing history" style decoy: if discovered on the device, the name
suggests the user installed a "questionable" app themselves, discouraging them from reporting it.
- This is a **psychological/social-engineering obfuscation** trick: victims
often won't admit to (or investigate) apps they are embarrassed to be
associated with.
- Alternatively, the check may be part of the dropper logic: if a previous
version of the spyware is already installed, skip re-installation to
avoid detection.
Press enter or click to view image in full size

Question 7

Get Yufan Limbu’s stories in your inbox

Join Medium for free to get updates from this writer.

The sample checks the device’s default language. How many languages does this sample target?

6
The malware reads the device's default language at runtime:

```java
String language = Locale.getDefault().getLanguage();
```

It then compares this value against a hardcoded list of **6 targeted
language codes**:

| Code | Language |
|------|-----------------|
| `ar` | Arabic |
| `en` | English |
| `pt` | Portuguese |
| `ru` | Russian |
| `tr` | Turkish |
| `zh` | Chinese |
Press enter or click to view image in full size

Question 8

What are the two permissions requested dynamically by the sample to install the next payload (separated by a comma)

WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
To install the next payload, the malware dynamically requests
(at runtime) the storage permissions:

- `WRITE_EXTERNAL_STORAGE` — allows the app to **write** files to
external/shared storage (used to save the downloaded APK,
e.g. `childapp.apk`, to the device).
- `READ_EXTERNAL_STORAGE` — allows the app to **read** files from
external storage (used to read/verify the saved APK before launching
the installer).
Press enter or click to view image in full size

Question 10

What is the SHA256 of the next payload?

799a3d9663bb9c26c3cfe68ed2c8e35c657ac3edf969825dc83f2c5812f96429

┌──(kali㉿kali)-[~/blue/malops]
└─$ sha256sum childapp.apk
799a3d9663bb9c26c3cfe68ed2c8e35c657ac3edf969825dc83f2c5812f96429 childapp.apk

- The **SHA256 hash is a unique fingerprint** of the file. Any change to
even one byte produces a completely different hash.
- Analysts use it to:
- **Share the sample** across teams and intelligence platforms (VirusTotal,
MalwareBazaar, MISP) without sharing the file itself.
- **Detect the malware** on other systems (hash-based detection / IOC).
- **Verify integrity** — confirm the extracted payload matches the one
deployed by the C2.
- Because hash-based detection is easily bypassed (repacking), it should
always be used together with behavioral and static indicators.
Press enter or click to view image in full size

Question 11

The second payload acts as a legitimate government application. What is the name of the Trojanized application?

VNeID
The second-stage payload is a **trojanized copy of VNeID** —
a legitimate Vietnamese government mobile application for digital
identification (the Vietnamese "National Digital Identity" app,
issued by the Ministry of Public Security, used for e-identification,
digital signatures, public services, etc.).
Press enter or click to view image in full size

Question 12

To avoid losing access to the compromised device, the malware establishes persistence on it. What is the name of the permission used for persistence?

RECEIVE_BOOT_COMPLETED
Persistence is the malware's ability to **survive a device reboot**.
EagleSpy does this by declaring and registering a Broadcast Receiver
for the `RECEIVE_BOOT_COMPLETED` permission:

```xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver android:name=".BootReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Press enter or click to view image in full size

Question 13

After identifying the method that establishes the C2 connection, what is the decoded IP address and port used by this malware?

103.253.23.8:7773
After identifying the method that establishes the C2 (Command & Control) c
onnection, the analyst found that the server address was
**not stored in plaintext** — it was encoded in **Base64**.

Decoding the Base64-encoded string revealed:

```
IP: 103.253.23.8
Port: 7773
Press enter or click to view image in full size

Since, it was in the base64 format after decoding it.

Press enter or click to view image in full size

Question 14

What is the decoded value from the ConnectionKey?

EagleSpy
The sample uses a `ConnectionKey` value during C2 communication, and
like the C2 address, it was stored in an encoded form. After decoding
(Base64), the value is:

```
ConnectionKey (decoded) = "Eaglespy"
Press enter or click to view image in full size

Question 15

What is the secret key used to encrypt and decrypt the JSON data?

93b89a273c1fbe59073af7bd9adfa6c0
The key format (32 hex characters = 16 bytes = 128 bits) is consistent
with **AES-128** (the most common choice in Android RATs,
including the SpyNote lineage), though it could also be used with other symmetric algorithms (e.g., Blowfish, which was popular in older SpyNote builds).
- The key is **hardcoded in the application** (stored in the DEX code, o
ften in an encoded/obfuscated form that must be decoded first).
- The analyst typically:
1. Locates the encryption routine (e.g., calls to `Cipher.getInstance("AES")`).
2. Extracts the key material from the code or strings.
3. Confirms it by decrypting a captured C2 JSON message and validating
the plaintext structure.
Press enter or click to view image in full size

--

--