S4CTF 2021: Baby-IQ

Baby-IQ

Category: crypto

114 points

Use this simple crypto algorithm to learn about padding and evaluate yourself on how well you understand algorithms.

baby-iq.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from math import sqrt
from flag import flag
import os
import random
import base64

def chunkchunk(msg, l):
	return [msg[l*i:l*(i + 1)] for i in range(0, len(msg) // l)]

def pad(msg):
	r = int(sqrt(len(msg))) + 1
	head = base64.b64encode(os.urandom(r**2))[:r**2 - (len(msg))]
	msg = head + msg.encode('utf-8')
	msg = chunkchunk(msg, r)
	return [list(m) for m in msg]

def encrypt(A):
	row = len(A)
	col = len(A[0])
	top = 0
	left = 0
	tmp = []
	while (top < row and left < col) :       
		for i in range(left, col) : 
			tmp.append(A[top][i])              
		top += 1
		for i in range(top, row) : 
			tmp.append(A[i][col - 1])     
		col -= 1
		if ( top < row) : 
			for i in range(col - 1, left - 1, -1) : 
				tmp.append(A[row - 1][i])  
			row -= 1
		  
		if (left < col) : 
			for i in range(row - 1, top - 1, -1) : 
				tmp.append(A[i][left])   
			left += 1
	result = []
	for i in range(len(A)):
		r = []
		for j in range(len(A[0])):
			r.append(tmp[i*len(A[0]) + j])
		result.append(r)
	return result

A = pad(flag)
for _ in range(len(A)):
	_ = encrypt(A)
	A = _

print('enc =', A)

enc.txt

enc = [[122, 83, 52, 67, 84, 70], [89, 114, 79, 48, 67, 125], [95, 121, 114, 53, 116, 55], [123, 95, 80, 51, 52, 95], [102, 115, 114, 95, 119, 107], [52, 117, 109, 33, 97, 112]]

Solution

I took the source of given baby-iq.py and changed it a bit. Copied encrypt function and reversed it as decrypt. The result can be found below.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import sqrt
import os
import base64

def unchunkchunk(l):
    enc_merged = []
    for i in l:
        enc_merged += i
    return enc_merged


def chunkchunk(msg, l):
    return [msg[l * i:l * (i + 1)] for i in range(0, len(msg) // l)]


def pad(msg):
    r = int(sqrt(len(msg))) + 1
    head = base64.b64encode(os.urandom(r ** 2))[:r ** 2 - (len(msg))]
    msg = head + msg.encode('utf-8')
    msg = chunkchunk(msg, r)
    return [list(m) for m in msg]


def encrypt(A):
    row = len(A)
    col = len(A[0])
    top = 0
    left = 0
    tmp = []
    while (top < row and left < col):
        for i in range(left, col):
            tmp.append(A[top][i])
        top += 1
        for i in range(top, row):
            tmp.append(A[i][col - 1])
        col -= 1
        if (top < row):
            for i in range(col - 1, left - 1, -1):
                tmp.append(A[row - 1][i])
            row -= 1

        if (left < col):
            for i in range(row - 1, top - 1, -1):
                tmp.append(A[i][left])
            left += 1
    result = []
    for i in range(len(A)):
        r = []
        for j in range(len(A[0])):
            r.append(tmp[i * len(A[0]) + j])
        result.append(r)
    return result


def decrypt(A):
    row = len(A)
    col = len(A[0])
    top = 0
    left = 0
    col2 = 0
    row2 = 0
    tmp = [[0 for i in range(col)] for j in range(row)]
    while (top < row and left < col):
        for i in range(left, col):
            tmp[top][i] = A[col2][row2]
            row2 = row2 + 1 if row2 < len(A[0]) - 1 else 0
            col2 = col2 + 1 if row2 == 0 else col2
        top += 1
        for i in range(top, row):
            tmp[i][col - 1] = A[col2][row2]
            row2 = row2 + 1 if row2 < len(A[0]) - 1 else 0
            col2 = col2 + 1 if row2 == 0 else col2
        col -= 1
        if (top < row):
            for i in range(col - 1, left - 1, -1):
                # tmp.append(A[row - 1][i])
                tmp[row - 1][i] = A[col2][row2]
                row2 = row2 + 1 if row2 < len(A[0]) - 1 else 0
                col2 = col2 + 1 if row2 == 0 else col2
            row -= 1

        if (left < col):
            for i in range(row - 1, top - 1, -1):
                tmp[i][left] = A[col2][row2]
                row2 = row2 + 1 if row2 < len(A[0]) - 1 else 0
                col2 = col2 + 1 if row2 == 0 else col2
                # tmp.append(A[i][left])
            left += 1
    tmp = unchunkchunk(tmp)
    result = []
    for i in range(len(A)):
        r = []
        for j in range(len(A[0])):
            r.append(tmp[i * len(A[0]) + j])
        result.append(r)
    return result

enc = [[122, 83, 52, 67, 84, 70],
       [89, 114, 79, 48, 67, 125],
       [95, 121, 114, 53, 116, 55],
       [123, 95, 80, 51, 52, 95],
       [102, 115, 114, 95, 119, 107],
       [52, 117, 109, 33, 97, 112]]

for _ in range(len(enc)):
    enc = decrypt(enc)

flag = bytes(unchunkchunk(enc))
print('Flag: {}'.format(flag))

Output:

Flag: b'zS4CTF{34sY_CryPtO_7a5k_f0r_w4rmup!}'

Flag

S4CTF{34sY_CryPtO_7a5k_f0r_w4rmup!}

Privacy Policy
luc © 2021