Friday, 6 October 2017

How to try to predict the output of Micali-Schnorr Generator (MS-DRBG) knowing the factorization

The article was modified since its publication. Last update was 09/10/2017 

tl;dr in this post we are going to describe how to try predict the output of Micali-Schnorr Generator (MS-DRBG)  knowing the factorization of the n value. If this sounds like, "why the hell should I care?", you might want to give a look at this great post from Matthew Green about the backdoor in Dual_EC_DRBG. But In a nutshell, quoting Matthew Green :
What I am NOT claiming in this post though is that there is a backdoor in one of this standard.


The first time I heard about this problem is about couple of weeks ago via this Matthew's tweet:
From there I could "track" the challenge that he launched to enthusiastic mathematician.

Mind that I am yes enthusiastic but not a mathematician, but I still decided to accept the challenge :p
And yeah it looks like it took be about two weeks to (partially) solve the riddle.

Micali-Schnorr Generator (MS-DRBG)

So now I "accepted" this challenge, but Hey I do not even know that this Micali-Schnorr Generator (MS-DRBG) existed, so time to study. Googling a bit I found out that other people tried this previously but did not succeed ( I guess), not a good sign, but let's do not this discourage us. The best place where I found the explanation for the Micali-Schnorr Generator was this short pdf (while other books and online resource described it as well).
Trying to keep it simple the MS-DRBG given a number n and an RSA exponent e will output a sequence of bits. The slides from NIST explains this in a really simple way:

The logic behind this is extremely trivial, you start from a secret seed s (this is the internal state of the DRBG) and you will use the n and the e from the standard to do a classic RSA encryption aka (s)^e mod (n) then you will:
  • output the less significant bit of (s)^e mod (n)
  • and you keep  the most significant bit as the new state for the subsequent iteration
Well that is basically it. Now that we know better MS-DRBG I hope the question from Matthew results simpler, but basically he was asking: will the knowledge of the factorization of n give an advantage such being able to recover the internal state of the DRBG ? To be fair answering no to this question  would be extremely counter intuitive. At the end of the day RSA is completely bound to the secretiveness of the factorization of n and this DRBG is totally RSA, this was what really puzzled me. It must be something but what?
One little thing to note is that it seems that the original definition from Micali and Schnorr and the NIST's  standard differ from the number of bit they output. 
The NIST standard is much more conservative and outputs about 1/3 of the RSA computation. While it seems that the original version outputs up to 3/4 of the RSA computation and keeps only 1/4 for the internal state (well this give still 128 bits to recover, still pretty many...).
Well well the second version seems easier, so let's start simple.

Predict the output 

Ok now I know the problem statement but I still need to solve it. Let's see a bit of literature. For a reason that hopefully I clarify in another post, thanks to Brian Smith,  I came to know the Handbook of Elliptic and Hyperelliptic Curve Cryptography book. This book isn't only about elliptic curves (the reason why I bought this book BTW) but it also contains explanation of basic algorithms. My initial though was really simple. If I know the factorization of n say I know n = p * qI can maybe somehow use the most lethal weapon any cryptographer can use: the Chinese Remainder Theorem (CRT). I successfully used myself a couple of times already [0] and [1]. So what I thought is that in any moment I will have the less significant bit of (s)^e mod (n) and the factorization of n = p* q. The idea is really simple: if I can somehow obtain (s)^e mod(p) and (s)^e mod (q) from this partial knowledge I can finally obtain the full  (s)^e mod (n) using CRT!!!!!
So I opened the Handbook of Elliptic and Hyperelliptic Curve Cryptography book at the modular reduction part and I was "attracted" by the Special moduli section. I almost immediately discarded Mersenne primes

from Handbook of Elliptic and Hyperelliptic Curve Cryptography
from Handbook of Elliptic and Hyperelliptic Curve Cryptography
because the lack of the 2^128,2^520 interval (the one interesting for cryptography). But turning page I got an "illumination", it talked indeed about Crandall primes of the form p = b^k +c and described an algorithm for reduction for special form moduli

