Panitia CTF

← Back

Find IT Final 2021

Lucky Numbers (Crypto)

Ciphertext diperoleh dari hasil (flag ^ (LUCKY_NUMBER + 1))

Searching di google, ternyata dapat bilangan lucky numbernya

1e44be0da20bca4da3317fe583c1d605b61b2c6c.png

exec(open('output.txt').read())
LUCKY_NUMBERS = [1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63,
67, 69, 73, 75, 79, 87, 93, 99, 105, 111, 115, 127, 129, 133, 135, 141,
151, 159, 163, 169, 171, 189, 193, 195, 201, 205, 211, 219, 223, 231,
235, 237, 241, 259, 261, 267, 273, 283, 285, 289, 297]

FLAG = ""
for i, c in enumerate(ciphertext):
	num = c ^ (LUCKY_NUMBERS[i] + i)
	FLAG += chr(num)
	print (FLAG)

Multiple Messages (Crypto)

Deretan bilangan a dan c digenerate secara random, namun random menggunakan seed yaitu 6 huruf pertama flag. Dengan menggunakan seed yang sama, deretan bilangan a dan c bisa digenerate ulang.

Didapat x = a * m + c, kemudian nilai x dipangkatkan dengan 3 atau 5 dan dimodulo n. Nilai c jauh dibawah nilai n, artinya nilai x^3 < n. Sehingga, untuk mendapat nilai x tinggal di akarkan saja. m = (x - c) / a

from Crypto.Util.number import *
import random
import gmpy2

FLAG = b"FindITCTF"
random.seed(bytes_to_long(FLAG[:6]))
exec(open("output.txt").read())

CNT = 6

a = [random.randint(128, 1024) for _ in range(CNT)]
c = [random.randint(2048, 4096) for _ in range(CNT)]

FLAG = ""
for i, cipher in enumerate(ciphertext):
	x, _ = gmpy2.iroot(cipher, public_keys[i][0])
	m = (x - c[i])//a[i]
	print (long_to_bytes(m))

Chemistry Elements (Crypto)

Dilakukan dekripsi menggunakan periodic table cipher https://www.dcode.fr/atomic-number-substitution

Kemudian dilanjut menggunakan cyberchef dengan recipe sebagai berikut

ab8c2c39afbe3c30a7be2fd7df062ec0caf7de09.png

Sum 1 (Crypto)

Diberikan enkripsi menggunakan knapsack cryptosystem

import random
from collections import namedtuple
from Crypto.Util.number import isPrime, bytes_to_long, inverse, long_to_bytes

public_key = [...SNIP...]
encrypted = [...SNIP...]

def create_matrix_from_knapsack(ciphertext, pub_keys):
    last_col = []
    for p in pub_keys:
        last_col.append(p)

    last_col.append(ciphertext)
    last_row = [1 for i in pub_keys]

    my_matrix = MatrixSpace(ZZ, len(pub_keys))(2)
    m_last_row = matrix(ZZ, 1, len(last_row), last_row)
    m_last_col = matrix(ZZ, len(last_col), 1, last_col)

    my_matrix = my_matrix.stack(m_last_row)
    my_matrix = my_matrix.augment(m_last_col)

    return my_matrix

def is_short_vector(vector):
    for v in vector:
        if v != 1 and v != -1 and v != 0:
            return False
    return True

def find_short_vector(matrix):
    for row in matrix:
        if is_short_vector(row):
            return row

def main():
    flag = b''
    for cipher in encrypted:
        pub_keys = public_key
        my_matrix = create_matrix_from_knapsack(cipher, pub_keys)

        new_matrix = my_matrix.LLL()

        short_vector = find_short_vector(new_matrix)

        solution_vector = []
        for v in short_vector:
            if v == 1:
                solution_vector.append(0)
            elif v == -1:
                solution_vector.append(1)
                
        num = int(''.join([str(i) for i in solution_vector])[::-1], 2)
        flag += long_to_bytes(num)

    print(flag)

Sum 2 (Crypto)

b4992073da05505659e5776ac7f987e005bb9eb8.png

Kami menggunakan solver yang sama dengan sum 1 🙂

Calc (Reversing)

49220b11632b82c5f593490c423330dc6a67799b.png

Didapati string base64 pada offset 0xce483..0xce4af decode n profit xixixi

Find Me (Reversing)

Diberikan file dump firmware OpenWrt setelah dilakukan extraksi file tersebut didapati squashfs file

a0cd15a78cfea78679db0150a1dd6e558bd2c58f.png

Setelah melakukan mounting file tersebut didapati binary ctf yang terembed dengan binary busybox

d31bbe1c846b4ffddfc41708f1906e423458b589.png

Pada saat binary tersebut dijalankan didapati pesan Ok kemudian kita lanjut dengan decompile binary busybox tersebut

f9259e3f98e3c2a990928a3e67a6f192e8ea6d44.png

fdf229e59310ff3921212ae7afb79b7960e8ef3d.png

Pada offset 0x458B20 didapati string yang sama dengan return binary ctf pada saat dijalankan

3c2ebf11858a1ec3fbe4d68fbc46a155fa25c912.png

Didapati inputan user dilakukan xor dengan 0x50 kemudian dilakukan komparasi dengan byte_472000

import pwn

enc = [0x16, 0x39, 0x3E, 0x34, 0x19, 4, 0x13, 4, 0x16, 0x2B, 4, 0x25,
0x37, 0x31, 0x23, 0x61, 0x12, 0x25, 0x3C, 0x31, 0x3E, 0x1E, 0x37, 0x35,
0x22, 0x3A, 0x31, 0x39, 0x3E, 0x61, 0x38, 0x31, 0x22, 0x39, 0x2D]

print(pwn.xor(enc, 0x50))

Free Flag (Forensic)

from Crypto.Cipher import DES

d = DES.new('\x46\x69\x6e\x64\x49\x54'.ljust(8, '\x00'), DES.MODE_ECB)
print(d.decrypt(open('galf.dat', 'rb').read()).replace(b'\x00', b''))

Decrypt file galf.dat menggunakan DES, kemudian decrypt kembali dengan vigenere dengan key FindIT

Ahoy Pirate (Forensic)

Kami menggunakan openstegano dengan password: password

Kemudian didapati link channel telegram yang berisikan flag

Png (Misc)

61857aa2569f4737e1a99d3a69db40e65bf40b54.png

Remove junkbyte pada offset 0x00..0x10

open('image.png', 'wb').write(
	open('image.stex', 'rb').read()[0x10 * 2:]
)