# ångstromCTF 2020 - Shifter Writeup

Connecting to Shifter we are greeted with the following:

Solve 50 of these epic problems in a row to prove you are a master crypto man like Aplet123!
You'll be given a number n and also a plaintext p.
Caesar shift p with the nth Fibonacci number.
n < 50, p is completely uppercase and alphabetic, len(p) < 50
You have 60 seconds!
--------------------
Shift BXRUJEAKBPSKTXDOXETQV by n=22
:


They give us a number n and a caesar cipher. Easy enough, we can steal the implementations from StackOverflow (or write them ourselves) and do the following:

def get_last_line(text):
return text.split("\n")[-2]

def get_info(line):
l = line.split(" ")
return (l[1], l[-1].split("=")[1])

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while True:
data = s.recv(1024)
if not data:
break
text = data.decode("utf-8")
print(text)
cipher, n = get_info(get_last_line(text))
fN = fib(int(n))
shifted = caesar(cipher, fN)
print(shifted)
s.sendall(bytes(shifted + '\n', 'utf-8'))


fib and caesar are the implementations for Fibonnaci and Caesar cipher, respectively, both taken from some place on the internet, hence not being shown.

Breaking the script down:

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))


The code above will connect us to the challenge, then we just need to receive the buffer and parse it. I used these two functions:

def get_last_line(text):
return text.split("\n")[-2]

def get_info(line):
l = line.split(" ")
return (l[1], l[-1].split("=")[1])


Afterwards we just cast n, calculate it, and shift the given cipher.

Voilá!

actf{h0p3_y0u_us3d_th3_f0rmu14-1985098}
`