LITHP
by k0d14k
LITHP
CTF: Angstrom 2019
Category: misc, rev
Difficulty: Easy-Medium
Description
My friend gave me this program but I couldn’t understand what he was saying - what was he trying to tell me?
address
: https://2019.angstromctf.com/challenges
Solution
This challenge provides us a lisp piece of code containing the encrypted flag and the encryption function.
We need to reverse this snippet to decode the flag.
;LITHP
(defparameter *encrypted* '(8930 15006 8930 10302 11772 13806 13340 11556 12432 13340 10712 10100 11556 12432 9312 10712 10100 10100 8930 10920 8930 5256 9312 9702 8930 10712 15500 9312))
(defparameter *flag* '(redacted))
(defparameter *reorder* '(19 4 14 3 10 17 24 22 8 2 5 11 7 26 0 25 18 6 21 23 9 13 16 1 12 15 27 20))
(defun enc (plain)
(setf uwuth (multh plain))
(setf uwuth (owo uwuth))
(setf out nil)
(dotimes (ind (length plain) out)
(setq out (append out (list (/ (nth ind uwuth) -1))))))
(defun multh (plain)
(cond
((null plain) nil)
(t (cons (whats-this (- 1 (car plain)) (car plain)) (multh (cdr plain))))))
(defun owo (inpth)
(setf out nil)
(do ((redth *reorder* (cdr redth)))
((null redth) out)
(setq out (append out (list (nth (car redth) inpth))))))
(defun whats-this (x y)
(cond
((equal y 0) 0)
(t (+ (whats-this x (- y 1)) x))))
;flag was encrypted with (enc *flag*) to give *encrypted*
whats-this
(defun whats-this (x y)
(cond
((equal y 0) 0)
(t (+ (whats-this x (- y 1)) x))))
We can start from the simplest function in this script. It implements the times operator by summing recursively the y
parameter.
multh
(defun multh (plain)
(cond
((null plain) nil)
(t (cons (whats-this (- 1 (car plain)) (car plain)) (multh (cdr plain))))))
Let’s follow with multh
that invokes whats-this
. Multh is a recursive function which if the plain is empty multiplies the first item of the list before by the previous and then by -1
with these values it creates a couple (x y)
with y = -(x * (x-1)
and x
as an array entry.
If the condition isn’t respected it calls the same function over the other elements of the list.
owo
(defun owo (inpth)
(setf out nil)
(do ((redth *reorder* (cdr redth)))
((null redth) out)
(setq out (append out (list (nth (car redth) inpth))))))
owo
is a simple shuffle function. gets an array and shuffles it with the order given by reorder.
enc
(defun enc (plain)
(setf uwuth (multh plain))
(setf uwuth (owo uwuth))
(setf out nil)
(dotimes (ind (length plain) out)
(setq out (append out (list (/ (nth ind uwuth) -1))))))
In few words enc
just gets the flag, for each character multiplies it (as number) for the previous cardinal number then applies the reorder
array to shuffle it and appends every character to the out
list (that is encrypted
).
Solution
We can easy reverse the encryption function because we have the reorder array and now we now how the encryption works.
So we follow 2 steps:
- reorder the encrypted array
- bruteforce every printable character multiplied by it’s integer value -1
"""
@author K0d14k
Script to solve AngstromCTF 2019 - MISC - LITHP
"""
from string import printable
encrypted = [8930, 15006, 8930, 10302, 11772, 13806, 13340, 11556, 12432, 13340, 10712, 10100, 11556, 12432, 9312, 10712, 10100, 10100, 8930, 10920, 8930, 5256, 9312, 9702, 8930, 10712, 15500, 9312]
reorder = [19, 4, 14, 3, 10, 17, 24, 22, 8, 2, 5, 11, 7, 26, 0, 25, 18, 6, 21, 23, 9, 13, 16, 1, 12, 15, 27, 20]
sortedlist = []
flag = ""
for k, v in sorted(set(zip(reorder, encrypted))):
sortedlist.append(v)
for enc in sortedlist:
for i in printable:
if ord(i) * (ord(i) -1 ) == enc:
flag += i
print(flag)
Flag : actf{help_me_I_have_a_lithp}
Links and tools
LISP Reference
: https://lisp-lang.org/learn
YouTube Lisp tutorial
: https://www.youtube.com/watch?v=ymSq4wHrqyU