HactivityCon2020 Writeups

Ashish Agarwal
2 min readSep 17, 2020

Cryptography

Perfect XOR (Points 100)

Can you decrypt the flag?

fig(i) given python file

Now, as our first instinct, we would like to run the file to check out what it does. Sure, run the give code in a VM (Always be safe). Turns out this script is meant to just output the flag. But wait, is it that simple, they just give it you? No!, this process takes an infinite(rather long) amount of time to output the whole flag. So, what do we do? let’s see under the hood what this script really does.

Now, there’s a cipher text, and by the looks of it, it’s a base64 encoded cipher. But wait, the script literally just decodes it before the real fun(loop) begins (line 14). let’s see what decoded cipher message looks like.

fig(ii) Decoded message

Hmm, so the cipher contains some pretty interesting list of strings that are actually numbers. Also some are pretty huge numbers. Also there are just 14 of those numbers. so, the loop must iterate 14 times.

Now, what does that a() function do? It seems as if it is finding numbers having sum of factors as the original number. Now, I am a simple man. Whenever, I see numbers, I look for patterns. Wait a minute, did the topic mentioned perfect something? sure! they are perfect numbers.

Now, let’s figure out the second part XOR. okay this is easy, the script simply xor’s the first 14 perfect numbers with the cipher-decoded numbers, covert it in to ascii equivalent character and prints it. The huge amount of time was consumed to find perfect numbers.

As it turns out, we have list of perfect number online but they are huge and not formatted in most websites. So, simply we can generate perfect numbers ourselves by a simple and fast formula that involves small prime numbers.

For list of prime numbers to calculate perfect numbers Perfect

Also, the formula is : 2^(p-1) *2^p -1, where p is a prime number. Implementing the above equation as a function to generate the perfect number instead of that a() function, we get our flag in no time.

import base64
n = 1
i = 0
cipher_b64 = b"MTE0LDg0LDQzNyw4MDk1LDMzNTUwNDM0LDg1ODk4NjkxNzAsMTM3NDM4NjkxMzc2LDIzMDU4NDMwMDgxMzk5NTIyMzUsMjY1ODQ1NTk5MTU2OTgzMTc0NDY1NDY5MjYxNTk1Mzg0MjI0NSwxOTE1NjE5NDI2MDgyMzYxMDcyOTQ3OTMzNzgwODQzMDM2MzgxMzA5OTczMjE1NDgxNjkyOTQsMTMxNjQwMzY0NTg1Njk2NDgzMzcyMzk3NTM0NjA0NTg3MjI5MTAyMjM0NzIzMTgzODY5NDMxMTc3ODM3MjgyMjMsMTQ0NzQwMTExNTQ2NjQ1MjQ0Mjc5NDYzNzMxMjYwODU5ODg0ODE1NzM2Nzc0OTE0NzQ4MzU4ODkwNjYzNTQzNDkxMzExOTkxNTIyMTYsMjM1NjI3MjM0NTcyNjczNDcwNjU3ODk1NDg5OTY3MDk5MDQ5ODg0Nzc1NDc4NTgzOTI2MDA3MTAxNDMwMjc1OTc1MDYzMzcyODMxNzg2MjIyMzk3MzAzNjU1Mzk2MDI2MDA1NjEzNjAyNTU1NjY0NjI1MDMyNzAxNzUwNTI4OTI1NzgwNDMyMTU1NDMzODI0OTg0Mjg3NzcxNTI0MjcwMTAzOTQ0OTY5MTg2NjQwMjg2NDQ1MzQxMjgwMzM4MzE0Mzk3OTAyMzY4Mzg2MjQwMzMxNzE0MzU5MjIzNTY2NDMyMTk3MDMxMDE3MjA3MTMxNjM1Mjc0ODcyOTg3NDc0MDA2NDc4MDE5Mzk1ODcxNjU5MzY0MDEwODc0MTkzNzU2NDkwNTc5MTg1NDk0OTIxNjA1NTU2NDcwODcsMTQxMDUzNzgzNzA2NzEyMDY5MDYzMjA3OTU4MDg2MDYzMTg5ODgxNDg2NzQzNTE0NzE1NjY3ODM4ODM4Njc1OTk5OTU0ODY3NzQyNjUyMzgwMTE0MTA0MTkzMzI5MDM3NjkwMjUxNTYxOTUwNTY4NzA5ODI5MzI3MTY0MDg3NzI0MzY2MzcwMDg3MTE2NzMxMjY4MTU5MzEzNjUyNDg3NDUwNjUyNDM5ODA1ODc3Mjk2MjA3Mjk3NDQ2NzIzMjk1MTY2NjU4MjI4ODQ2OTI2ODA3Nzg2NjUyODcwMTg4OTIwODY3ODc5NDUxNDc4MzY0NTY5MzEzOTIyMDYwMzcwNjk1MDY0NzM2MDczNTcyMzc4Njk1MTc2NDczMDU1MjY2ODI2MjUzMjg0ODg2MzgzNzE1MDcyOTc0MzI0NDYzODM1MzAwMDUzMTM4NDI5NDYwMjk2NTc1MTQzMzY4MDY1NTcwNzU5NTM3MzI4MjQy"print("flag{", end='', flush=True)
cipher = list(map(int,base64.b64decode(cipher_b64).decode().split(",")))
primes = [2,3,5,7,13,17,19,31,61,89,107,127,521,607]#print(len(cipher)) #14while(i < len(cipher)):
print(chr(cipher[i] ^ (2**(primes[i]-1) * (2**primes[i] -1))), end='', flush=True)
i += 1print("}")

Voila! we get our flag.

--

--

Ashish Agarwal

Data Science || Data Engineer || Machine Learning || Linux || Infosec Enthusiast || Math-Physics-Philosophy Trilogy Admirer || Computer Engineer