from Handbook of Elliptic and Hyperelliptic Curve Cryptography
from Handbook of Elliptic and Hyperelliptic Curve Cryptography

Well bingo, looks like is really what I need. Now assuming p and q are both Crandall primes and p = 2^ 256 + c1 amd q = 2^ 256 + c2.

Lets split a bit the algorithm and comment on it:

  • q0 = is half unknown (128 bits) and half known (1/3 of the DRBG output, the most significant bits)
  • r0 = is the 2/3 of the DRBG output, the less significant bits.
Now is also important to know this:

from Handbook of Elliptic and Hyperelliptic Curve Cryptography
 This is actually again out case. So lets continue:

qi+1 amd ri+1 are going to be really easy to predict for us (giving the fact we have the DRBG 128 most significant bits of the output).
Lets see how. So we said we know the less significant bit of q0 that are equal to the 1/3 of the DRBG output, the most significant bits.
Now decoding the algorithm above notation:

  • qi+1 = c1 * q0 and taking the 2^256 most significant bits (this is usually a really small number for the instance of our problem namely some bits.
  • ri+1 = c1 * q0 and taking the 2^256 less significant bit. This can also be written as  c1 * q0 (mod 2^256). Hold on but we have most of this already (is enough to multiply the part of q0 that we know for c1) apart few bits (again the instance of our problem namely some bits).
This will allow us to recover (s)^e mod(p). If we repeat the same using c2 will allow us to recover (s)^e mod(q). Than CRT and ...

...and that is basically it. I hope you enjoyed as much as I enjoyed thinking about this riddle.
We will provide a much more deeper analysis of this with a some code showing this in the next post.

EDIT: I spotted an issue on my program that invalidates so far my results. I am going to continue working on it though and maybe solve the issue. Or I hope this post will inspire someone else to work on this really great problem.

Predict the output (updated)

So as said above I spotted an issue on my program that invalidates so far my results. But hey not all of them :p (I hope).
Basically I still claim some less exiting result. Indeed using the technique based on Crandall's primes above I clam that I can predict ~ the 128 less significant bits of (s)^e mod(p) and (s)^e mod (q). If you still do not believe me here is the gist with a POC you can run*:

Now while this is not revolutionary this result is new to me. In order to have a rough idea of why this actually works (most of the time) let see how binary multiplication actually works. The article from Wikipedia contains a good example:

As you see the less significant bits of the result depends only on the less significant bits of the second term. 

Now decoding the Crandall's algorithm notation:
  • qi+1 = c1 * q0 and taking the 2^256 most significant bits (this is usually a really small number if c1 is small).
  • ri+1 = c1 * q0 and taking the 2^256 less significant bit. This can also be written as  c1 * q0 (mod 2^256). Hold on but we know the 128 less significant bits of the second term, and as shown above this means we can also predict the 128 less significant bits of this result.

Now the question is: would knowing the ~ the 128 less significant bits of (s)^e mod(p) and (s)^e mod (q) help to recover the internal state of the DRBG?


I would like to thank Matthew Green to give me such a good puzzle :) and Brian Smith for letting me know about  the Handbook of Elliptic and Hyperelliptic Curve Cryptography book.

That's all folks. For more crypto goodies, follow me on Twitter.

* I am aware the p and q are not suited for RSA but this is just an example.

Wednesday, 9 August 2017

CVE-2017-7781/CVE-2017-10176: Issue with elliptic curve addition in mixed Jacobian-affine coordinates in Firefox/Java

tl;dr Firefox and Java suffered from a moderate vulnerability affecting the elliptic curve point addition algorithm that uses mixed Jacobian-affine coordinates where it can yield a result POINT_AT_INFINITY when it should not.


