# BYUCTF 2022

## **Misc**

### Reconstruct \[183 pts] <a href="#reconstruct" id="reconstruct"></a>

> **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

{% file src="<https://980792987-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Md9Bzo_DCKomMglV10a%2Fuploads%2FqXEoloAiTwOfkPOdnCCK%2Freconstruct.png?alt=media&token=64fbe7ff-ca66-462e-971c-4c0d3caafaa6>" %}

**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.

```python
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] <a href="#makes" id="makes"></a>

> **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.

```python
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] <a href="#probably" id="probably"></a>

> **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&#x20;

```python
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] <a href="#xqr" id="xqr"></a>

> 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.

```python
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)

```
