️🏴 MetaCTF February 2024 Flash CTF

A monthly mini CTF competition organized by MetaCTF and Antisyphon.



MetaCTF February 2024 Flash CTF

A monthly mini CTF competition organized by MetaCTF and Antisyphon. There will be 5 challenges and you will have 2 hours to solve as many as you can.

Direct Login

Take a look at ConnectWind's internal employee portal. In addition to company policies & HR information, I heard it also stores flags.

Can you access the protected employee portal without knowing the password and steal the flag?

The main page contains this JavaScript:

if (r.login_successful) {
 // Redirect if login successful
 set_alert('Login successful! Redirecting... <i class="fa-solid fa-spinner fa-spin"></i>', "success");
 setTimeout(function () {
   window.location.href = "./employee_portal.php";
}, 1500);

There's no actual authentication; visiting employee_portal.php reveals the flag:


Obfuscated Secrets

I hid the flag in this Python script. It asks you for a flag and tells you if it's correct or not. Can you reverse engineer it to find the correct flag?

The flag that the script above validates as correct is the flag for this challenge.

You can also access the script in an online Python IDE here: https://www.online-python.com/1i6lX9bv0a. Click the green "Run" button to run the program.

The script here takes in user input and then essentially makes this check:

all([ord(flag[i]) - 1 == ord(encrypted[i]) + i for i in range(len(encrypted))])

…where flag is the user input and encrypted is the encrypted flag. Simply reverse-engineering that comparison reveals the flag:

>>> encrypted = "Lcq]>N?s]bV[R[_OaScQ]]NGPYDKDNG]"
>>> "".join(chr(ord(encrypted[i]) + i + 1) for i in range(len(encrypted)))

Simple Sums

Take a look at my new calculator app!

The only thing it can do at the moment is adding two positive integers. There's an easter egg that gives you the flag if your numbers add up to a special number. Can you get that flag?_

Connect to my calculator app with the flag using the nc host5.metaproblems.com 5030 command.

Here the C program takes in 2 int values, both of which must be <= 0 and the sum of which must be -1337.

These are unsigned int values so integer-overflowing is the crux of this.

Taking INT_MAX (as it's the upper limit at which things will begin to overflow) and INT_MAX - 1335 results in the correct value:

nc host5.metaproblems.com 5030
Welcome to the SimpleSum calculator!

Provide two integers between 0 and 2147483647, inclusive

Enter the first positive integer: 2147483647
Enter the second positive integer: 2147482312

The sum is 4294965959

Good job! Here's your flag:

SHA256 Collider

I've heard no one has found a collision for sha256 yet ... will you be the first?

Take a look at this program. If you give it the right secret, it will give you the flag!

Connect to our instance of this program at nc host5.metaproblems.com 7050

The service reveals the underlying values:

 nc host5.metaproblems.com 7050
Welcome! Please wait for the secret ...

g = 3
p = 176990879449076061394656208196471172772796858746347869333441279405195482688385975304880833357734442233801462103581022209200859912054692903826387709385614287807701459307239660196202170697996271354481597203147379846644879109903687638341699852267708487952068587305618378357476857928558713970326437806256518178353
secret = 146802330728120378918906691881895374785480307070866779454516776790411811985618126251720916771758679657681171678349141469419391516537668903272003830572369327589991248382248087525806631471585012412111100182322711401172439831685120287246754540246392578979672737389183817026689029121609192962868973898418954591865

Enter your secret:

This appears to be a quasi-Diffie-Helman algorithm wherein each party selects their secret (user_secret and secret respectively), and the values to be shared are calculated.

The aim here is effectively to produce a user_secret which results in identical user_shared and shared values (the SHA256 is irrelevant: it's the values input thereto that matter).

Cue Fermat's little theorem. That states that for any number a not divisible by p, a prime number, then a^(p−1) ≡ 1 mod  p.

Essentially, what's desired is: g^user_secret ≡ g^secret mod p. Because this is modular arithmetic, adding or subtracting a multiple of p-1 from the exponent secret is adding or subtracting a multiple of p-1 to the power, which doesn't change the result mod p.

Therefore setting user_shared to (p - 1) + secret should result in the right answer:

[+] Opening connection to host5.metaproblems.com on port 7050: Done
[+] Receiving all data: Done (88B)
[*] Closed connection to host5.metaproblems.com port 7050

Well done, you are the first! Here is your flag: MetaCTF{well_d0n3_you_br0k3_sha256?!}

007: License to Scan

The transport department purchased a bunch of used MetaCTF license plate cameras on eBay, but the console's display is fried, and we can't figure out how to use them. Can you help us out? Here's a packet capture, and here's a description of the protocol they use.

Using pyshark and largely implementing the spec. as provided:

import pyshark

cap = pyshark.FileCapture(
    display_filter="not arp",

k1 = bytes.fromhex(cap[0].data.data)[3:]
k2 = bytes.fromhex(cap[1].data.data)[3:]
key = bytes(a ^ b for a, b in zip(k1, k2))

for packet in list(cap)[2:]:
    data = bytes.fromhex(packet.data.data)

    _version_type = bin(data[0])
    _length = int.from_bytes(data[1:3], byteorder="big")

    for j in range(0, len(data[3:]), 16):
        plate_index = j + 4
        plate = bytes(
            a ^ b
            for a, b in zip(
                data[3 + plate_index : 3 + plate_index + 16],
        plate = plate.decode().strip()

        if "{" in plate or "}" in plate:
            print(plate, end="")

…although I've skipped some of the explicit packet-type checks for simplicity, thanks to the ordering of the packets in the capture and the fact that of course it's using encryption: