PicoCTF - New Caesar

PicoCTF - New Caesar

tags: PicoCTF CTF Crypto

Challenge: New Caesar

Source code

::: spoiler source code

import string

LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16]

def b16_encode(plain):
	enc = ""
	for c in plain:
		binary = "{0:08b}".format(ord(c))
		enc += ALPHABET[int(binary[:4], 2)]
		enc += ALPHABET[int(binary[4:], 2)]
	return enc

def shift(c, k):
	t1 = ord(c) - LOWERCASE_OFFSET
	t2 = ord(k) - LOWERCASE_OFFSET
	return ALPHABET[(t1 + t2) % len(ALPHABET)]

flag = "redacted"
key = "redacted"
assert all([k in ALPHABET for k in key])
assert len(key) == 1

b16 = b16_encode(flag)
enc = ""
for i, c in enumerate(b16):
	enc += shift(c, key[i % len(key)])
print(enc)

:::

Recon

  1. Hint in the code It gave two hints in the code that represented by assert 1.1 The key must in the first 16 character of alphabet strings, that is, the key is composed of a~p. 1.2 The key length is just 1
  2. Encode to binary Then it encodes each character to hex and split it in the middle. Then map the value to alphabet sequence, that is, a $\to$ 0 b $\to$ 1o $\to$ 14 p $\to$ 15
  3. Shift string This process is just like rot n that it shift the concatenated strings with n characters.

Exploit - Recover

  1. Guess it shift n character First, we can guess the n value for example 1. And then we try to shift it back.
  2. Regroup and Re-mapping Then we can represent the shifted string as binary. If the length of the binary value is equal to 8, that means we can regroup it to a real strings as ascii.
  3. Then repeat 16 times Here is the 16 outcomes…
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     et_tu?_23217b54456fb10e908b5e87c6e89156
     v`@`CDCBHsFEEFGwsBAvJAIsFvIHtGvIJBFG
     qQqTUTSYWVVWXSR[RZWZYXZ[SWX
     §§¨befedjhgghidclckhkjikldhi
     ©¸¸¹svwvu{¦yxxyzª¦ut©}t|¦y©|{§z©|}uyz
     ºÉ¤Éʤ·»·º·º¸º
     ËÚµÚÛµÈÌÈËÈËÉË
     ÜëÆëì¦Æ©ª©¨®Ù¬««¬­ÝÙ¨§Ü §¯Ù¬Ü¯®Ú­Ü¯ ¨¬­
     íü×üý·×º»º¹¿ê½¼¼½¾îê¹¸í±¸°ê½í°¿ë¾í°±¹½¾
     ÈèËÌËÊÀûÎÍÍÎÏÿûÊÉþÂÉÁûÎþÁÀüÏþÁÂÊÎÏ
    

    Seems the first one is quite normal. And we got the flag… Flag: picoCTF{et_tu?_23217b54456fb10e908b5e87c6e89156} :::spoiler whole exploit ```python!= import string

LOWERCASE_OFFSET = ord(“a”) ALPHABET = string.ascii_lowercase[:16] cipher_flag = “apbopjbobpnjpjnmnnnmnlnbamnpnononpnaaaamnlnkapndnkncamnpapncnbannaapncndnlnpna”

def binToHexa(n): bnum = int(n) temp = 0 mul = 1 count = 1 hexaDeciNum = [‘0’] * 100 i = 0 while bnum != 0: rem = bnum % 10 temp = temp + (remmul) if count % 4 == 0: if temp < 10: hexaDeciNum[i] = chr(temp+48) else: hexaDeciNum[i] = chr(temp+55) mul = 1 temp = 0 count = 1 i = i+1 else: mul = mul2 count = count+1 bnum = int(bnum/10) if count != 1: hexaDeciNum[i] = chr(temp+48) if count == 1: i = i-1 hex_string = ‘’ while i >= 0: hex_string += hexaDeciNum[i] i = i-1 if hex_string == ‘’: hex_string = ‘00’ return hex_string

tmp = “” guess_strings = “” for i in range(1, 16): for e in cipher_flag: tmp += “{0:04b}”.format((ord(e) - LOWERCASE_OFFSET + i) % len(ALPHABET)) if len(tmp) % 8 == 0: guess_strings += chr(int(binToHexa(tmp), 16)) tmp = “” tmp = “” print(guess_strings) guess_strings = “” :::