# 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="/files/OHiKLnZHsUPyg7cJfOfF" %}

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

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codingmace.gitbook.io/masterward/ctf/2022/byuctf-2022.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