Few months ago I was working on a vulnerability affecting the internet standard JWE (slides here) and I got a stroke of luck. Yuppieeee  Basically I was constructing the malicious JWEs needed for the Demo Attack. When something weird happened :S
You can try and share with me the surprise I had, the gist is here

If you try to execute this class with Java 1.7 you basically have

Exception in thread "main" java.lang.IllegalStateException
    at Method)
    at javax.crypto.KeyAgreement.generateSecret(
    at orig.EccJava.getAgreedKey(
    at orig.EccJava.main(

😲 Wait, what? Ok I know, obviously not clear. Let's step back and slowly move forward.

Invalid curve attack on elliptic curve

In order to understand what is going on here you need to be knowledgeable about elliptic curves and invalid curve attack on them. I tried to give some explanation in the already mentioned post.
Said that let come back to the gist above. Why so much surprise about this java.lang.IllegalStateException ?
As mentioned, in order to exploit the JWE vulnerability present in many libraries, I was crafting malicious JWEs. One of the steps involved to construct an invalid curve somehow related to the famous P-256 curve. One of the malicious curve I came out with for the demo attack had the really low order of 2447.  Hence the attack required me to build 2447 malicious JWEs something like:

G = base point of the invalid curve;
for (i = 1; i<2447; i ++) {
    P = i * G; 

All was going pretty well until arrived to the point 2417 (this is basically the gist above) in the loop  BOOM:

Exception in thread "main" java.lang.IllegalStateException

This happened back in March while I was working on the JWE's disclosure. I was extremely surprised to see this Exception!! Why an apparently innocuous normal scalar multiplication was throwing this Exception??? This made me really really curious but unfortunately I did not have time to explore this more deeply. So I simply decided to temporary park it and come back to it having more time.

Elliptic curve point addition in mixed Jacobian-affine coordinates

So once the disclosure was out and after taking few week of rest I was ready to dig deeper this issue. First thing I did was to download the OpenJDK source code and started inspecting. 
After quite a bit of investigation I ended up here:

At the same time I found out that for some reason NSS (hence Firefox) shares the same code base with OpenJDK (for elliptic curve cryptography). Then I found this:

Continue surfing through the code looking for the usage I found the algorithms used were taken from:
/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
 * curve points P and R can be identical. Uses mixed Modified-Jacobian
 * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
 * additions. Assumes input is already field-encoded using field_enc, and
 * returns output that is still field-encoded. Uses 5-bit window NAF
 * method (algorithm 11) for scalar-point multiplication from Brown,
 * Hankerson, Lopez, Menezes
. Software Implementation of the NIST Elliptic
 * Curves Over Prime Fields. */
Cool. Let's look at this Brown et al paper.  Here it is:

Oh boy but this is exactly what is implemented in the code so what is wrong? All seems legit... :S Hold on a sec, what is happening if C = X2 Z1^2  -  A is equal to zero ? It must be something wrong here... Of course it is. Got it, the if/else block is missing as per here

Holy Elliptic Curve Batman, so instead of doubling a point the algorithm returns POINT_AT_INFINITY!!


OK, now we know what is wrong, but what is special about 2417? Why this is not happening with 2416 or 1329 instead? The reason why the issue is triggered goes along this lines:

Basically at a certain point of the algorithm (toward the end, remember it uses 5-bit window NAF) needs to do 2432 -15 = 2417 . Now 2432 = -15 mod (2447) so ==> -15 -15 and BOOOM rather than double the point the algorithm returns point at infinity....!!

Right. Next natural question: is this something special about this invalid curve* or this can be reproduced with any curve (e.g. a standard curve)?

With another bit of tweaking I came out with a P-521 example (hence even the last patched version of Java was affected):

Cool, and now? Can we exploit this in some way and recover any private key? The reality is PROBABLY NOT :( Believe me, I have tried hard to exploit this stuff but nothing, niente, nada, niet, nisba! At least for the classic ECDH where the private key is not under attacker's control. Maybe this could be exploited if this very same code is employed to implement some other more "exotic" protocol (e.g. PAKE) ? In any case, the comment section of the blog is open and my Twitter DM is open, so hit me up if you have any idea.....

Disclosure timeline

Apr-2017 - Reported to Mozilla security team.
Apr-2017 - Reported to Oracle security team.
Jul-2017 - Oracle Critical Patch Update Advisory - July 2017 (CVE-2017-10176), fix here
Aug-2017 - Mozilla Foundation Security Advisory 2017-18 (CVE-2017-7781), fix here


I would like to thank the Oracle and Mozilla team for the constant and quick support specially to Franziskus Kiefer.

That's all folks. For more crypto goodies, follow me on Twitter.

 Java SUN JCA provider that comes with Java later than version 1.8.0_51 are not affected by invalid curve attacks since they check for point on the curve.

Tuesday, 8 August 2017

Analisi dei dump di Rousseau (Movimento Cinque Stelle) - Parte I: password


Questo blog post e' scritto da evariste.gal0is ed Antonio Sanso. Entrambi gli autori non hanno nessuna affiliazione politica ed il post ha l'unico scopo di fornire un'analisi tecnica di parte dei dump relativa alle password.

Riassunto delle puntate precedenti

In data 2 agosto 2017 uno dei coautori di questo blog post  (evariste.gal0is) ha segnalato
una severa vulnerabilita' (del tipo SQL injection) che affligeva la piattaforma del Movimento Cinque Stelle chiamata Rousseau: . La sua segnalazione riceve una notevole copertura mediatica e minacce di querela da parte del  Movimento Cinque Stelle* (cosa che spinge  evariste.gal0is a prendere temporaneamente una pausa). Nel frattempo un black hat hacker che si fa chiamare rogue0 viola nuovamente la piattaforma
e mette in vendita i dati degli utenti
Link agli articoli giornalistici qui e qui.

Ma secondo Di Maio il problema e' la sicurezza informatica dell'Italia (non l'incompetenza di chi ha creato la piattaforma)

I dump e le password

Come detto i dump  rilasciati da rogue0 contengono un po' di tutto (nomi, cognomi, date di nascita, indirizzo, e chi piu' ne ha piu' ne metta...) degli iscritti alla piattaforma. In questo post ci concentreremo pero' solo sulle password. Piccola parentesi, a quante pare alcune (o tutte) le password usate su sono salvate in "chiaro" (aka salvate verbatim nel database)!!! Questo come spiegato qui e' un errore di sicurezza grossolano.
Nel caso di Rousseau non sembra sia il caso che le password siano salvate in "chiaro" (per fortuna) :

Queste password sono chiaramante non in cleartext, ma in che modo sono conservate allora? Visto cosa fatto su, le speranze che gli autori della piattaforma abbiano adottato delle misure decenti (e.g. bcrypt, Argon2, Scrypt o il piu' classico salt+hash) per la protezione delle password appaiono remote. Ma procediamo....
Citando questo articolo, secondo Riccardo Meggiato il software utilizzato probabilmente per Rousseau si chiama Movabletype. Vediamo se riusciamo a trovare qualche riscontro relativo alle password:

Mmmmm diamo un'occhiata a questo file

La funzione set_password sembra interessante. Sembra usare SHA1 o SHA512 per conservare le password. Non male direi (benche' non ottimo). Ma sara' cosi per Rousseau? Prendiamo una password a caso:  LViSE5785tkGA

Acqua, mancato, non sembra corrispondere ad un output SHA1 o SHA512.
Forse Riccardo Meggiato si sara' sbagliato.  Aspetta un attimo non sara' forse che hanno usato una versione un po' piu' vecchia di Movabletype. Proviamo la versione piu vecchia disponibile (4.2x):

Sembra promettente, ma cosa e' crypt? Scrollando un po sotto:

Set the I<$author> password with the perl C<crypt> function.

Ok perl C<crypt>. Vediamo:
Creates a digest string exactly like the crypt(3) function in the C library (assuming that you actually have a version there that has not been extirpated as a potential munition).

Crypt (3)

Crypt(3) e' una funzione di derivazione di chiave a dir poco preistorica (del 1980!!!) e facilmente craccabile che usa un altro algoritmo palesemente obsoleto: DES!!!!  Ma davvero Rousseau usa questo algoritmo? Vediamo il formato di LViSE5785tkGA sembra corrispondere. Chiediamo al nostro amico John the Ripper

Bingo! Ci ha messo ben 12 secondi per trovare la password :D !!!!


  • La piattaforma del Movimento Cinque Stelle (Rousseau) sembra davvero usare una versione obsoleta di Movabletype 
  • Le password sono  conservato usando una funzione facilmente craccabile che risale alla preistoria informatica: Crypt(3)
Stay tuned: Evariste & Antonio

Se vuoi saperne di piu' sulle falle della piattforma Rousseau seguici su Twitter: evariste.gal0is ed asanso

* questo dimostra quanto l'Italia sia indietro rispetto alle altre nazioni riguardo la segnalazione di vulnerabilita' informatiche

Wednesday, 21 June 2017

Historical courses and resorts in Elliptic Curves Cryptography - Is Curve25519 dead?

tl;dr This short blog post serves to me to recollect some of the thing I have been learning (climbing) about Elliptic Curves Cryptography (ECC from now on) during the last months/years, so please take it with a grain of salt since it might contains some erroneous beliefs.

'80 - Introduction

Giambattista Vico  was an Italian political philosopher and rhetorician, historian and jurist, of the Age of Enlightenment famous (also) for the concept of historical courses and resorts. This can be resumed with: "some events are repeated in the same way even after a long time; and this is not by chance". Well it seems that this might also applies to ECC so he maybe he was right :)
Elliptic Curve made its first appearance in cryptography with Lenstra in 1984 (eventually published in 1987). Curiously enough he introduced them not while trying to come up with a new crypto system but he employed EC in order to factor integers (a side note, there is a really beautiful survey about the number factorization problem by the great Carl Pomerance). Then it did not take long for Neal Koblitz and independently (as often happens in science) Victor S. Miller to connects the dots and coming with a brand new crypto system that translated the Diffie Hellman technique from finite field to EC.  Clearly the main advantage claimed back then (and it looks that this still stands 30 years later) is that EC are immune to index-calculus attacks.
Great starting points to learn ECC are :

'90 - ECC NIST Standard

Fast forward to the '90s when NIST standardized some EC.  The EC in the standard were in the form

y^2 = ax^3 + ax + b

that are so called Weierstrass curves. This is a really classic shape of elliptic curve.
Weierstrass curve
The formulas used for this curves are derived from the work done by the Chudnovsky brothers and as we will see shortly might not be the most efficient. The complete formulas are somehow complicated and on top is not easy to implement constant time algorithm for those curves (unless replace all that code with curve specific, constant-time code). This paper from Brown,Hankerson, Lopez, Menezes shows several optimizations that can be done for NIST's elliptic curves.
One important thing to remember for the sake of this blog post is that this kind of curves have a minimum cofactor of 1, hence the might have a prime order (like all the NIST curves). 
One thing to take care when implementing EC is to employ point validation, in order to avoid invalid curve attacks (see the recent Critical vulnerability in JSON Web Encryption for an example ).
So far so good. For many years did not gain too much popularity among the practitioners, probably due patent related worryings.

'00 - DJB curves

In 2006 djb published the famous Curve25519 paper. In this work he leverages some work done by Montgomery, the so called (unsurprisingly) Montgomery curve. A Montgomery curve comes in the form:

by^2 = x^3 + ax^2 + x

A Montgomery curve is different from the usual Weierstrass form:

Montgomery curve

but it turns out that constitute ≈25% of all elliptic curves.  The main advantages of using such curve shapes are:

  • Speed: a single scalar multiplication is very simple and fast (it can leverage the so called Montgomery Ladder)
  • Side-channel resistance: the Montgomery Ladder is not only fast but is also side-channel resistant,
  • Security: one peculiarity of Montgomery Ladder is that the output is guaranteed to be either on the curve or on its twist. So if a curve is chosen to be twist secure there is no risk to fall into the invalid curve trap seen above.
In his paper djb introduced a new Montgomery Curve (Curve 25519) that contained all the goodies listed above (see also djb and Tanja talk at 31c3 or visit to visit for details).

But as this wasn't still enough goodies, as djb explains in the The first 10 years of Curve25519 talk, while him and Tanja moved in the Netherlands they discovered Edwards (and twisted Edwards) curves.

Edward curve

And they immediately got the idea to employ those new object for signing starting from Schnorr signature (this became eventually the Ed25519 signature system). Now it turns out that every Montgomery Curve is bi-rationally equivalent to a twisted Edward curve (in particular: Curve25519).
Beautiful, right? Yes indeed but but but ... there is a little caveat: Montgomery Curves have a  minimum cofactor of 4 (Curve 25519 has cofactor 8). We will see shortly how this is relevant...

'10 - Historical courses and resorts

Gradually ECC was better understood (also some patents expired) and ECC grew up popularity together (also) within mobile devices (EC arithmetic is way faster since it uses way less bits). Also the majority of TLS connections are now served using ECDHE (we probably need to thank Snowden for this). Together with EC also djb curves gain more and more popularity mainly due to two reasons:
  • Curve 25516 has all the goodies listed above
  • People have more confidence on djb than NIST
But in the last months/days we started to see some cracks on djb's castle. The first signal of something happening was JP's blog post about Curve25519's validation that caused some debate on the curve mailing list (all is beautifully summarized in  this post).
Second we started to see some catastrophic failures (about 1.000.000 $!!!!!) related to curve having cofactor > 1 (is also true that CryptoNote employed a rather exotic flow without a proper understanding of the underlying primitive, but still).
It appears clearly that what it seems to be a settled (by djb et al) problem is actually not (at all).
Lately the curve mailing list is full of discussion about:
and as Isis says in another curve mailing list thread"... To say that cofactors are annoying would be putting it mildly! ..".
Now I am not saying this is the end of  Curve25519 and/or Montgomery Curve BUT lately the great Prof. Barreto proposed a new curve that is prime order and a Weierstrass curve.
This made me thinking, is  Prof. Barreto right? Should we go back to Weierstrass curves? Aka ending as we started with Vico

Historical courses and resorts in Elliptic Curves Cryptography 


That's all folks. For more crypto goodies, follow me on Twitter. 

Tuesday, 30 May 2017

Cross-origin brute-forcing of Github SAML and 2FA recovery codes

Yesterday while reading my Twitter stream I found this interesting article about  downloading GitHub SSO bypass codes. Same as Yasin Soliman I was invited to a Github pre-release of the organisation SAML single sign-on (SSO) private program. And same as him I found an issue in the same endpoint. So I thought to write a quick blog post about it.
Github already published a tl;dr about this,

 I will try to fill the blanks here.

As mentioned by Yasin, Github offers an endpoint where privileged users can recover bypass codes. These recovery codes were accessible for download as plaintext and had the content-type as text/plain , something like:

What immediately caught my attention was that the format of the code forms (with some exceptions) a valid JavaScript file with lines in the format of XXXXX-XXXXX, ten hex digits separated by a hyphen. This is interpreted in JavaScript as the subtraction of two variables! This remember an old blog post of mine where I could possibly exfiltrate information from properties file formatted in a peculiar way. And another great blog post: Plain text considered harmful: A cross-domain exploit.
So I thought I could do something similar here. It did not take long until I found the right approach.

Caveat #1: also in this case Github sets the X-Content-Type-Options: nosniff to prevent browsers from interpreting this content as valid JavaScript or other file types. But while Firefox now added support for nosniff the browser compatibility is still spotty (I am looking at you Safari!!).

But without waiting any further HERE is the live POC. The nut of the trick is to define a valueOf function for the corresponding variable:

and enumerate them all!!

Caveat #2: We are talking about enumerating/brute-forcing 5 hex digit variables that requires a considerable effort, but is far from be unfeasible. A rough calculation tells us that we need to define about 16^5 variables that are about 1048576!

Caveat #3: not all the codes are valid Javascript variable (e.g. the one starting with a number are not). For a random hexadecimal digit that's six out of sixteen, thus a 37.5% chance.

Disclosure timeline 

06-03-2017 - Reported the issue via Hackerone.
07-03-2017 - Github triaged the issue. 
16-03-2017 - Bounty awarded


I would like to thank the Github security  team, you guys rock, really!!

Well that's all folks. For more Javascript trickery follow me on Twitter.

Friday, 5 May 2017

OAuth Worm II - The revenge

We all know about this massive Google Doc Phishing Attack that hit about 1 million accounts right?

Image from
Well this really "sophisticated attack" (really??) was based on a really spread Internet procol named OAuth. It also turns out that during the early stage of the standardization someone reported this very own attack vector but as often happens he was ignored. 

Back in 2015 I also reported another "hidden feature"

 of OAuth that turns an OAuth server into an open redirector that makes phishing a piece of cake.

Yesterday I was twitting about this and today I decided to imitate Eugene Pupov (lol) and work on my master thesis project. So this is the resulting mail. Have fun:

Fret not, go ahead and click and you will be redirected to:

that is not a Github page but is rather controlled by me.

Well that's all folks. For more OAuth phishing follow me on Twitter

P.S. for the record me and some other folks from the OAuth working group proposed a draft  (3 years ago!!!) that should close this open redirector. Let's see.


Thursday, 20 April 2017

Meh : CSRF in Facebook Delegated Account Recovery

Note this is going to be a quick post.

This year, at Enigma 2017 Conference, Facebook introduced a way to move Account Recovery beyond Email and the "Secret" Question.
After the presentation the moved operationally and presented the first integration partner : Github.

These days I have seen a lot of press around this and both Facebook and Github open sourced their implementation and specification (also presented at F8).
Well it turned out that Facebook side was susceptible to Cross Site Request Forgery.
Really simple explanation:

<img src="">

Then is enough for the victim to visit and will have a new Github Token of the attack under

You might said: nice but whats the threat here?
Indeed is exactly what Facebook replied. Despite it they fixed the issue adding an additional confirmation page.

For the record the threat here is a Login CSRF to a Github account that is kind of

That's all folks. For more Meh follow me on Twitter.

Monday, 10 April 2017

CSRF in Facebook/Dropbox - "Mallory added a file using Dropbox"

tl;dr  Facebook Groups offers the option to upload files directly from the Dropbox account. This integration is done using the OAuth 2.0 protocol and suffered from a variant of the classic OAuth CSRF (defined by Egor Homakov as the the Most Common OAuth2 Vulnerability),  see video below:


 Facebook Groups offers the option to upload files directly from the Dropbox account:

This will allow to surf via browser the Dropbox account 

and post a specific file to the group. 
This integration is done using a variant of the OAuth 2.0 protocol seen in this blog many many times. But once more, OAuth is an access delegation protocol standardized under the IETF umbrella. A typical OAuth flow would look like:
From “OAuth 2 In Action” by Justin Richer and Antonio Sanso, Copyrights 2017

Usually the client initiates the OAuth flow in the following way:

From “OAuth 2 In Action” by Justin Richer and Antonio Sanso, Copyrights 2017

then after that the resource owner has authorized the client the authorization server redirects the resource owner back to the client with an authorization code:
From “OAuth 2 In Action” by Justin Richer and Antonio Sanso, Copyrights 2017

Then the OAuth dance continues....

Facebook/Dropbox integration

In the Facebook/Dropbox integration Dropbox is the client while Facebook is Authorization/Resource server.

The flow is a pretty standard OAuth flow with an exception. Being Dropbox the client he would be in charge of initiate the dance, but the reality is:

Indeed is Facebook that initiates the flow doing:

Everything else is as supposed to be:

CSRF in OAuth 2

The eagle-eye reader will sure notice that the initiation link, aka

lacks one really important piece (in OAuthland) namely the state parameter. This parameter is, according to the OAuth core specification:

An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery (CSRF).

The best way to see this CSRF account in action is through a picture:

From “OAuth 2 In Action” by Justin Richer and Antonio Sanso, Copyrights 2017
You can also find a great introduction to this attack in the the Most Common OAuth2 Vulnerability by Egor Homakov. 

CSRF in Facebook/Dropbox integration

Before to describe the specific attack we need to highlight one really important thing. The classic protection against CSRF in OAuth (aka the use of the state parameter) would not work in this case. The reason is due the fact that, as we have seen already, the flow is initiated "weirdly" by Facebook and not Dropbox. So there is no way to have Dropbox checking that the right state parameter is bounced back. So wazzup? The attacker will forge a page with a malicious link (containing his own authorization code) in

<img src="
#_=_" />

and after the victim visits this address his Dropbox upload file post will be done with the name of the attacker!! See:

But wait a second, why this is actually the case? Well it turns out that it was a strange issue in Dropbox and the access token was cached indefinitely. So once the crafted authorization code was bound with the victim resource owner than no matter a legit authorization code was actually employed, Dropbox will not trade it and continue to use the old malicious access token to post the file to Facebook!!

Disclosure timeline

Little rant. Reporting integration issues is always a challenge. Is not always clear who the culprit is. In this case the culprit was clearly Dropbox while the victim was Facebook. The paradox was the being Dropbox not affected by the issue it was not extremely interested to hear about this issue. On the Facebook side even if they were clearly the target they could not do much without the help of Dropbox. And me ? Well I was right in the middle :)

13-01-2017 - Reported to Facebook security team.
14-01-2017 - Reported to Dropbox security team via  Hackerone.

Dropbox part I 

15-01-2017 - Dropbox replied: "This is a bug in Facebook's use of our API rather than the Dropbox API itself."
15-01-2017 - I replied to Dropbox saying: "Is not Facebook using Dropbox API but it is quite the opposite."
15-01-2017 - Dropbox replied: "I will take a look again and reopen if we decide its valid." and -5 points!!!!!!!!
15-01-2016 - While I do not care too much about those point I replied to Dropbox saying: having -5 points reputation for this is rather frustrating.....
15-01-2016 - Dropbox reopened the report and closed as Informative (so got +5 points back :))


from 20-01-2017  to 25-02-2017 - Back an forth between me and Facebook in order to have them to reproduce the issue.
25-02-2017 - Facebook closed the issue saying: "We're able to reproduce the behavior you described, but this may be an issue on the Dropbox side (in particular the /fb/filepicker endpoint) which we do not control."
04-03-2017 - Asked Facebook if there is any chance they can contact Dropbox and explain the situation.

Dropbox part II 

07-03-2017 - Reported (once more) to Dropbox security team via Hackerone.
22-03-2017 - Dropbox rewarded asanso with a $1,331 bounty.

10-04-2017 - Public disclosure. 


This was quite a ride with an happy end eventually! I would like to thank the Facebook and Dropbox security teams and specially Neal Poole from Facebook Security.

That's all folks. For more OAuthy goodies, follow me on Twitter.

If you like OAuth 2.0 and/or you want to know more about it here you can find a book on OAuth that Justin Richer and myself have been writing on the subject.