BYUCTF 2022

Misc

Reconstruct [183 pts]

Description

To prevent the need to brute force submit what may seem to be multiple likely answers, I have provided the MD5 hash of the entire flag so you can verify that you have it right before submitting it online (lessening load on the server).

63b1424fa6fe8aa81d9ce4b5637f7acd

Solution

So given the stupid image I tried to come up with the most by myself which left me with byuctf{" + guess1 + "w1th_the" + guess2 + "of_1nfo_1" + guess3 + "_" + guess4 + "_1t}. And with a teammates help we narrowed it down and could use some code to brute force the word we didn't know to get the flag.

import hashlib
targetHash = "63b1424fa6fe8aa81d9ce4b5637f7acd"
charSet = "abcdefghijklmnopqrstuvwxyz0123456789a"
def get(guesses):
    ans = ""
    for g in guesses:
        ans += charSet[g]
    return ans
guess1 = "aaaaaa"
myGuess = "byuctf{even_w1th_the_" + guess1 + "_of_1nfo_1_can_reconstruct_1t}"
guesses = []
for i in range(0, 6):
    guesses.append(0)

cont = True
while cont:
    guesses[0] += 1
    indChange = 0
    while guesses[indChange] > len(charSet) - 1:
        guesses[indChange] = 0
        indChange += 1
        guesses[indChange] += 1
    guess = "byuctf{even_w1th_the_" + get(guess1) + "_of_1nfo_1_can_reconstruct_1t}"
    
    if hashlib.md5(guess.encode()).hexdigest == targetHash:
        print("flag is", guess)
        cont = False

Makes [267 pts]

Description

Uhoh! I was learning how to make makefiles, and somehow I made all of my targets messed up... Which target will print the pattern 1111111l11lll1ll11l11111111l when called?

Flag format - byuctf{target_name} (ie byuctf{8585bc2f9})

Solution

Noticing it was jumping all over the place my mind went to nodes. I wrote a software that was going to try and jump each make type and see which one matches. That didn't work as well as I thought so I ended up writing it all to a file and searching for the string based on what each call did an output to find it.

import subprocess
import os
class node:
    def __init__(self, cur):
        self.cur = cur
        self.val = -1
        self.next = "main"
        
    def setVal(self, val):
        if val == "1":
            self.val = 1
        elif val == "l":
            self.val = 0
    
    def setNext(self, next):
        self.next = next

    def getNext(self):
        return self.next
    
    def getVal(self):
        return self.val

    def getName(self):
        return self.cur

def findNode(nodeList, myNode):
    for i in range(0, len(nodeList)):
        if nodeList[i] == myNode:
            return i
    return 0
    
f = open("Makefile", "r")
lines = f.readlines()

entry = []
nodeList = []
nodeIndexs = []
for i in range(0, len(lines), 1):
    if ":" in lines[i]:
        curNode = node(lines[i][:-2])
        nodeIndexs.append(lines[i][:-2])
        i += 1
        value = lines[i].replace("echo","")
        curNode.setVal(value.strip())
        i += 1
        curNode.setNext(lines[i].replace("make","").strip())
        i += 1
        nodeList.append(curNode)


g = open("nodes", "w")
maxNumb = 0
for i in range(0, len(nodeList)):
    # make the items
    lastInd = 0
    checkStr = "1111111011000100110111111110"
    curNode = nodeList[i]
    cont = True
    curResult = ""
    length = 0
    while cont:
        if length > len(checkStr):
            cont = False
        curResult += str(curNode.getVal())
        newInd = findNode(nodeIndexs, curNode.getNext())
        print(newInd)
        if newInd == 0:
            cont = False
        length += 1
        curNode = nodeList[newInd]
    g.write(nodeList[i].getName() + " " + str(curResult) + '\n')

Probably [338 pts]

Description

Is this challenge going to give you the flag? Um, probably. I don't know. Maybe not.

nc byuctf.xyz 40004

Solution

At first I tried reversing the pyfiglet by comparing the first value with a generated one and finding the best value. That didn't work too well so then I figured it would be faster to just input manually enough to be able to find a pattern. I did that and ran the code

def duplicate(values):
    ans = ""
#    values.sort()
    for i in range(0, len(values) - 1):
        for o in range(i + 1, len(values)):
            if values[i] == values[o]:
                ans += values[i]
#                print(values[i])
#                return values[i]
    print(ans)
    return '?'

myGuess = "byuctf{rhaz_are_the_chances_7e53fcs}"
f = open("gotten.txt", "r")
test = []
lines = f.readlines()
for line in lines:
	test.append(line)
#test = ["0y8ayw0aga2ohge0tj89hhhn_g__meez3eosk","g37c80jc8askar5ynde91hz3a_e_7yq831gh1","byn_t9{duazmno0_tkp610ok3r6c7bgquffsj","_wwmf9wguapopr8kthe_e0un8efvps6p3fivk","jy_qozfl7a85258jtizkc6usck2dl8e84hjsf","b7umtferopu7k40hbhe5qltzgjrejebgbfa5}","3npctfijhat_ard_cxydwlaj_eg_ovt5dmcir","oyu1tpnwhx7wabb_dvekkha29iu_9e253ysm}", "uy9464{rcxz_hdeg25a_vsq6cxs_091qxecb}", "3w7h2t{ih2k_5e3k6gyee9a3mds231eycfl3z}","byuhyd{ndai_x0d0iojikh0nb1s1jme5bwks0"]
ind = 0
ans = ""
while ind < len(test[0]):
    values = []
    for i in range(0, len(test)):
        values.append(test[i][ind])
    ans += duplicate(values)
    ind += 1

We didn't have something readable so me and another teammate ran it more times until we got something more definitive and with some luck and a few inputs we got the flag.

Cryptography

XQR [490 pts] [UNSOLVED]

Description

I love QR codes! But maybe it's true what they say about having too much of a good thing...

Hint: If my eyesight gets bad enough, i might think the chall title is XOR...

Solution

I started out with splitting up the image into the sub images, which the QR reader was not picking up. I was going to potentially enhance the image because it was blurry, but don't think that was the point so I dropped it. The code below is to split images.

from numpy import asarray
from PIL import Image
import cv2

def splitImage(imageName):
	im = cv2.imread(imageName)
	M = 27 # Split x
	N = 27 # Split y
	tiles = [im[x:x+M,y:y+N] for x in range(0,im.shape[0],M) for y in range(0,im.shape[1],N)]
	det = cv2.QRCodeDetector()
	for i in range(0, len(tiles)):
		val, pts, st_code = det.detectAndDecode(tiles[i])
		print(val)
	image2 = Image.fromarray(tiles[0])
	for i in range(0, len(tiles)):
		cv2.imwrite("QR/" + str(i) + ".png", tiles[i])

import qrtools
def readQR(imageName):
	det = cv2.QRCodeDetector()
	im = cv2.imread(imageName)
	val, pts, st_code = det.detectAndDecode(im)
	print(val)

qr = qrtools.QR()
readQR("QRcode.jpg")
print(qr.data)

Last updated