fn do_oracle_attack(address: &str, variant: packet::Variant) {
// 16 bytes encrypted data from 'Packet::random_packet_data([4])'.
- let cipher_block: [u8, ..16] = [254, 9, 228, 149, 60, 42, 165, 34, 233, 75, 112, 57, 37, 9, 116, 103]; // Known by the attacker.
- let xor_operand: [u8, ..16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]; // This is the IV or the previous 16 bytes cipherblock. In our case we took the IV.
+ let cipher_block = [191, 192, 149, 84, 202, 163, 109, 230, 173, 249, 170, 248, 83, 60, 228, 111]; // Known by the attacker.
+ let xor_operand = [213, 29, 217, 187, 93, 103, 76, 129, 233, 142, 98, 83, 69, 50, 97, 91]; // This is the IV or the previous 16 bytes cipherblock. In our case we took the previous block.
+ let expected_clear_block = [242, 93, 12, 22, 8, 164, 4, 77, 200, 120, 189, 71, 75, 189, 2, 2]; // To be found by the attacker.
- let expected_clear_block: [u8, ..16] = [44, 92, 31, 98, 220, 84, 226, 53, 58, 94, 45, 25, 242, 6, 199, 1]; // To be found by the attacker.
+ /* Another sample with an IV instead of a previous block.
+ let cipher_block: [u8, ..16] = [254, 9, 228, 149, 60, 42, 165, 34, 233, 75, 112, 57, 37, 9, 116, 103];
+ let xor_operand: [u8, ..16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]; IV.
+ let expected_clear_block: [u8, ..16] = [44, 92, 31, 98, 220, 84, 226, 53, 58, 94, 45, 25, 242, 6, 199, 1];
+ */
match oracle_machine::decipher(address, PORT, &xor_operand, &cipher_block, variant) {
Some(ref deciphered) if deciphered.as_slice() == expected_clear_block => {
}
}
+fn print_usage() {
+ println!(
+ r"{} [genkey | tests | oracle-weak | oracle-fixed]
+ genkey: Generate a 256 bits key
+ tests: launch some tests between a client and a weak server
+ oracle-weak: launch a padding oracle attack against a weak server
+ oracle-fixed: launch a padding oracle attack against a fixed server",
+ os::args()[0]
+ );
+}
+
enum Mode {
Help,
ServerAlone,
}
}
-fn print_usage() {
- println!(
- r"{} [genkey | tests | oracle-weak | oracle-fixed]
- genkey: Generate a 256 bits key
- tests: launch some tests between a client and a weak server
- oracle-weak: launch a padding oracle attack against a weak server
- oracle-fixed: launch a padding oracle attack against a fixed server",
- os::args()[0]
- );
-}
-
fn main() {
let mode = mode();
use end_point::EndPoint;
/// Try to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port.
-/// May print some message on stdout.
-pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cipherblock: &[u8, ..16], variant: packet::Variant) -> Option<Vec<u8>> {
+/// May print some messages on stdout.
+pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cipher_block: &[u8, ..16], variant: packet::Variant) -> Option<Vec<u8>> {
let mut end_point = EndPoint::new(
match TcpStream::connect(address, port) {
Ok(s) => s,
// See 'packet::Packet' documentation for a complete description about the binary packet structure.
let mut final_packet = [0u8, ..2 + 1 + 8 + 32 + 10];
final_packet[1] = (final_packet.len() as u8) - 2; // Data length.
- copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipherblock);
+ copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipher_block);
let mut decipher_block = [0u8, ..16]; // The result.
- let mut x_prime_block = [0u8, ..16]; // The cipher block ('cipherblock') after AES and before XOR.
+ let mut x_prime_block = [0u8, ..16]; // The cipher block ('cipher_block') after AES and before XOR.
let mut current_timestamp = 0u64;
let mut first_byte = 0u8; // Used to save the first byte for the first iteration.
Ok(Ok(p @ Packet { t: Error(packet::AuthError), .. })) => {
println!("We received a MAC Error: {}", p);
- // If we already got a MAC mismatch for the first byte then the second byte is incremented and the loop is replayed.
+ // If we already got a MAC mismatch for the first byte then
+ // the second byte is incremented and the main loop is replayed for the first byte.
if byte == 15 && get_mac_mismatch_error {
forged_xor_operand(&mut final_packet)[14] += 1;
continue 'main_loop;
_ => ()
}
- // Compute the MAC. It depends the choosen variant.
+ // Compute the MAC. It depends of the choosen variant.
let mac = crypto::compute_mac(data.slice_to(match variant { Weak => data_size, _ => data.len() }));
// Encrypt.
+@article {authenticated-encryption-bellare-namprempre,
+ author = "M. Bellare and C. Namprempre",
+ title = "Authenticated Encryption: Relations among notions and analysis of the generic composition paradigm",
+ journal = "UC San-Diego",
+ year = "2007",
+ url = "\url{http://cseweb.ucsd.edu/~mihir/papers/oem.html}"
+}
+
@misc {wiki-replay-attack,
author = "Wikipedia",
title = "Replay attack --- {W}ikipedia{,} The Free Encyclopedia",
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Simulation du protocole}
-\subsection{Utilisation du code}
+\subsection{Utilisation du programme}
+
+Le code est écrit en langage Rust \footnote{\url{http://www.rust-lang.org}} et utilise le système de build \emph{Cargo} qui est livré en standard. Il est conseillé d'installer la version \emph{nightly} disponible ici : \url{http://www.rust-lang.org/install.html}.
+
+Pour construire et lancer l'application il faut se trouver dans le dossier contenant le fichier \emph{Cargo.toml} et lancer la commande suivante.
+
+\begin{lstlisting}
+$> cargo run -- <args>
+\end{lstlisting}
+
+Où \emph{<args>} peut valoir :
+
+\begin{itemize}
+ \item \emph{genkey} : génère une clef de 256 bits. Utilisé initialement pour définir la clef d'authentification $K_{a}$ et la clef de chiffrement $K_{c}$ ;
+ \item \emph{tests} : effectue un certain nombre de tests pour vérifier le comportement du serveur vis-à-vis du protocole ;
+ \item \emph{oracle-weak} : effectue une attaque sur la première version du serveur ;
+ \item \emph{oracle-fixed} : effectue une attaque sur la version corrigé du serveur.
+\end{itemize}
+
\subsection{Structure du code}
+Le code est structuré en quatre modules :
+
+\begin{itemize}
+ \item \emph{crypto} : fournit les primitives de chiffrement, déchiffrement, calcul du MAC. Utilise un binding \emph{Rust} vers \emph{OpenSSL} ;
+ \item \emph{packet} : définit le format des paquets et permet leur sérialisation et dé-sérialisation ;
+ \item \emph{end\_point} : permet la création de serveurs et de clients et gère la communication sur \emph{TCP/IP} ;
+ \item \emph{oracle\_machine} : implémente l'attaque par padding-oracle.
+\end{itemize}
+
+
\subsection{Quelle est la stratégie recommandée en pratique parmi les trois listées ci après ?}
\begin{itemize}
\item \emph{Encrypt-then-MAC} : $Enc(M)|MAC(Enc(M))$.
\end{itemize}
+D'après \cite{wiki-authentication-encryption} la stratégie \emph{Encrypt-then-MAC} est la plus sûre dans le cadre de chiffrage authentifié. L'article de \emph{M. Bellare and C. Namprempre} \cite{authenticated-encryption-bellare-namprempre} évalue ces trois stratégies.
+
+
\subsubsection{Quelle stratégie est utilisée par \emph{TLS} ?}
\emph{TSL} utilise la deuxième version (\emph{MAC-then-Encrypt}). À noté que le \emph{MAC} est optionnel.
\subsection{Remarques concernant la sécurité de notre protocole}
-TODO
+A priori nous n'avons pas choisi la stratégie la plus recommandée en terme de sécurité. Comme nous le verrons par la suite, ce protocole est vulnérable à une attaque de type \emph{padding-oracle}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Historique de l'attaque par oracle à l'aide du remplissage}
-TODO
+L'attaque original a été publié en 2002 par \emph{Serge Vaudenay}. En 2010, cette attaque a été mise en pratique contre plusieurs frameworks web tel que \emph{JavaServer Faces}, \emph{Ruby on Rails} et \emph{ASP.NET}. En 2012, il a été montré qu'elle est efficace contre certain appareils hardware.
+
+Il existe une nouvelle variante, publiée en 2013, nommée \emph{the Lucky Thirteen attack}, permettant d'attaquer des implémentations ayant été corrigées. En février 2013, les personnes en charge des implémentations de \emph{TLS} travaillaient à la réalisation d'un correctif à cette attaque.
+Cette section est largement inspirée de l'article de \emph{Wikipedia} sur la \emph{padding-oracle attack} \cite{wiki-padding-oracle-attack}.
\subsection{Explication de l'attaque pour notre cas}
Une subtilité existe pour la recherche du premier octet, il est possible que le paquet d'erreur \emph{AuthError} correspond, avec une faible probabilité, à un autre bourrage que \emph{[0x01]}. Pour prévenir ce cas il faut, pour ce premier octet, envoyer un paquet de commande pour toutes les valeurs de $F_{1}$ et compter le nombre de paquet d'erreur \emph{AuthError} reçu. Si ce nombre est égal à 1 alors on peut passer à $b'$, sinon il faut recommencer en modifiant $F_{2} = (F_{2} + 1) mod 256$.
+Le code correspondant à cette attaque peut être exécuté par la commande suivante :
+
+\begin{lstlisting}
+$> cargo run --release -- oracle-weak
+\end{lstlisting}
+
\subsection{Calcul de la complexité moyenne de l'attaque en terme de nombre de requête effectué auprès de l'oracle}
Sans prendre en compte la particularité du premier octet illustré à la section précédente, la complexité moyenne pour le décryptage d'un bloc de 16 octets est de $16 * 256 / 2 = 2048$ requêtes.
-Dans le cas présenté dans le code, le nombre de requête est de 1795.
+Dans l'exemple présenté dans le code, le nombre de requête est de 2099. La durée d'exécution est de ~0.180 ms, ça relative longueur est certainement dû à l'overhead des couches \emph{TCP/IP}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Description}
+Le correctif proposé consiste à authentifier également le bourrage et non-plus que les données. Cela a pour conséquence de vérifier en premier l'authenticité du contenu avant de procéder à la validité du padding. Les deux messages d'erreur, \emph{CryptError} et \emph{AuthError}, font toujours partis du protocole.
+
+Le code correspondant à ce correctif peut être exécuté par la commande suivante :
+
+\begin{lstlisting}
+$> cargo run --release -- oracle-fixed
+\end{lstlisting}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Conclusion}
+TODO
+
+
+
+
-%http://crypto.stackexchange.com/a/205
-%https://en.wikipedia.org/wiki/Malleability_%28cryptography%29
\bibliographystyle{plain}
\bibliography{main}