Writing Vulnerable Code On Purpose

Hello,

I'm working as security researcher and just started to learn rust.

I want to simulate a buffer overflow vulnerability with Rust for educational purpose.

Is it possible to write a vulnerable code on purpose ?

Also following code can be compiled :

fn main() {
let data = [1, 2, 3, 4, 5];
let index = 10;
println!("The value of element is: {}", a[index]);
}

However when it run, I want it to write some string at *data + 10 in the memory.

Thank you.

You cannot do this in safe code, by design, it will be detected and lead to a panic at runtime. You must use unsafe methods like ptr::write or get_unchecked_mut for this kind of purpose.

(and then the compiler may do curious things with your code in optimized builds under the assumption that out-of-bounds array accesses cannot happen, such as deleting the entire program, which I guess is what you are looking for)

6 Likes

One of the first things one learns about Rust is that one has to go out of ones way to create buffer overruns and such memory use errors in Rust. Indeed that is, too a large part, why one is interest in Rust in the first place. How did you miss this major fact?

If you really want to I guess creating a security vulnerability by leaking data could be done quite easily.

Imagine:

  1. Your program defines a nice big vector as buffer for data traveling through the system.
let buffer: Vec<u8> = vec![1024];
  1. Somewhere your program reads user input into that buffer, including passwords, keys, whatever secret stuff. The input data does not fill the buffer.

  2. Somewhere your program outputs that data, perhaps as a slice.

What if the size of that slice being output is bigger than the amount of data the user input? Now you are outputting some unknown junk at the end of the buffer?

What if that unknown junk is actually the password, key, secret stuff from some previous user whose data passed through that buffer?

I have already done something like that when reading/writing to a serial port. I was getting a lot of junk in my serial output till I realized I was outputting an entire buffer rather than a slice of the correct length.

I'm sure someone here could craft a good example.

Actually, here is my potential security vulnerability function:

fn serial_rx_to_nats(port: &mut BoxSerial, nats_client: &mut nats::Client) -> BoxResult<()> {
    let mut buffer: Vec<u8> = vec![0; 1024];

    // Send data from serial to NATS forever
    loop {
        if let Ok(length) = port.read(&mut buffer.as_mut_slice()) {
            if length > 0 {
                nats_client.publish("radar", &buffer)?;
            }
        }
    }
}

Spot the problem?

So there is no compile option for this. Thank you very much.

That is why i interest with Rust even if i'm not a programmer.

The question is if there is any force method to tell rust compiler to do not make security checks. Like fstack-protector in GCC.

1 Like

We should not confuse the memory safety, thread safety, type safety, out of range checks of Rust with "security checks". They are very different things.

Certainly mistakes in memory usage in C/C++ etc are the cause of many security vulnerabilities, but there many security issues that are outside that set. As my example above shows.