Dc1ph3r Discord CTF
This was a small CTF hosted on the dc1ph3r discord server and had a total of 3 simple but fun challenges. It turned out at the end that the winner receives a 2 month subscription to pentester lab, so a huge thanks to @MrT4ntr4 for that!
Challenge #1 - Game of Bases
Game_of_Bases.txt there is:
My personal favourite tool for these types of challenges is CyberChef, it allows you to do all kinds of encoding/decoding and other forensics.
For both of the encoded strings, I can tell which base encoding it (most likely) is based off of the character set, which is also shown in CyberChef. The order is base32 -> base64
Challenge #2 - RSAyyy
This challenge was just a simple test of understanding for RSA. You are given Rsay.txt:
n: 379557705825593928168388035830440307401877224401739990998883 e: 65537 c: 244703312358921240309421014098878267031729391832640247437102
The steps to solve RSA when given these are:
- Find p and q
- Get φ(n) AKA phi(n)
- From this, get the private key (d)
Since n = p*q, we need to factor n. Luckily, n already exists in the super handy site factordb now with p and q, we can get φ(n) using the totient function:
phin = (p-1) * (q-1)
We can calculate d as the inverse of e mod φ(n)
import gmpy d = gmpy.invert(e, phin)
and decryption is given using c^d mod n. There is a nice function in python called
pow() which does this well.
m = hex(pow(c, d, n))[2:]
I use the [2:] to get rid of the 0x at the start.
printing this returns the hex string
With the codecs module, we can create a couple simple functions so it doesn't get too messy.
import codecs decode_hex = codecs.getdecoder("hex_codec") decode_b64 = codecs.getdecoder("base64_codec") # We will use this in a second
hex_codec(m) we receive:
b'RkxBR3tGdUNrMW42X1I1QX0K' which is a base64 string.
decode_b64(b64_string).decode('utf-8') and printing out the result, we get the flag!
#!/usr/bin/python3 import gmpy import codecs n = 379557705825593928168388035830440307401877224401739990998883 e = 65537 p = 564819669946735512444543556507 q = 671998030559713968361666935769 c = 244703312358921240309421014098878267031729391832640247437102 phin = (p-1) * (q-1) d = gmpy.invert(e, phin) # print(d*e % phin) = 1 m = hex(pow(c, d, n))[2:] decode_hex = codecs.getdecoder("hex_codec") decode_b64 = codecs.getdecoder("base64_codec") b64_string = decode_hex(m) plaintext = decode_b64(b64_string).decode('utf-8') print(plaintext)
Challenge #3 - Dumb Admin
Created by Corb3nik
Unfortunately, the website for this challenge was shut down and the local files are unavailable, so I'm going to be doing this writeup pretty much from memory :P (I'll update it when/if I have access to the full challenge)
The challenge starts off on a web page, and from viewing the source you can see some weird esolang in place of js. On first look, you might think "Oh, it's brainfuck", but although they look similar it's actually the less well known JSfuck.
Here's some example JSfuck (not the code used in the challenge)
On "decoding" the script with this, we are led towards a page that has php which first checks if its "blacklisted" word is in a get parameter in the url, and if it is it will replace it with nothing. However, later in the script it will give you the flag if that blacklisted word remains in the url.
Similar to some LFI bypass that people may be familiar with, we can abuse the implementation by "sandwiching" parts of the blacklisted words between eachother.
For example, if the blacklisted word was hello this is what would happen:
After doing this, we are presented with the flag!