# Tapjacking {{#include ../../banners/hacktricks-training.md}} ## **Basic Information** **Tapjacking** is an attack where a **malicious** **application** is launched and **positions itself on top of a victim application**. Once it visibly obscures the victim app, its user interface is designed in such a way as to trick the user to interact with it, while it is passing the interaction along to the victim app.\ In effect, it is **blinding the user from knowing they are actually performing actions on the victim app**. ### Detection In order to detect apps vulnerable to this attacked you should search for **exported activities** in the android manifest (note that an activity with an intent-filter is automatically exported by default). Once you have found the exported activities, **check if they require any permission**. This is because the **malicious application will need that permission also**. You can also check the minimum SDK version of the app, checking the value of **`android:minSdkVersion`** in the **`AndroidManifest.xml`** file. If the value is **lower than 30**, the app is vulnerable to Tapjacking. ### Protection #### Android 12 (API 31,32) and higher [**According to this source**](https://www.geeksforgeeks.org/tapjacking-in-android/)**,** tapjacking attacks are automatically prevented by Android from Android 12 (API 31 & 30) and higher. So, even if the application is vulnerable you **won't be able to exploit it**. #### `filterTouchesWhenObscured` If **`android:filterTouchesWhenObscured`** is set to **`true`**, the `View` will not receive touches whenever view's window is obscured by another visible window. #### **`setFilterTouchesWhenObscured`** The attribute **`setFilterTouchesWhenObscured`** set to true can also prevent the exploitation of this vulnerability if the Android version is lower.\ If set to **`true`**, for example, a button can be automatically **disabled if it is obscured**: ```xml ``` ## Exploitation ### Tapjacking-ExportedActivity The most **recent Android application** performing a Tapjacking attack (+ invoking before an exported activity of the attacked application) can be found in: [**https://github.com/carlospolop/Tapjacking-ExportedActivity**](https://github.com/carlospolop/Tapjacking-ExportedActivity). Follow the **README instructions to use it**. ### FloatingWindowApp An example project implementing **FloatingWindowApp**, which can be used to put on top of other activities to perform a clickjacking attack, can be found in [**FloatingWindowApp**](https://github.com/aminography/FloatingWindowApp) (a bit old, good luck building the apk). ### Qark > [!CAUTION] > It looks like this project is now unmaintained and this functionality isn't properly working anymore You can use [**qark**](https://github.com/linkedin/qark) with the `--exploit-apk` --sdk-path `/Users/username/Library/Android/sdk` parameters to create a malicious application to test for possible **Tapjacking** vulnerabilities.\ The mitigation is relatively simple as the developer may choose not to receive touch events when a view is covered by another. Using the [Android Developer’s Reference](https://developer.android.com/reference/android/view/View#security): > Sometimes it is essential that an application be able to verify that an action is being performed with the full knowledge and consent of the user, such as granting a permission request, making a purchase or clicking on an advertisement. Unfortunately, a malicious application could try to spoof the user into performing these actions, unaware, by concealing the intended purpose of the view. As a remedy, the framework offers a touch filtering mechanism that can be used to improve the security of views that provide access to sensitive functionality. > > To enable touch filtering, call [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29) or set the android:filterTouchesWhenObscured layout attribute to true. When enabled, the framework will discard touches that are received whenever the view's window is obscured by another visible window. As a result, the view will not receive touches whenever a toast, dialog or other window appears above the view's window. --- ## Accessibility Overlay Phishing (Banking-Trojan Variant) Besides classic Tapjacking, modern Android banking malware families (e.g. **ToxicPanda**, BrasDex, Sova, etc.) abuse the **Accessibility Service** to place a full-screen WebView **overlay** above the legitimate application while still being able to **forward the user input** to the view underneath. This dramatically increases believability and allows attackers to steal credentials, OTPs or even automate fraudulent transactions. ### How it works 1. The malicious APK requests the highly-sensitive `BIND_ACCESSIBILITY_SERVICE` permission, usually hiding the request behind a fake Google/Chrome/PDF-viewer dialog. 2. Once the user enables the service, the malware programmatically simulates the taps required to grant additional dangerous permissions (`READ_SMS`, `SYSTEM_ALERT_WINDOW`, `REQUEST_INSTALL_PACKAGES`, …). 3. A **WebView** is inflated and added to the window manager using the **`TYPE_ACCESSIBILITY_OVERLAY`** window type. The overlay can be rendered totally opaque or semi-transparent and can be flagged as *“through”* so that the original touches are still delivered to the background activity (thus the transaction really happens while the victim only sees the phishing form). ```java WebView phishingView = new WebView(getApplicationContext()); phishingView.getSettings().setJavaScriptEnabled(true); phishingView.loadUrl("file:///android_asset/bank_login.html"); WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams lp = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY, // <-- bypasses SYSTEM_ALERT_WINDOW prompt WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // «through» flag → forward touches PixelFormat.TRANSLUCENT); wm.addView(phishingView, lp); ``` ### Typical workflow used by banking Trojans * Query installed packages (`QUERY_ALL_PACKAGES`) to figure out which banking / wallet app is currently opened. * Download an **HTML/JS overlay template** from the C2 that perfectly imitates that specific application (Logo, colours, i18n strings…). * Display the overlay, harvest credentials/PIN/pattern. * Use the **Accessibility API** (`performGlobalAction`, `GestureDescription`) to automate transfers in the background. ### Detection & Mitigation * Audit the list of installed apps with `adb shell pm list packages -3 -e BIND_ACCESSIBILITY_SERVICE`. * From the application side (bank / wallet): - Enable **`android:accessibilityDataSensitive="accessibilityDataPrivateYes"`** (Android 14+) on sensitive views to block non-Play-Store services. - Combine with `setFilterTouchesWhenObscured(true)` and `FLAG_SECURE`. * System hardening: - Disable *Install from Unknown Sources* & *Accessibility for untrusted apps*. - Enforce PlayProtect & up-to-date devices. For additional details on leveraging Accessibility Services for full remote device control (e.g. PlayPraetor, SpyNote, etc.) see: {{#ref}} accessibility-services-abuse.md {{#endref}} ## References * [Bitsight – ToxicPanda Android Banking Malware 2025 Study](https://www.bitsight.com/blog/toxicpanda-android-banking-malware-2025-study) {{#include ../../banners/hacktricks-training.md}}