What happens when you send a link?
Various stories about malware spreading over SVG files sent on Facebook were circulating over the interwebs lately. You can read more about this vector and the methods used by malicious hackers in this post, but what caught my interest was not the attack itself.
As you probably know, SVG is a vector image format that is, in fact, an XML file containing various drawing instructions and, surprisingly to some, capable of containing and running JavaScript code. For example, when opening in most modern browsers, this SVG will show you a blue circle and run an external script loaded from the redacted host.
This will work only when the browser is explicitly pointed to the SVG file URL or if the file is open from the disk; <img src= does not work anymore for obvious reasons.
So, when this SVG topic has popped up again, this time in the context of poor content filtering in Facebook Messenger, I instinctively thought about privacy implications introduced by this (apparently inefficient) security measure. I thought it could be a good idea to use JavaScript code delivered in SVG to check how modern instant messengers process this file format.
After a series of messages sent to my wife and colleagues, I feel a subtle hope that I will not be banned from using the messengers I’ve tested. And, of course, I have some results to share.
The good news is that Signal, Viber, WhatsApp, and both Facebook Messenger and Telegram in their “secret” modes, all five claiming end-to-end encrypted communications, were not caught cheating. Although in WhatsApp and Telegram, pasted URLs resulted in some activity originating from the client, no one else appeared in the web-server logs.
Bad news is that that’s pretty much all good news.
Starting from expected obvious: Slack does an active preview of the linked content to show it in the GUI. That’s cool; we all know that, so I use it as an example of how this kind of activity looks like for this post. So, when you send a link, the web-server serving it registers this request in the log:
54.89.92.4 — — [21/Nov/2016:16:02:31 +0000] “GET /avakl.js HTTP/1.1” 404 152 “-” “Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)"
Where 54.89.92.4 of course is a Slack instance in Amazon AWS:
$ whois 54.89.92.4 | grep Organization
Organization: Amazon Technologies Inc. (AT-88-Z)
Let’s take a look how other messengers deal with the links.
Skype sends 6 requests from 2 hosts, both belonging to Microsoft directly. A rich company can afford that.
23.101.61.176 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
23.101.61.176 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
23.101.61.176 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
23.101.61.176 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
104.45.18.178 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
104.45.18.178 — — [21/Nov/2016:15:38:44 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5”
Telegram fetches the image once, form it’s directly owned network.
149.154.167.163 — — [21/Nov/2016:15:35:18 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “TelegramBot (like TwitterBot)”
$ whois 149.154.167.163 | grep -E ‘^descr|^person|^address’
descr: Telegram Messenger Network
person: Nikolai Durov
address: P.O. Box 146, Road Town, Tortola, British Virgin Islands
descr: Telegram Messenger Amsterdam Network
The URL sent via Facebook Messenger on mobile results in four requests from different addresses.
31.13.102.98 — — [21/Nov/2016:19:44:51 +0000] “GET /avakl.svg HTTP/1.1” 206 328 “-” “facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
173.252.120.119 — — [21/Nov/2016:19:44:52 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
173.252.123.130 — — [21/Nov/2016:19:44:53 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
173.252.123.129 — — [21/Nov/2016:19:45:12 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “-” “facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
Facebook kindly explains its behavior by provided URL.
However, when the link is sent via Facebook web-site, look what happens:
31.13.113.194 — — [21/Nov/2016:15:11:58 +0000] “GET /avakl.svg HTTP/1.1” 206 328 “-” “facebookexternalhit/1.1”
66.220.145.243 — — [21/Nov/2016:15:12:01 +0000] “GET /avakl.svg HTTP/1.1” 200 328 “https://l.facebook.com/lsr.php?u=https%3A%2F%2F*******%2Favakl.svg&ext=1479741420&hash=AcnhtJ5F7tKqGD-kIHGSbCF0-TflNMaiR9WNCxHznoOqJw" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:01 +0000] “GET /kl.js HTTP/1.1” 200 283 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:01 +0000] “GET /favicon.ico HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:03 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:04 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:05 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:06 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:07 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
66.220.145.243 — — [21/Nov/2016:15:12:08 +0000] “GET /keylogger? HTTP/1.1” 404 152 “https://*******/avakl.svg" “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0”
As you can see, first, some Facebook-owned host fetches the SVG, and after that, there is a series of requests to “embedded” script URL, which demonstrates that the script is actually run at some “browser.”
Strangely enough, Google Hangouts haven’t shown any sign of interest in my links.
This leaves a lot of questions open. However, one thing is obvious: privacy policies are correct, and we don’t really own the stuff we send over Instant Messengers unless our comms are encrypted end-to-end.
During these tests I used awesome JavaScript keylogger by John Leitch.