2023-05-01 10:28:41 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import hashlib
|
|
|
|
import qrcode
|
|
|
|
from PIL import Image
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
|
|
def get_user():
|
|
|
|
r = requests.get("https://brachiosaure.france-cybersecurity-challenge.fr/")
|
|
|
|
name = r.text.split("text-warning\">")[1].split('<')[0]
|
|
|
|
return name
|
|
|
|
|
|
|
|
def get_digest(name):
|
|
|
|
m = hashlib.sha512()
|
|
|
|
m.update(name.encode())
|
|
|
|
digest = m.digest()
|
|
|
|
return digest
|
|
|
|
|
|
|
|
def linearize_serial(matrix_serial):
|
|
|
|
serial = bytearray()
|
|
|
|
|
|
|
|
for line in matrix_serial:
|
|
|
|
for b in line:
|
|
|
|
serial.append(b % 256)
|
|
|
|
return bytes(serial)
|
|
|
|
|
|
|
|
def img_to_matrix(img):
|
|
|
|
array = list(img.getdata())
|
|
|
|
width, height = img.size
|
|
|
|
|
|
|
|
matrix_img = [[array[i * width + j] for j in range(width)] for i in range(height)]
|
|
|
|
return matrix_img
|
|
|
|
|
|
|
|
|
|
|
|
def matrix_to_img(mat, path):
|
|
|
|
array = np.uint8(mat)
|
|
|
|
img = Image.fromarray(array)
|
|
|
|
img.save(path)
|
|
|
|
|
|
|
|
|
|
|
|
def gen_qrcode(data, path):
|
|
|
|
qr = qrcode.QRCode(version = 1, box_size = 2, border = 2)
|
|
|
|
qr.add_data(data)
|
|
|
|
qr.make()
|
|
|
|
qr_usr = qr.make_image()
|
|
|
|
qr_usr.save(path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def identitymatrix(n):
|
|
|
|
return [[int(x == y) for x in range(0, n)] for y in range(0, n)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_flag(name):
|
|
|
|
files = {
|
|
|
|
"upload1": open(f"{name}_usr.png", "rb"),
|
|
|
|
"upload2": open(f"{name}_serial.png", "rb")
|
|
|
|
}
|
|
|
|
r = requests.post("https://brachiosaure.france-cybersecurity-challenge.fr/login", files=files)
|
|
|
|
for line in r.text.split('\n'):
|
|
|
|
if "FCSC{" in line:
|
|
|
|
print(line)
|
|
|
|
|
|
|
|
|
|
|
|
name = get_user()
|
|
|
|
digest = get_digest(name)
|
|
|
|
|
|
|
|
matrix_usr = [[digest[i * 8 + j] for j in range(8)] for i in range(8)]
|
|
|
|
matrix_usr = np.array(matrix_usr)
|
|
|
|
|
|
|
|
matrix_serial = np.dot(matrix_usr, matrix_usr)
|
|
|
|
serial = linearize_serial(matrix_serial)
|
|
|
|
|
|
|
|
|
|
|
|
gen_qrcode(digest, "user.png")
|
|
|
|
gen_qrcode(serial, "serial.png")
|
|
|
|
|
|
|
|
|
|
|
|
img_usr = Image.open("./user.png", "r")
|
|
|
|
img_serial = Image.open("./serial.png", "r")
|
|
|
|
|
|
|
|
matrix_img_usr = img_to_matrix(img_usr)
|
|
|
|
matrix_img_serial = img_to_matrix(img_serial)
|
|
|
|
|
|
|
|
|
|
|
|
def invert(usr, serial):
|
2023-05-02 14:19:27 +00:00
|
|
|
# Add empty and identity matrices to make it invetible
|
2023-05-01 10:28:41 +00:00
|
|
|
usr = make_invertible(usr)
|
|
|
|
serial = make_invertible(serial)
|
|
|
|
|
|
|
|
n = len(usr)
|
|
|
|
# Total size after redimensionning
|
|
|
|
new_n = n * 2
|
|
|
|
|
|
|
|
# The magic inversion by swapping corners and computing matrix opposite
|
|
|
|
usr_inv = invert_magic(usr)
|
|
|
|
serial_inv = invert_magic(serial)
|
|
|
|
|
|
|
|
# Will hold the final user png
|
|
|
|
new_usr = []
|
|
|
|
# Will hold the final serial png
|
|
|
|
new_serial = []
|
|
|
|
|
|
|
|
|
|
|
|
# Create the new_usr
|
|
|
|
for i in range(new_n):
|
|
|
|
line = [0] * new_n
|
|
|
|
if i < n:
|
|
|
|
for j in range(n):
|
|
|
|
line[j] = usr[i][j]
|
|
|
|
if i >= n:
|
|
|
|
for j in range(n):
|
|
|
|
line[j + n] = int(serial_inv[i - n][j])
|
|
|
|
new_usr.append(line)
|
|
|
|
|
|
|
|
|
|
|
|
# Create the new_serial
|
|
|
|
for i in range(new_n):
|
|
|
|
line = [0] * new_n
|
|
|
|
if i < n:
|
|
|
|
for j in range(n):
|
|
|
|
line[j] = int(usr_inv[i][j])
|
|
|
|
if i >= n:
|
|
|
|
for j in range(n):
|
|
|
|
line[j + n] = serial[i - n][j]
|
|
|
|
new_serial.append(line)
|
|
|
|
|
|
|
|
|
|
|
|
return new_usr, new_serial
|
|
|
|
|
|
|
|
|
|
|
|
def make_invertible(mat):
|
|
|
|
res = []
|
|
|
|
n = len(mat)
|
|
|
|
ident = identitymatrix(n)
|
|
|
|
|
|
|
|
# Add the identity matrix below the original
|
|
|
|
for line in ident:
|
|
|
|
mat.append(line)
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(len(mat)):
|
|
|
|
line = mat[i]
|
|
|
|
for j in range(n):
|
|
|
|
# Add the identity matrix at the right of the original
|
|
|
|
if i < n:
|
|
|
|
line.append(ident[i][j])
|
|
|
|
# Add the empty matrix at the bottom right corner
|
|
|
|
else:
|
|
|
|
line.append(0)
|
|
|
|
|
|
|
|
return mat
|
|
|
|
|
|
|
|
|
|
|
|
def invert_magic(mat):
|
|
|
|
n_tot = len(mat)
|
|
|
|
n = n_tot // 2
|
|
|
|
|
|
|
|
#Create a new empty matrix to hold the result
|
|
|
|
res = [[0 for _ in range(n)] for _ in range(n)]
|
|
|
|
|
|
|
|
ident = identitymatrix(n)
|
|
|
|
|
|
|
|
# Add the identity matrix below
|
|
|
|
for line in ident:
|
|
|
|
res.append(line)
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(len(mat)):
|
|
|
|
line = res[i]
|
|
|
|
for j in range(n):
|
|
|
|
# Identity matrix on the right
|
|
|
|
if i < n:
|
|
|
|
line.append(ident[i][j])
|
|
|
|
|
|
|
|
# Oposite of the original in the bottom right corner
|
|
|
|
else:
|
|
|
|
el = -mat[i - n][j] % 256
|
|
|
|
line.append(el)
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
res_usr, res_serial = invert(matrix_img_usr, matrix_img_serial)
|
|
|
|
|
|
|
|
matrix_to_img(res_usr, f"{name}_usr.png")
|
|
|
|
matrix_to_img(res_serial, f"{name}_serial.png")
|
|
|
|
|
|
|
|
get_flag(name)
|