https://00xbyte.github.io/posts/Don%27t-Believe-Your-Eyes-A-WhatsApp-Clickjacking-Vulnerability/ avatar Security Is Broken by Zuki * HOME * CATEGORIES * TAGS * TIMELINE * ABOUT Home Don't Believe Your Eyes - A WhatsApp Clickjacking Vulnerability Post [ ] Cancel Don't Believe Your Eyes - A WhatsApp Clickjacking Vulnerability Posted Oct 29, 2023 Preview Image By Zuki (Itay Zukerman) 6 min read Imagine you have received a WhatsApp message with a link to ln.instagram.com. Where do you think the link leads? Instagram? Think again. I have found a clickjacking vulnerability in WhatsApp that enables phishing attacks. An attacker can send anyone a crafted message with a link that appears to lead to a legitimate website, but in fact leads to any website of the attacker's choice. Discovery Process I started my research looking for a way to make a message recipient perform an HTTP request. My initial thought was to check WA's link preview feature. I hoped the the link would be rendered twice, once by the sender and once by the receiver. In order to check my theory, I created a webhook and sent it to a friend. Sadly only one request was made, only by me. That got me thinking. If the receiver does not render the link for themselves, that must mean I send both the link and the preview. If so, I wonder if I can send a link to one site with a preview of another? Issue #1 - Link Preview Mismatch I decided to take a look into what data is sent in a WA message that contains a link with a preview. My goal was to intercept the message, change the link and the preview to mismatch, and send it. I decided to intercept a message via WA web, as hopefully that would be a faster setup than debugging an emulator. I then ran into a problem - WA uses and E2EE so I couldn't simply modify the message with proxy like Burp Suite. [svg] Instead of understanding the encryption mechanism, I decided insert a breakpoint a moment before the message was encrypted and sent through the websocket. WA web's javascript was uglified and minified, however after a while of searching I found the right place. [svg] Exactly as I suspected, the link and the preview were sent separately! I created a message object forinstagram.com and changed the text property to google.com. Unfortunately, the message that was sent did not have a preview anymore. Only a link to Google. Blackbox testing taught me that: Property Purpose text The text of the message canonicalURL The domain that is shown at the bottom of the preview matchedText Seems to be compared against canonicalURL, also tested that its value apears in text I discovered that if the matchedText was deleted from the object, I could create a mismatch! [svg] Success! I have created a message with a preview to one site, and when clicked, leads to another. This was a great start, but I didn't want the real link to be shown in the message. I was looking for ways to hide the message text. Issue #2 - Disguising Links (2K2E) I remembered that some unicode characters can change the representation of text, so I tried fuzzing characters to see their effect: 1 function fuzz(start, end) { 2 for (let i = start; i <= end ; i++) { 3 j = i.toString(16) 4 if (j.length < 4) { j = "0".repeat(4 -j.length) + j} 5 msg += eval("\"\\u"+j+"\"") 6 + "https://google.com/" + i.toString(16) 7 + "\n" 8 } 9 } I observed the results and one result caught my eye. One of the lines (202e) was in reverse: [svg] Apparently, the unicode character U+202E (Right-To-Left Override) alters the way that text is presented to the user by displaying it in reverse order. That was a great start but this link looks horrible. Nobody would click it. Crafting A Mirror URL I wanted to create a URL that, when reversed, looked like https:// instagram.com. This means that the link should be moc.margatsni/ /:sttph (\u202e+moc.margatsni//:sttph = https://instagram.com ) This fist problem is the TLD. I cannot register a .margatsni domain. My solution was to find a TLD that could look like a subdomain. For example the TLD .nl (Netherlands) would result in ln.instagram.com (ln as in link) Problem number two was that the URL needed to start with https:// in order to look legitimate. My solution to this was to append the string //:sptth (which is a valid path) to the URL, so that https://moc.margatsni.nl//:sttph would appear as https://ln.instagram.com//:sptth With a mirror URL and the U+202E character, an attacker can make any URL look like any other! I call this vulnerability 2K2E Final Result Finally I have a legitimate looking URL that seems like it leads to Instagram, when in fact it leads to my blog Security Is Broken. [svg] Attack Scenario Utilizing both these issues can allow attackers to perform phishing attacks where they construct legitimate looking links that lead to malicious websites. The full attack flow: 1. An attacker purchases the mirror domain of the site they would like to impersonate. For example moc.margatsni.nl to impersonate ln.instagram.com 2. The attacker creates a message with a link to original domain in order to use its preview. 1 { 2 "text": "https://instagram.com/", 3 "matchedText": "https://instagram.com/", 4 "canonicalUrl": "https://instagram.com/", 5 "description": "Create an account...", 6 "title": "Instagram", 7 "jpegThumbnail": {}, 8 "previewType": 0, 9 "mediaKey": {}, 10 "mediaKeyTimestamp": 1693302818542, 11 "thumbnailDirectPath": "/v/t62.36...", 12 "thumbnailSha256": {}, 13 "thumbnailEncSha256": {}, 14 "thumbnailHeight": 1024, 15 "thumbnailWidth": 1024, 16 "inviteLinkGroupTypeV2": 0 17 } 3. The attacker then removes the matchedText property and changes the text property to the following value: U+202E + "URL to the mirror domain" + //:sptth 1 { 2 "text": "\u202ehttps://moc.margatsni.nl//:sptth", 3 "canonicalUrl": "https://instagram.com/", 4 "description": "Create an account...", 5 "title": "Instagram", 6 "jpegThumbnail": {}, 7 "previewType": 0, 8 "mediaKey": {}, 9 "mediaKeyTimestamp": 1693302818542, 10 "thumbnailDirectPath": "/v/t62.36...", 11 "thumbnailSha256": {}, 12 "thumbnailEncSha256": {}, 13 "thumbnailHeight": 1024, 14 "thumbnailWidth": 1024, 15 "inviteLinkGroupTypeV2": 0 16 } 4. Finally the attacker sends the crafted message to their victim Meta's Response Because we support many different platforms and environments, there are a significant number of ways that some platform could choose to normalize a URL differently than our server-side logic does. To address that, we have systems in place which allow us to adjust our URL normalization logic dynamically in the event of real-world spam and abuse. Sadly, Meta has shown no intention to resolve this security issue and from their response it seems that they will try to stop these attacks only if their systems detect them as spam. This means that WhatsApp users can only cross their fingers that they won't fall victims to 2K2E attacks. Apposed to WhatsApp, other platforms such as X, TikTok, and Pinterest, all have sanitization of the U+202E character. Mitigation Because Meta has no intention of fixing this issue, links on WhatsApp cannot be trusted. In order to not fall victim to a 2K2E phishing attack, before clicking on a link, copy it. The clipboard preview should show the link address while sanitizing the U+202E character. Update I have found other services that do not have proper sanitization and are vulnerable to 2K2E as well. * WhatsApp + Shown Above * Facebook + * Android Messages + [svg] * Google Keep (Spreading phishing links via shared note) + * Google Photos (Commenting on shared photos) + Reverse Engineering Phishing ClickJacking This post is licensed under CC BY 4.0 by the author. Share Recently Updated * Physical Security * Bezeq Router Auth-Bypass * Bypassing Router Bootloader Protection * Leaking Credit Card Numbers In A KFC Trending Tags IoT Auth-Bypass Info-Leak AI Backdoor Bootloader ClickJacking Credit-Card DOS Memory-Corruption Contents Further Reading Jul 27, 2020 LG Soundbar DOS I have found a memory corruption that causes DOS in some of LG's soundbars. The details of this vulnerability have been redacted in respect to LG's bug bounty program Jan 23, 2023 Bezeq Router Auth-Bypass Intro I want to share with you a cute little vulnerability I found (CVE-2022-47848). Two models of Bezeq's routers, Vtech NB603-IL and Vtech IAD604-IL are vulnerable to authentication bypass. The v... May 10, 2023 Bezeq Router RCE Intro There is a saying that you don't truly own a router until you root it. So i accepted the challenge with my ISP's router. This is the same router from my previous posts a customized Broadcom B... Bypassing Router Bootloader Protection - Trending Tags IoT Auth-Bypass Info-Leak AI Backdoor Bootloader ClickJacking Credit-Card DOS Memory-Corruption Using the Jekyll theme Chirpy (c) 2023 Zuki (Itay Zukerman). Some rights reserved. By using this site you agree to let third party servies gather anonymous information using cookies. Dismiss