Diga não à Volatilidade Juvenil
”An oracle is an individual who knows the personal cell phone number of a
god. This enables him (or her) to obtain some information which is usually
considered as out of reach of mere mortals, such as glimpses of the future. In
cryptography, that's the same, except that no deity is involved: an oracle is any
system which can give some extra information on a system, which otherwise
would not be available.”
[Link]
”An Oracle is a system that knows the secret key and the algorithm used to
decrypt some data that you have but don’t know what means. Generally these
data are provided by the application and, as you don't know the secret key, the
application expects the guarantee of the integrity and confidentiality of the
data.”
My poor definition (-:
• Logical Operator as ⊕
• Used in programming languages as ^
• Used in Digital Systems as XOR Gate:
A B A⊕B
0 0 0
0 1 1
1 0 1
1 1 0
A B A⊕B
0 0 0
0 1 1
1 0 1
1 1 0
A 0 1 0 0 1 1 0 1 7710
B 0 0 1 1 1 0 0 1 5710
A⊕B 0 1 1 1 0 1 0 0 11610
A B A⊕B
0 0 0
0 1 1
1 0 1
1 1 0
A 0 1 0 0 1 1 0 1 7710
B 0 0 1 1 1 0 0 1 5710
A⊕B 0 1 1 1 0 1 0 0 11610
A⊕A 0
A B A⊕B A⊕1 ~A
0 0 0 A⊕0 A
0 1 1 A⊕B B⊕A
1 0 1 (A ⊕ B) ⊕ C A ⊕ (B ⊕ C)
1 1 0 (A ⊕ B) ⊕ B A ⊕ (B ⊕ B) = A ⊕ 0 = A
(A ⊕ B) = C A⊕C=B
B⊕C=A
A 0 1 0 0 1 1 0 1 7710
B 0 0 1 1 1 0 0 1 5710
A⊕B 0 1 1 1 0 1 0 0 11610
• P → Decrypted plaintext
• C → Encrypted ciphertext
• Pn / Cn → plaintext/ciphertext of the block n (nth block)
• N → Number of blocks
• IV → Initialization Vector (a random string)
• E() → Single block encryption function
• D() → Single block decryption function
C1 = E(P1 ⊕ IV)
C2 = E(P2 ⊕ C1)
C3 = E(P3 ⊕ C2)
…
Cn = E(Pn ⊕ Cn-1)
[Link]
C1 = E(P1 ⊕ IV)
C2 = E(P2 ⊕ C1)
C3 = E(P3 ⊕ C2)
…
Cn = E(Pn ⊕ Cn-1)
[Link]
P1 = D(C1) ⊕ IV
P2 = D(C2) ⊕ C1
P3 = D(C3) ⊕ C2
…
Pn = D(Cn) ⊕ Cn-1
[Link]
P1 = D(C1) ⊕ IV
P2 = D(C2) ⊕ C1
P3 = D(C3) ⊕ C2
…
Pn = D(Cn) ⊕ Cn-1
[Link]
– Defined by RFC 2315
– Padding described on the Section 10.3
[Link]
– Defined by RFC 2315
– Padding described on the Section 10.3
[Link]
– Defined by RFC 2315 ”ABCDEFGHIJ”
– Padding described on the Section 10.3
[Link]
– Defined by RFC 2315 ”ABCDEFGHIJ”
– Padding described on the Section 10.3
A B C D ….
41 42 43 44 45 46 47 48 49 4A
[Link]
– Defined by RFC 2315 ”ABCDEFGHIJ”
– Padding described on the Section 10.3
A B C D ….
41 42 43 44 45 46 47 48 49 4A
data Padding
10 bytes 6 bytes
[Link]
– Defined by RFC 2315 ”ABCDEFGHIJ”
– Padding described on the Section 10.3
A B C D ….
41 42 43 44 45 46 47 48 49 4A
data Padding
10 bytes 6 bytes
A B C D ….
41 42 43 44 45 46 47 48 49 4A 06 06 06 06 06 06
[Link]
– Defined by RFC 2315 ”ABCDEFGHIJ”
– Padding described on the Section 10.3
A B C D ….
41 42 43 44 45 46 47 48 49 4A
data Padding
10 bytes 6 bytes
A B C D ….
41 42 43 44 45 46 47 48 49 4A 06 06 06 06 06 06
[Link]
A B C D ….
41 42 43 44 45 46 47 48 49 4A 06 06 06 06 06 06
data Padding
10 bytes 6 bytes
[Link]
A B C D ….
41 42 43 44 45 46 47 48 49 4A 06 06 06 06 06 06
data Padding
10 bytes 6 bytes
41 42 43 44 45 46 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A
data Padding
6 bytes 10 bytes
[Link]
A B C D ….
41 42 43 44 45 46 47 48 49 4A 06 06 06 06 06 06
data Padding
10 bytes 6 bytes
41 42 43 44 45 46 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A
data Padding
Padding 16 bytes
6 bytes 10 bytes
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
data
16 bytes
[Link]
• An application that implements an Oracle cryptography system.
– The application trust in a data sent encrypted to the client side (a.k.a. the
attacker), and try to decrypt it when get it back.
• If something goes wrong (e.g. padding error), the application should inform the
client.
• Let’s assume the following padded plaintext Pn with N blocks:
• Let’s assume the following padded plaintext Pn with N blocks:
P1 P2 P3 P4 … Pn-2 Pn-1 Pn
data
N x 16 bytes
• Let’s assume the following padded plaintext Pn with N blocks:
P1 P2 P3 P4 … Pn-2 Pn-1 Pn
data
N x 16 bytes
• After the encryption, we will have the following ciphertext Cn for the last block:
Cn[0] Cn[1] Cn[2] Cn[3] Cn[4] Cn[5] Cn[6] Cn[7] Cn[8] Cn[8] Cn[9] Cn[A] Cn[B] Cn[C] Cn[D] Cn[E] Cn[F]
Encrypted data
16 bytes
• Where Cn[x] is the xth byte in the last ciphertext block.
• To perform the attack, we need only the ciphertext (spitting on blocks):
• To perform the attack, we need only the ciphertext (spitting on blocks):
• Create a new ciphertext block (C’) with random data (usually zero filled):
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
• To perform the attack, we need only the ciphertext (spitting on blocks):
Cn[0] Cn[1] Cn[2] Cn[3] Cn[4] Cn[5] Cn[6] Cn[7] Cn[8] Cn[8] Cn[9] Cn[A] Cn[B] Cn[C] Cn[D] Cn[E] Cn[F]
• Create a new ciphertext block (C’) with random data (usually zero filled):
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
• We create a new ciphertext making the concatenation (||) operation between the original
ciphertext block and the ciphertext block we just created:
• C = C’ || Cn
C’ Cn
16 bytes 16 bytes
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
• The application server decrypt it:
• P1 = D(C’) ⊕ IV
• P2 = D(Cn) ⊕ C’
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
• The application server decrypt it:
• P1 = D(C’) ⊕ IV Garbage!
• P2 = D(Cn) ⊕ C’
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
• The application server decrypt it:
• P1 = D(C’) ⊕ IV Garbage!
• P2 = D(Cn) ⊕ C’
• We already know that:
• Cn = E(Pn ⊕ Cn-1)
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
• The application server decrypt it:
• P1 = D(C’) ⊕ IV Garbage!
• P2 = D(Cn) ⊕ C’
• We already know that:
• Cn = E(Pn ⊕ Cn-1)
• So…
• P2 = D(E(Pn ⊕ Cn-1)) ⊕ C’
• P2 = Pn ⊕ Cn-1 ⊕ C’
• What happened when we send back to the application server the C ciphertext?
C’ Cn
16 bytes 16 bytes
After rewriting
• The application server decrypt it:
• P1 = D(C’) ⊕ IV Garbage! Pn = P2 ⊕ Cn-1 ⊕ C’
• P2 = D(Cn) ⊕ C’ UNKNOWN KNOWN
• We already know that:
• Cn = E(Pn ⊕ Cn-1)
• So…
• P2 = D(E(Pn ⊕ Cn-1)) ⊕ C’
• P2 = Pn ⊕ Cn-1 ⊕ C’
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
??? ??? Ok Ok
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
??? ??? Ok Ok
Brute-force
01 .. FF
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
??? ??? Ok Ok
0x01 Brute-force
01 .. FF
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
??? ??? Ok Ok
Padding Ok Brute-force
0x01
01 .. FF
• We have:
Pn = P2 ⊕ Cn-1 ⊕ C’
• As the XOR operation is bitwise, we can simplify the formula applying it only on the last kth char:
Pn[k] = P2[k] ⊕ Cn-1[k] ⊕ C’[k]
??? ??? Ok Ok
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
Padding Ok Brute-force
0x01
01 .. FF
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We can fixe the last char in 0x02 with:
C’[k] = 0x02 ⊕ Pn[k] ⊕ Cn-1[k]
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We can fixe the last char in 0x02 with:
C’[k] = 0x02 ⊕ Pn[k] ⊕ Cn-1[k]
• We following the same approach to look for the padding ”\x02\x02”
Pn[k-1] = P2[k-1] ⊕ Cn-1[k-1] ⊕ C’[k-1]
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We can fixe the last char in 0x02 with:
C’[k] = 0x02 ⊕ Pn[k] ⊕ Cn-1[k]
• We following the same approach to look for the padding ”\x02\x02”
Pn[k-1] = P2[k-1] ⊕ Cn-1[k-1] ⊕ C’[k-1]
Brute-force
01 .. FF
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We can fixe the last char in 0x02 with:
C’[k] = 0x02 ⊕ Pn[k] ⊕ Cn-1[k]
• We following the same approach to look for the padding ”\x02\x02”
Pn[k-1] = P2[k-1] ⊕ Cn-1[k-1] ⊕ C’[k-1]
0x02 Brute-force
01 .. FF
• We already know:
Pn[k] = 0x01 ⊕ Cn-1[k] ⊕ C’[k]
• We can fixe the last char in 0x02 with:
C’[k] = 0x02 ⊕ Pn[k] ⊕ Cn-1[k]
• We following the same approach to look for the padding ”\x02\x02”
Pn[k-1] = P2[k-1] ⊕ Cn-1[k-1] ⊕ C’[k-1]
Padding Ok Brute-force
0x02
01 .. FF
• Remote oracle running on [Link]:1043
Maycon Maia Vitali
Maycon@[Link]
Thank you