Rust fixme 2
picoCTF Rust fixme 2 Challenge
Challenge description:
The Rust saga continues? I ask you, can I borrow that, pleeeeeaaaasseeeee?
Another challenge in the PicoCTF Rust fixme saga! if you haven’t caught the previous challenge, check it out here.
After copying this project and extracting it, let’s see what happens when we try to run it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
❯ cargo run
Compiling crossbeam-utils v0.8.20
Compiling rayon-core v1.12.1
Compiling either v1.13.0
Compiling crossbeam-epoch v0.9.18
Compiling crossbeam-deque v0.8.5
Compiling rayon v1.10.0
Compiling xor_cryptor v1.2.3
Compiling rust_proj v0.1.0 (/home/slavetomints/training/picoCTF/rust-fixme-2/fixme2)
error[E0596]: cannot borrow `*borrowed_string` as mutable, as it is behind a `&` reference
--> src/main.rs:9:5
|
9 | borrowed_string.push_str("PARTY FOUL! Here is your flag: ");
| ^^^^^^^^^^^^^^^ `borrowed_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
3 | fn decrypt(encrypted_buffer:Vec<u8>, borrowed_string: &mut String){ // How do we pass values to a function that we want to change?
| +++
error[E0596]: cannot borrow `*borrowed_string` as mutable, as it is behind a `&` reference
--> src/main.rs:20:5
|
20 | borrowed_string.push_str(&String::from_utf8_lossy(&decrypted_buffer));
| ^^^^^^^^^^^^^^^ `borrowed_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
3 | fn decrypt(encrypted_buffer:Vec<u8>, borrowed_string: &mut String){ // How do we pass values to a function that we want to change?
| +++
For more information about this error, try `rustc --explain E0596`.
error: could not compile `rust_proj` (bin "rust_proj") due to 2 previous errors
Alrighty, with these error, let’s take a look at the source code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
use xor_cryptor::XORCryptor;
fn decrypt(encrypted_buffer:Vec<u8>, borrowed_string: &String){ // How do we pass values to a function that we want to change?
// Key for decryption
let key = String::from("CSUCKS");
// Editing our borrowed value
borrowed_string.push_str("PARTY FOUL! Here is your flag: ");
// Create decrpytion object
let res = XORCryptor::new(&key);
if res.is_err() {
return; // How do we return in rust?
}
let xrc = res.unwrap();
// Decrypt flag and print it out
let decrypted_buffer = xrc.decrypt_vec(encrypted_buffer);
borrowed_string.push_str(&String::from_utf8_lossy(&decrypted_buffer));
println!("{}", borrowed_string);
}
fn main() {
// Encrypted flag values
let hex_values = ["41", "30", "20", "63", "4a", "45", "54", "76", "01", "1c", "7e", "59", "63", "e1", "61", "25", "0d", "c4", "60", "f2", "12", "a0", "18", "03", "51", "03", "36", "05", "0e", "f9", "42", "5b"];
// Convert the hexadecimal strings to bytes and collect them into a vector
let encrypted_buffer: Vec<u8> = hex_values.iter()
.map(|&hex| u8::from_str_radix(hex, 16).unwrap())
.collect();
let party_foul = String::from("Using memory unsafe languages is a: "); // Is this variable changeable?
decrypt(encrypted_buffer, &party_foul); // Is this the correct way to pass a value to a function so that it can be changed?
}
Okay, so now I see the issue. Whats happening in the decrypt
function is that the borrowed_string
variable is being edited via the push_str
method, which appends a string onto another string.
The first issue is that the borrowed_string
variable isn’t mutable, meaning that the variable’s value can not change. By trying to change its value, we encounter an error during compilation and so the program wont run. We can fix this issue by changing the definition of the variable from borrowed_string: $String
to borrowed_string: $mut String
.
However, this creates a new issue. The new issue with this is that that string that is passed to the borrowed_string
in the function call isn’t mutable either, so we need to make it mutable as well. We can do this by adding the mut
keyword to the variable definition before the variable name, so let party_foul
becomes let mut party_foul
. And then we’ll change how the variable is passed in the main
function so that it is now decrypt(encrypted_buffer, &mut party_foul);
Here’s what the final code should look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
use xor_cryptor::XORCryptor;
fn decrypt(encrypted_buffer:Vec<u8>, borrowed_string: &mut String){ // How do we pass values to a function that we want to change?
// Key for decryption
let key = String::from("CSUCKS");
// Editing our borrowed value
borrowed_string.push_str("PARTY FOUL! Here is your flag: ");
// Create decrpytion object
let res = XORCryptor::new(&key);
if res.is_err() {
return; // How do we return in rust?
}
let xrc = res.unwrap();
// Decrypt flag and print it out
let decrypted_buffer = xrc.decrypt_vec(encrypted_buffer);
borrowed_string.push_str(&String::from_utf8_lossy(&decrypted_buffer));
println!("{}", borrowed_string);
}
fn main() {
// Encrypted flag values
let hex_values = ["41", "30", "20", "63", "4a", "45", "54", "76", "01", "1c", "7e", "59", "63", "e1", "61", "25", "0d", "c4", "60", "f2", "12", "a0", "18", "03", "51", "03", "36", "05", "0e", "f9", "42", "5b"];
// Convert the hexadecimal strings to bytes and collect them into a vector
let encrypted_buffer: Vec<u8> = hex_values.iter()
.map(|&hex| u8::from_str_radix(hex, 16).unwrap())
.collect();
let mut party_foul = String::from("Using memory unsafe languages is a: "); // Is this variable changeable?
decrypt(encrypted_buffer, &mut party_foul); // Is this the correct way to pass a value to a function so that it can be changed?
}
And rerunning it gives us this:
1
2
3
4
5
❯ cargo run
Compiling rust_proj v0.1.0 (/home/slavetomints/training/picoCTF/rust-fixme-2/fixme2)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
Running `target/debug/rust_proj`
Using memory unsafe languages is a: PARTY FOUL! Here is your flag: picoCTF{4r3_y0u_h4v1n5_fun_y31?}
Success!!!
FLAG: picoCTF{4r3_y0u_h4v1n5_fun_y31?}