1 of 10

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Alright so this is basically obscurity crypto.

A little experimentation shows us that it for every byte of the plaintext and the matching byte of the key it adds the ascii values and then moduluses them by 256.

NOTE: because of how python .encode and decode works, for example, '\x7f'.encode() = b'\xc2\x7f'.

So, whenever we base 64 decode, we have to .decode().encode('latin-1') to get the proper byte values instead of weird UTF-8 ones.

It's possible to use modular arithmetic to get the key, in fact that probably wouldn't have been much harder, but instead I just ran a small byte by byte brute force of each char of the key, and then the flag, as this is a character by character cipher making it vulnerable to such an attack.

My script is below:

Flag:ractf{f00l_m3_7w1c3_5h4m3_0n_m3}

Basic CBC bit flipping - We're given ciphertext for `access=9999;`

+ an expiry timestamp, and have to provide an IV and ciphertext that decrypt to `acesss=0000`

.

ractf{cbc_b17_fl1pp1n6_F7W!}

Essentially a scripting challenge. You'll be given all sorts of parameters and need to calculate the missing one. Instead of going through every possible solution, which would've been really excruciating, I went through this approach -

Create a function that solves for a value.

The function's logic is as follows:

if we want a value that's already defined, just return it

if we want n, call ourself to solve p and q, then multiply

if we want ct, call ourself to solve n, then do pt^e mod n

if we want pt, call ourself to solve d and n, then do ct^d mod n

if we want d, call ourself to solve p and q,compute phi, then return inverse(e,phi)

if we want p, or q, then:

pretend p is the prime we have and q is the prime we want

if we have n, return n // p

if we have phi, return (phi // (p - 1)) + 1

if all else fails and we have e and d, use Crypto.PublicKey.RSA to compute p and q via n, e and d

More of a rev really :/

Simple first step is to extract all the b85 encoded values as bytes. The ct and e are just b85 encoded, so we can store those for later use with rsactftool

P and Q on the other hand are treated differently. They are xored with a variable called 's' (state) using 'walrus operators'. The function can be expressed as:

The encrypted bytes of p and q are also interleaved throughout the value we receive. As XOR is commutative and s is XORed with the value we have just recovered, we can simply run the script again to recover the original values for p and q, making sure to use the recovered values of p and q bytes to update the state. We recover primes

Plugging our data into RsaCtfTool yields:

Flag: ractf{DoY0uLik3MyW4lrus35}

Monoalphabetical Substitution Cipher (trial and error)

**Flag: documents**Vigenere Cipher (trial and error)

**Flag: zurich**Railfence Cipher (freq anal)

**Flag: ANUALLEAVE**Columnar Transposition Cipher (freq analysis, x's at end for padding)

**Flag: CONCERNEDENCRYPTED**Bifid Cipher (lack of j hinted at grid cipher, cant be playfair because of doubles)

Key: ReallyAwesome

**Flag: Campbell**Periodic Gromark Cipher (number key, nothing else given)

Key: agency

**Flag: organization**

The OpenSSH private key is actually not a private key and is simply just base64.

We decode it to get a long useless message and 2 hex strings.

If we decode these hex strings we get,

`ineedtoopenlocks`

and `initialisation12`

Decoding the binary gets us a long hex string.

Looking at initialisation, I immediately thought of AES. Since an IV is provided, we can assume it is AES-CBC, so I just used cyberchef to

decrypt and get the flag.

Flag: ractf{3Asy_F1aG_0n_aEs_rAcTf}