This proof of concept is focused on the cryptography behind the BEAST (Browser Exploit Against SSL/TLS) attack presented by Thai Duong and Juliano Rizzo on September 23, 2011. This a chosen-plaintext attack and this allow you to retrieve sensitives informations if the Transport Layer Security used is TLS1.0 or SSLv3. The orginal proof of concept can be found here : Here come the Ninjas
Note: This is also an implementation of the vulnerability originally discovered by Phillip Rogaway. Discovered in 2002, there was no exploit released until BEAST in 2011. OpenSSL already knew the problem and this why they updated TLS1.0 to TLS1.1 in April 2006.
2 The CBC IV for each record except the first is the previous records' last ciphertext block. Thus the encryption is not secure against adversaries who can adaptively choose plaintexts;
SSLv3/TLS1.0 are protocols to encrypt/decrypt and secure your data. In our case, they both use the CBC cipher mode chainning . The plaintext is divided into block regarding the encryption alogithm (AES,DES, 3DES) and the length is a mulitple of 8 or 16. If the plaintext don't fill the length, a padding is added at the end to complete the missing space. I strongly advice you to open this images of encryption and decryption to read this readme.
Encryption | Decryption |
---|---|
Ci = Ek(Pi ⊕ Ci-1), and C0 = IV | Pi = Dk(Ci) ⊕ Ci-1, and C0 = IV |
Basically this is just some simple XOR, you can also watch this video (not me) https://www.youtube.com/watch?v=0D7OwYp6ZEc.
I will introduce the IV in the next point. Remember that all this property will help us to drive our attack.
When we use the CBC we need a vector initialisation call IV. This IV is random (or fixed) but in any case it should not be predictable from anyone. In TLS1.0 and SSLv3 the first IV of the request is random, fine. But to gain some time and not generate a new random IV every time, the implemenation of TLS1.0 and SSLv3 used the last block of the previous cipher text has an IV. In other words, the IV is now guessable. We will assume the length of each block will be 8 (DES) and the attacker have a MiTM to retrieve all the cipher.
Example :
C0 | C... | Ci-1 | Ci | Ci+1 |Cn
Now the interesting part, this is the different cryptographic steps of the attack to retrieve one byte :
- first we send a request call C² to get the last block of the cipher meaning the next IV of the second request
- this is a chosen plaintext attack, so the attacker can send this message
bbbbbbbTHIS_IS_A_SECRET_COOKIE
through the victim.
You can notice the seven b
before the secret cookie. If the length of a block is 8 we need to push 7 know bytes. This information is very important, the attacker know the 7 first bytes of the first block.
But why ? This allow us to have only 256 possibilty to find one byte and not 256^8 to find 8 bytes !
Now the victim send the request and it will be encrypted like this :
C0 | C1 | C2 | C3 | C4
Where C0 = Ek(IV ⊕ bbbbbbbT) = Ek(C²n ⊕ bbbbbbbT)
- the attacker want to retrieve the information in the block C0 C1, C2 ... he always need the previous block
- a third request is send after build a special block P'0. The first block will be encrypted like this : C'0 = Ek(P'0 ⊕ IV') Since this is a chosen plaintext attack, the attacker can construct a block P'0 like this :
P'0 = C²n ⊕ C4 ⊕ bbbbbbbX
The only unknow element is X
, there is 256 possibilities so he will try max 256 char.
The request is send and encrypt like this :
C'0 = Ek(P'0 ⊕ IV')
C'0 = Ek(C²n ⊕ C4 ⊕ bbbbbbbX ⊕ IV') or C4 ⊕ IV' = 0
C'0 = Ek(C²n ⊕ bbbbbbbX)
C'0 = Ek(IV ⊕ bbbbbbbX)
Now he compares : C'0 and C0, if they are equal, then he just found the byte X
in position 8. If it doesn't match, he retries with another char and compare again etc.
Now we have one byte we can get another one by shift the previous request by one on the left : bbbbbbTHIS_IS_A_SECRET_COOKIE
. He now have six b
and we also now the T
, so we have one char unknow. We build a new P'0 = C0 ⊕ C4 ⊕ bbbbbbTX etc...
Note: another way with only two request is to set the first block of the plaintext and use this information for the three XOR. We don't need anymore the C² last block. C1 = Ek(C0 ⊕ bbbbbbbT) and then P'0 = C0 ⊕ C4 ⊕ bbbbbbbX. He also need to compare C'0 and C1. This is another way to do it, you can notice in the PoC i code the two possibilities :)
We can now retrieve all the char !
python BEAST-poc.py
An attacker cannot use HTTP protocol because the first block will be field with GET / HTTP/1.1\r\n
.
... cannot control the first few bytes of each request because they are always set as a fixed string such as GET /, POST /, etc. Instead he can use socket.
He also need to inject some javascript into a malicious page. The victim need to be connected to this page and stay during unitl the attack is done. This is a chosen-plaintext attack so the attacker can send through the javascript code every plaintext he wants and intercept the result with a Man in The Middle. This diagram of the attack :
This attack need a important conditions to be successfull (TLS1.0 or inferior, CBC cipher mode, MiTM, malicious javascript). But Thai Duong and Juliano Rizzo proove it can be possible and the demontrate there exploit by stealing cookie on Paypal webiste.
Everythings is now fix and this attack has little probability of being realized.
- http://netifera.com/research/beast/beast_DRAFT_0621.pdf
- http://www.bortzmeyer.org/beast-tls.html
- http://fr.slideshare.net/danrlde/20120418-luedtke-ssltlscbcbeast
- http://crypto.stackexchange.com/questions/5094/is-aes-in-cbc-mode-secure-if-a-known-and-or-fixed-iv-is-used
- http://security.stackexchange.com/questions/18505/is-beast-really-fixed-in-all-modern-browsers
- https://defuse.ca/cbcmodeiv.htm
- http://stackoverflow.com/questions/22644392/chrome-websockets-cors-policy