# CSAW Qualifiers 2021

## Lazy Leaks

> **Description**
>
> Someone at a company was supposedly using an unsecured communication channel. A dump of company communications was created to find any sensitive info leaks. See if you can find anything suspicious or concerning.

{% file src="/files/-MjpfXe4Gm1In5mazIhT" %}
Lazy Leaks
{% endfile %}

**Solution**

Ran the cmd `strings Lazy_leaks.pcap | grep flag`

**Flag: flag{T00\_*****L\@ZY\_4\_*****$3CUR1TY}**

## Weak Password

> **Description**
>
> Can you crack Aaron’s password hash? \
> He seems to like simple passwords. I’m sure he’ll use his name and birthday in it. Hint: Aaron writes important dates as YYYYMMDD rather than YYYY-MM-DD or any other special character separator. Once you crack the password, prepend it with flag{ and append it with } to submit the flag with our standard format. \
> Hash: 7f4986da7d7b52fa81f98278e6ec9dcb.

**Solution**

The program I built was a little bit overkill when it came to the name, but I started out with the date and just "aaron" and didn't come back with a result. Because of that, I decided to do every variation I could think of to make sure I get it the next time I run the program.

```python
import hashlib

def pad(year, month, day):
    date = str(year) + ""
    if month < 10:
        date += "0"
    date += str(month)
    if day < 10:
        date += "0"
    date += str(day)
    return date

def hashing(password):
    return hashlib.md5(password.encode())

year = 1800
day = 1
month = 1
a = ['a', 'A', '@']
r = ['r', 'R']
o = ['o', 'O','0']
n = ['n', 'N']
#variables = ['a', 'r', 'o', 'n', 'A', 'R', 'O', 'N', '0' ,'@']
name = ["aaron", "AARON"]
for i1 in a:
    for i2 in a:
        for i3 in r:
            for i4 in o:
                for i5 in n:
                    curName = i1 + i2 + i3 + i4 + i5
                    name.append(curName)

#goalHash = "2cf2481031af7347b0be175f64cd39a7"
goalHash = "7f4986da7d7b52fa81f98278e6ec9dcb"
while year < 2021:
    while month <= 12:
        while day <= 31:
            for n in name:
                password = pad(year, month, day)
                if (hashing(n + password).hexdigest() == goalHash):
                    print("I FUCKING FOUND IT" , n, year, month, day)
            day += 1
        month += 1
        day = 1

    year += 1
    day = 1
    month = 1
```

**Flag: flag{Aaron19800321}**

## Contact Us

> **Description**
>
> Veronica sent a message to her client via their website's Contact Us page. Can you find the message? \
> Author: moat, Pacific Northwest National Laboratory

{% file src="/files/-MjpaOb5Obba8Fn6-NXf" %}

**Solution**

Given the two files, I saw that the encrypted traffic was where the focus needed to be. I opened up Wireshark and went blank. How do I import the key? After some searching on the internet, I found that I had to go to`Edit -> Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log filename` and select the sslkeyfile.txt. Bam then the whole file was decrypted and I just had to go in and search for the flag.

**Flag: flag{m\@r$hm3ll0w$}**

## Gotta Decrypt Em All \[175 pts] (Pwnaday Solution) <a href="#gotta-decrypt-em-all" id="gotta-decrypt-em-all"></a>

> **Description**
>
> You are stuck in another dimension while you were riding Solgaleo. You have Rotom-dex with you to contact your friends but he won't activate the GPS unless you can prove yourself to him. He is going to give you a series of phrases that only you should be able to decrypt and you have a limited amount of time to do so. Can you decrypt them all?
>
> nc crypto.chal.csaw\.io 5001

**Solution**

This problem was simple in my opinion but a pain in the butt.\
First up is the morse code which was a quick copy and paste from the internet. That then was decoded into a weird ASCII which was identified as Base64. That Base64 Spit out an RSA key with N, e, c, and when decoded put through ROT13 It creates a word to send to the server.&#x20;

```python
from pwn import *
import time
import base64
from owiener import attack,isqrt
from Crypto.Util.number import inverse,bytes_to_long,long_to_bytes,GCD
# Dictionary representing the morse code chart
MORSE_CODE_DICT = { 'A':'.-', 'B':'-...',
                    'C':'-.-.', 'D':'-..', 'E':'.',
                    'F':'..-.', 'G':'--.', 'H':'....',
                    'I':'..', 'J':'.---', 'K':'-.-',
                    'L':'.-..', 'M':'--', 'N':'-.',
                    'O':'---', 'P':'.--.', 'Q':'--.-',
                    'R':'.-.', 'S':'...', 'T':'-',
                    'U':'..-', 'V':'...-', 'W':'.--',
                    'X':'-..-', 'Y':'-.--', 'Z':'--..',
                    '1':'.----', '2':'..---', '3':'...--',
                    '4':'....-', '5':'.....', '6':'-....',
                    '7':'--...', '8':'---..', '9':'----.',
                    '0':'-----', ', ':'--..--', '.':'.-.-.-',
                    '?':'..--..', '/':'-..-.', '-':'-....-',
                    '(':'-.--.', ')':'-.--.-'}

def decrypt(message):
    # extra space added at the end to access the
    # last morse code
    message += ' '
    decipher = ''
    citext = ''
    for letter in message:
        # checks for space
        if (letter != ' '):
            # counter to keep track of space
            i = 0
            # storing morae code of a single character
            citext += letter
        # in case of space
        else:
            # if i = 1 that indicates a new character
            i += 1
            # if i = 2 that indicates a new word
            if i == 2 :
                 # adding space to separate words
                decipher += ' '
            else:
                # accessing the keys using their values (reverse of encryption)
                decipher += list(MORSE_CODE_DICT.keys())[list(MORSE_CODE_DICT
                .values()).index(citext)]
                citext = ''
    return decipher
def rot(s, k):
    alphabet = list('abcdefghijklmnopqrstuvwxyz')
    s = list(s)
    for i in range(len(s)):
        e = s[i]
        is_upper = e.isupper()
        if e in [' ','.','_']:
            continue
        idx = alphabet.index(e.lower())
        new_idx = (idx+k)%len(alphabet)
        if is_upper:
            s[i] = alphabet[new_idx].upper()
        else:
            s[i] = alphabet[new_idx]
    return ''.join(e for e in s)



def iroot(k,n):
    u,s = n,n+1
    while u < s:
        s = u
        t = (k-1)*s+n // pow(s,k-1)
        u = t//k
    return s
binary = remote("crypto.chal.csaw.io", 5001)
done = False
while not done:
    try:
        print(binary.recvuntil(bytes("mean?", "utf-8")))
        more = (binary.recvuntil(bytes(">>", "utf-8"))) # Morse code
        morseCode = str(more, 'utf-8').replace('>>' ,"")
        morseCode = morseCode.replace('\n', "").replace('\r', '')
        words = morseCode.split('/')
        text = ""
        for word in words:
                text += chr(int(decrypt(word)))

        based = base64.b64decode(text).split(b'\n')
        N = int(based[0].decode()[4:])
        e = int(based[1].decode()[4:])
        c = int(based[2].decode()[4:])

        cube_root = iroot(3,c)
        root_bytes = long_to_bytes(cube_root)
        rot_bytes = rot(root_bytes.decode(),13).encode()
        binary.sendline(rot_bytes)
    except Exception as e:
        print('exception: {}'.format(e))
        done = True
binary.recvuntil(b'friends: ')
buf = binary.recvuntil(b'\r\n')[:-2].decode()
print('flag: {}'.format(buf))
```

## Mic

> **Description**
>
> My Epson InkJet printer is mysteriously printing blank pages. Is it trying to tell me something?

{% file src="/files/-MjpaD5pdowPekyNErln" %}

**Solution**

We were stumped on this one until we found something on the printer. We looked at the PDF with analysis. Nothing showed up until someone saw dots. I thought at first we were just seeing something but he wasn't lying. This lead to a great trail and by using [deda ](https://github.com/dfd-tud/deda)we produced the report below with the serial numbers being the flag.

{% file src="/files/-Mjm56ey0lKwiadHz4ae" %}
Results
{% endfile %}

**Flag: flag{watchoutforthepoisonedcoffee}**


---

# 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/2021/csaw-qual-2021.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.
