018e2a5948cd024526ede01fba3eed4a25472f02
2 use std
::io
::TcpStream
;
3 use std
::iter
::range_inclusive
;
4 use std
::slice
::bytes
::copy_memory
;
7 use packet
::PacketType
::Error
;
8 use end_point
::EndPoint
;
10 /// Tries to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port.
11 /// May print some messages on stdout.
12 pub fn decipher(address
: &str, port
: u16, original_xor_operand
: &[u8, ..16], cipher_block
: &[u8, ..16], variant
: packet
::Variant
) -> Option
<Vec
<u8>> {
13 let mut end_point
= EndPoint
::new(
14 match TcpStream
::connect((address
, port
)) {
17 println!("Unable to connect to the oracle on [{}]:{}", address
, port
);
24 // Sees 'packet::Packet' documentation for a complete description about the binary packet structure.
25 let mut final_packet
= [0u8, ..2 + 1 + 8 + 32 + 10];
26 final_packet
[1] = (final_packet
.len() as u8) - 2; // Data length.
27 copy_memory(final_packet
.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipher_block
);
29 let mut decipher_block
= [0u8, ..16]; // The result.
30 let mut x_prime_block
= [0u8, ..16]; // The cipher block ('cipher_block') after AES and before XOR.
31 let mut current_timestamp
= 0u64;
32 let mut first_byte
= 0u8; // Used to save the first byte for the first iteration.
35 fn forged_xor_operand(packet
: &mut [u8]) -> &mut [u8] { packet
.slice_mut(2 + 1 + 8, 2 + 1 + 8 + 16) }
40 let mut get_mac_mismatch_error
= false; // For the first byte we need to insure there is only one AUTH error (one valid padding).
42 for v
in range_inclusive(0u8, 255) { // For each values of the current byte.
44 // Computes and writes timestamp.
45 current_timestamp
+= 2;
47 let mut timestamp_writer
= io
::BufWriter
::new(final_packet
.slice_mut(2 + 1, 2 + 1 + 8));
48 let _
= timestamp_writer
.write_be_u64(current_timestamp
- 1);
51 forged_xor_operand(&mut final_packet
)[byte
] = v
;
53 match end_point
.send_raw_with_result(&final_packet
) {
54 Ok(Ok(p @ Packet
{ t
: Error(packet
::ErrorType
::Auth
), .. })) => {
55 println!("We received a MAC Error: {}", p
);
57 // If we already got a MAC mismatch for the first byte then
58 // the second byte is incremented and the main loop is replayed for the first byte.
59 if byte
== 15 && get_mac_mismatch_error
{
60 forged_xor_operand(&mut final_packet
)[14] += 1;
64 get_mac_mismatch_error
= true;
66 let padding_value
= 16 - byte
;
67 x_prime_block
[byte
] = v ^
(padding_value
as u8);
68 decipher_block
[byte
] = x_prime_block
[byte
] ^ original_xor_operand
[byte
];
70 // We set the processed bytes of the forged XOR operand to have the next padding value (2, 3, 4, etc..).
71 for i
in range(16 - padding_value
, 16) {
72 forged_xor_operand(&mut final_packet
)[i
] = x_prime_block
[i
] ^
((padding_value
as u8) + 1);
75 // Special case for the first byte: we have to test all the values to avoid a valid padding
76 // which is not [.., 0x01], for instance [.., 0x02, 0x02]. It's a very rare case but not impossible.
78 first_byte
= forged_xor_operand(&mut final_packet
)[15];
83 Ok(Ok(Packet
{ t
: Error(packet
::ErrorType
::Crypt
), .. })) => (), // Ignored case: the padding is wrong.
85 println!("Unexcepted response, aborting. {}", other
);
92 forged_xor_operand(&mut final_packet
)[15] = first_byte
;
95 // It was the last byte.
96 if byte
== 0 { break; }
101 Some(decipher_block
.to_vec())