crypto

Challenges

Secure-Server

John Doe uses this secure server where plaintext is never shared. Our Forensics Analyst was able to capture this traffic and the source code for the server. Can you recover John Doe's secrets?

  • strings capture.pcap

  • server.py

  • passive cryptanalysis — we just get the value and reverse engineer it

  • I didn't do too much beside strings the capture.pcap file and trace the flawed implementation

Since we know both from the pcap:

  • john_input (what John enter) — flag ⊕ john_key = encrypted_flag

  • enc2 (the print statement)

We can recover the server's secret key using the XOR property:

  • enc2 = XOR(john_input, server_key)

  • Therefore: server_key = XOR(john_input, enc2)

  • Once we have the server key, we can decrypt: flag = XOR(final_input, server_key)

  • the dec in the code is the final_input we were looking for

circle-info

Script

  • scriptCTF{x0r_1s_not_s3cur3!!!!}

RSA - 1

Yú Tóngyī send a message to 3 peoples with unique modulus. But he left it vulnerable. Figure out :)

I translated the challenge description as:

  • (Yú Tóngyī) sending

    • Same message to multiple people

    • Different moduli ("unique modulus" for each person)

    • Left it "vulnerable"

1

Looking at out.txt, we see:

  • 3 different moduli (n1, n2, n3)

  • 3 different ciphertexts (c1, c2, c3)

  • Same small exponent (e = 3)

  • Number of messages = exponent value (3 messages, e=3)

2

We could see that

3

This is a classic RSA vulnerability so I highly recommend you to read over the CTR article, since the conditions met. We can just follows the theorem and decrypt the flag

  • Here are the math for...whoever needs it.

circle-info

Script

  • scriptCTF{y0u_f0und_mr_yu's_s3cr3t_m3g_12a4e4}

Mod

Just a simple modulo challenge

The challenge generates a random 32-byte (256-bit) secret and implements this simple protocol:

  1. Accept a number from the user

  2. Return number % secret (our input % secret)

  3. Ask for a guess of the secret

  4. Give the flag if the guess is correct


chevron-rightThe intended solution:hashtag

This is due to how Python handled negative modulo opeartions.

  • From the highlight

  • So we simply input -1 and then +1 to whatever the number % secret is.

circle-check
  • My solution on the other hands tho...

In my mind: "This is a crypto challenge, so it must require advanced mathematical attacks"

Reality: "a simple logic flaw that can be exploited with basic knowledge"


  • I think I was heading towards the same direction...although slightly off.

  • I fundamentally exploits the relationship: large_number = quotient × secret + remainder

  • So when we can send a large_prime = 2^256 + 1 and receive remainder, we can rearrange it to:

  • secret = (large_prime - remainder) / quotient

  • Next:

    • secret ranges from ~2^248 to 2^256 (a wild assumption)

    • large_prime = 2^256 + 1

    • --> quotient = (2^256 + 1) // secret will be 1 or 2

    • Then try each possible quotient q in the estimated range

    • Calculate potential secret using secret = (large_prime - remainder) / q

    • Verify the answer by checking if large_prime % potential_secret == remainder

chevron-rightThat is why I need to run the script 2, 3 times to get the flag.hashtag
  • scriptCTF{-1_f0r_7h3_w1n_4a3f7db1_43eed08ce9f6}

Secure-Server-2

circle-exclamation

This time, the server is even more secure, but did it actually receive the secret? Simple brute-force won't work!

chevron-rightWhat happening is:hashtag
  • strings capture.pcap to see

  • "Simple brute-force won't work!"

    • That just tell us to do some shenanigans

    • Well this is where I stuck and couldn't come up with an effective attacks in time.

  • Solution:

  • 4 keys, each 16 bits (2 bytes)

  • individual keys are small and easily brute force, it is impossible if combined them.

  • So we have

    • We want to find K3 and K4 such that

      • E4(E3(Value 1)) = Value 2

    • The same logic for finding K1 and K2.

  • The "Meet in the Middle".

    • From the LEFT: encrypt all possible K3 values on Value 1

    • From the RIGHT: decrypt all possible K4 values on Value 2

    • Look for where they MEET

  • We then proceed to reverse the entire process with the all the keys (from Value 1)

circle-info

Script

scriptCTF{s3cr37_m3ss4g3_1337!_7e4b3f8d}

EaaS

circle-info

upsolve 🚩 it is a fun challenge.

Email as a Service! Have fun...

Let's first analyze the source code that was given to us.

When we connect / run to the server:

  1. We get assigned a random email: Something like abcdefghij@notscript.sorcerer

  2. We must provide a password in hex: Must be a multiple of 16 bytes (AES block size)

  3. Password restrictions: Cannot contain our email address or the string @script.sorcerer

  4. The server encrypts our password using AES-CBC with the same key and IV for both encryption and decryption

So what is our win conditions? To get the flag, we need to:

  1. Trigger has_flag = True by convincing the server that we received an email from the sorcerers

  2. Check messages to read the flag

The server will only set has_flag = True if we can submit encrypted data that when decrypted:

  • Ends with exactly @script.sorcerer (last 16 bytes)

  • Contains our assigned email (hint: as one of the comma-separated recipients)

The problem: The server forbids us from including @script.sorcerer and our email in the input, but requires the decrypted output to end with @script.sorcerer and contain our email!, the lines responsible for our problem:

  • Input validation (what we submit):

  • Output validation (what gets decrypted):

  • So of course...we need to find a way to manipulate our input so that after encryption and decryption, it magically contains the forbidden strings.

  • Well...then we have to understand what the encryption method is being used ...AES-CBC...classic

  • I think the articles below will do a better job at explaining the CBC Bit-Flipping Attack than I do

The key is that in CBC mode, you can precisely control changes to plaintext by manipulating the previous ciphertext block.

circle-info

Script

  • scriptCTF{CBC_1s_s3cur3_r1ght?_3c38ba9890e9}

Last updated