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.

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.

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

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

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.

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?

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 we produced the report below with the serial numbers being the flag.

Flag: flag{watchoutforthepoisonedcoffee}

Last updated