CTF Tasks with Clojure

Using clojure where it is not normally used

Introduction

It might not come as a surprise, but Clojure is one of my most favorite programming language. Although I love the language I never used it while participating in a CTF to solve challenges. This is mainly due to the difficulty of working with things like hex numbers, which you need to do often in CTFs.

So I decided to give it some effort and start developing tools when I run into challenges. Today I did a CTF challenge that required a xor of a list of bytes. So here we go.

String XORring

So, the fist thing to know is to convert an integer to a hex number is not something that is part of the language. In order to do it, the integer has to be formatted as a hexidecimal using format. That will result in a string of the hexidecimal number. The string is then converted using symbol to be an actual byte.

(defn int->hex
  "Function that int as argument and returns a symbol hex representation of the number.

For example the number 115 is 0x73 hexidecimal"
  [int]
  (symbol (format "0x%02x" int)) )

Using this technique a flag can be encoded using a key. By using a map vector each character of the flag is matched with a character from the key, so it would result in a list of pairs such as [\A \s] for the A from the flag and the s from the key. Obviously in this situation the key has to be as long or longer then the flag that is to be encoded.

The list of pairs is then mapped into a bit-xor and its result is converted to hexidecimal. A list of hexidecimals is the result of this map, and the input for our decoding function.

;; Creating a key
(map (fn [[a b]] (int->hex (bit-xor (int a) (int b))))
     (map vector
          "ARJEN{flag}"
          "supersecretkey"))
;; => (0x32 0x27 0x3a 0x20 0x3c 0x08 0x03 0x0f 0x13 0x02 0x09)

As it is very common to map a key to some sequence of bytes to xor them I created a function to do just this. The rather lengthy name xor-byte-list->string does exactly that, it takes a list of bytes and xors it with a key (a string). It uses the same technique as above with map vector.

(defn xor-byte-list->string [byte-list xor-key]
  ;; Decoding a key
  (apply str
         (map (fn [[a b]] (char (bit-xor a (int b))))
              (map vector byte-list xor-key))))

(xor-byte-list->string 
 '(0x32 0x27 0x3a 0x20 0x3c 0x08 0x03 0x0f 0x13 0x02 0x09)
 "supersecretkey")

;; => "ARJEN{flag}"

Other hex related functions

I keep a list of other hex related functions handy. Some I have copied over from the internet somewhere in the past such as this wonderful post on alternatives to Python’s encode('hex') functions.

(defn str->hex [s]
  (apply str
    (map #(format "0x%02x" (int %)) s)))

(defn int->hex [i]
  (format "0x%02x" i) )


(defn hexify [s]
    (apply str
      (map #(format "%02x" (int %)) s)))

  (defn unhexify [hex]
    (apply str
      (map 
        (fn [[x y]] (char (Integer/parseInt (str x y) 16))) 
        (partition 2 hex))))

  (hexify "Clojure")
  ;; ⇒ "436c6f6a757265"

  (unhexify "436c6f6a757265")
  ;; ⇒ "Clojure"