From b35d2a76409d266c2bd8e7ecf271dec688649fbd Mon Sep 17 00:00:00 2001 From: mudasir <96320211+mud-ali@users.noreply.github.com> Date: Thu, 6 Jun 2024 23:11:47 -0400 Subject: [PATCH] rev/crabby (#64) * rev/crabby * fix container origin * solvepath + jack up point value * i think u need this to deploy correctly --------- Co-authored-by: glacialcascade <11969863+glacialcascade@users.noreply.github.com> --- crabby/Dockerfile | 35 +++++++++++++++++++++++++++++++++++ crabby/chall.yaml | 24 ++++++++++++++++++++++++ crabby/flag.txt | 1 + crabby/rust/Cargo.toml | 8 ++++++++ crabby/rust/src/main.rs | 26 ++++++++++++++++++++++++++ crabby/server/main.py | 21 +++++++++++++++++++++ crabby/solve.txt | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 151 insertions(+) create mode 100644 crabby/Dockerfile create mode 100644 crabby/chall.yaml create mode 100644 crabby/flag.txt create mode 100644 crabby/rust/Cargo.toml create mode 100644 crabby/rust/src/main.rs create mode 100644 crabby/server/main.py create mode 100644 crabby/solve.txt diff --git a/crabby/Dockerfile b/crabby/Dockerfile new file mode 100644 index 00000000..38b6a628 --- /dev/null +++ b/crabby/Dockerfile @@ -0,0 +1,35 @@ +FROM rust:1-slim-buster AS builder + +WORKDIR /app + +RUN apt-get update \ + && apt-get install -y pkg-config libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY rust/Cargo.toml . + +WORKDIR /app/src + +COPY rust/src . + +WORKDIR /app + +RUN cargo build --release + + +FROM python:3.12-slim-bookworm AS server + +WORKDIR /app + +COPY --from=builder /app/target/release/crabby . + +WORKDIR /app/server + +COPY server/main.py . +COPY flag.txt .. + +RUN pip install flask + +EXPOSE 7787 + +ENTRYPOINT [ "python3", "main.py"] diff --git a/crabby/chall.yaml b/crabby/chall.yaml new file mode 100644 index 00000000..319c2937 --- /dev/null +++ b/crabby/chall.yaml @@ -0,0 +1,24 @@ +name: Crabby +categories: + - rev +value: 125 +flag: + file: ./flag.txt +description: |- + I asked somebody to open source a specific project, but they're being very crabby about it. + Instead, they sent me this binary and said "Everything is open source if you can read assembly". + + I can't read assembly, can you help me out? +hints: [] +files: + - src: /app/crabby + dest: crabby + container: web +authors: + - Mudasir +visible: true +deploy: + web: + build: . + expose: 7787/tcp + diff --git a/crabby/flag.txt b/crabby/flag.txt new file mode 100644 index 00000000..9711904e --- /dev/null +++ b/crabby/flag.txt @@ -0,0 +1 @@ +bcactf{h0W_Ru$7ic_f5ui3roifj354uybr823} \ No newline at end of file diff --git a/crabby/rust/Cargo.toml b/crabby/rust/Cargo.toml new file mode 100644 index 00000000..26d2181b --- /dev/null +++ b/crabby/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "crabby" +version = "0.1.0" +edition = "2021" + +[dependencies] +reqwest = { version = "0.12", features = ["json"] } +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/crabby/rust/src/main.rs b/crabby/rust/src/main.rs new file mode 100644 index 00000000..c525240d --- /dev/null +++ b/crabby/rust/src/main.rs @@ -0,0 +1,26 @@ +#[tokio::main] +async fn main() -> Result<(), Box> { + let shared_secret : &str = "null"; + let _private : &str = &gpwd(); + let url : &str = "http://localhost"; + let port : &str = "7787"; + let resp = reqwest::Client::new() + .post(url.to_owned()+":"+port+"/flag") + .header("Authorization", shared_secret) + .send() + .await? + .text(); + println!("{:?}", resp.await?); + Ok(()) +} + +fn gpwd() -> String { + let vals = "99 50 57 116 90 86 57 122 100 88 66 108 99 108 57 122 90 87 78 121 90 88 82 102 97 50 86 53 88 51 82 108 101 72 82 102 97 71 86 121 90 81 61 61" + .split(" ") + .map(|x| x.parse::().unwrap()); + let mut res = String::new(); + for val in vals { + res.push(val as char); + } + res +} \ No newline at end of file diff --git a/crabby/server/main.py b/crabby/server/main.py new file mode 100644 index 00000000..23ec5226 --- /dev/null +++ b/crabby/server/main.py @@ -0,0 +1,21 @@ +from flask import Flask, request, jsonify +import base64 + +app = Flask(__name__) +SECRET = base64.b64encode(b"some_super_secret_key_text_here") + +FLAG = "bcactf{f4ke_flag}" + +with open("../flag.txt", "r") as f: + FLAG = f.read().strip() + +@app.route('/flag', methods=['POST']) +def flag(): + data = request.headers.get("Authorization").encode() + if data == SECRET: + return jsonify({"flag": f"{FLAG}"}) + return jsonify({"error": "Unauthorized"}), 401 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=7787) \ No newline at end of file diff --git a/crabby/solve.txt b/crabby/solve.txt new file mode 100644 index 00000000..a8f1d7d2 --- /dev/null +++ b/crabby/solve.txt @@ -0,0 +1,36 @@ +(solvepath written by a total Rust noob. someone actually +competent will probably have a much different solvepath) + +Running the binary (after installing openssl-1.1 to get libssl.so +if necessary) returns some error about a HTTP request. We can +see that the request is to localhost:7787/flag, so we presume we +will need to access /flag on the remote server. + +Use a executable decompiler to open the given binary. + +After doing some digging, we find two functions in the +crabby namespace, namely gpwd and main. + +gpwd seems to do some things with this string, +"99 50 57 116 90 86 57 122 100 88 66 108 99 108 57 122 90 87 78 121 90 88 82 102 97 50 86 53 88 51 82 108 101 72 82 102 97 71 86 121 90 81 61 61" + +Converting from decimal, we get +"c29tZV9zdXBlcl9zZWNyZXRfa2V5X3RleHRfaGVyZQ==" + +and "some_super_secret_key_text_here" from Base64. +That seems pretty important! + +Looking into the references of crabby::gpwd throughout +the binary, we find a function that makes many calls to +the reqwest:: namespace, so it's likely the one sending the +HTTP request. + +Later in this function, we see that it runs Client::post +from reqwest, adds some sort of Authorization header, and +sends the reqwest. + +Someone more familiar with Rust rev than me can probably tease +out what exactly's going on with gpwd(), but we can piece together +what the program's doing. The correct way to solve the challenge +is to send a POST request to /flag with the Authorization header +set to "c29tZV9zdXBlcl9zZWNyZXRfa2V5X3RleHRfaGVyZQ==". \ No newline at end of file