1 — Base64
This file has been base64 encoded 50 times — write a script to retrieve the flag. Try to do this in both Bash and Python!
- Read input from the file
- Use function to decode the file
- Do process in a loop
To start, let’s first write in bash.
Bash
In bash, to decode encoded texts, you can pipe them like this:
Because challenge wants us to use functions, we can wrap this code like this:
b64decode() {
echo -n "$1" | base64 -d
}
Because bash functions don’t havereturn
statement, we are just echoing. The -n
flag emits the newline and wrapping the function parameter $1
in quotes is a safe practice for handling spaces (because we are dealing with base64 here it’s not that useful, but it’s a good habit to wrap.).
Now we need to save file content to a variable
content=$(cat b64.txt)
Now we need a for
loop to call our function as many times as we want.
for i in {1..50}; do
content=$(b64decode "$content")
done
In bash, we can use either c-style for loops or ranges. The above code is an example of range.
Now we can finish by printing our final string
echo "$content"
Full code would look like this:
Python
In order to use base64 functionality, we need to import it first.
import base64
To decode a string, we can write a simple function like this:
def b64decode(string: str):
return base64.b64decode(string)
To read or write to files, we need to open a file handle. But in this case we don’t need to write, thus we can open the file read-only.
file = open("/tmp/thm/b64.txt", "r")
Load the content of the file and close the handle like this:
content = file.read()
file.close()
Putting everything together:
2 — Gotta Catch em All
You need to write a script that connects to this web server on the correct port, do an operation on a number and then move onto the next port.
- Create a socket in Python using the sockets library
- Connect to the port
- Send an operation
- View response and continue
This challenge is pretty time-consuming. First, let’s start simple. And try to just connect and send a package. Our starting point would be port 1337 and challenge says we might need to wait for it to become alive.
And challenge also says we need to stop if port hits 9765. You can kinda see where we’re going with this. In order to keep trying to connect, we have to wrap our code with try except block and while loop. And because ports change every 4 seconds, if our request fails, we need to wait before sending another.
Now if you run the script and if it can connect to the port we can see some data, but it seems random. We know the format of the required data (The format is: operation, number, next port.) so we can use regex to reliably get operation. After running a couple of times, some of the problems I encountered and their solutions:
Operation regex can get some unwanted texts too, like (ep <number> <number>
) so setting minimum characters would solve it ([a-z]
to [a-z]{3,}
)
Number to operate can contain integers, floats and their negatives, so regex for number would become from [0-9]
to -?[0–9]+\.?[0–9]*
Complete regex:
[a-z]{3,}\s-?[0-9]+\.?[0-9]*\s[0-9]+
Now we can get only what we want. The next step would be to evaluate the extracted string. Putting a variable with initial value of zero and a function to update that would be as follows
Sometimes the same operation can be called multiple times. But we know that a single port won’t be called multiple times. We can leverage that into a control mechanism. After adding that, our code is done.
Everything put together would look like this:
3 — Encrypted Server Chit Chat
The VM you have to connect to has a UDP server running on port 4000. Once connected to this UDP server, send a UDP message with the payload “hello” to receive more information.
Now we need to be able to:
- Send UDP packages
- Use decryption
- Compare hashes
Again starting simple, let us send the required payload to the server.
We are just creating socket and sending packages.
We have information about what to do next, so we are just following instructions and sending another payload.
Lines after goal
variable are added afterwards for convenience. They are just for parsing the response string.
Server instructs us again, we know from the room that, text and tag are sent consecutively. And it’s clear after a couple of tries that we need a while loop because we need our script to run until we find a suitable match.
Now we can write the function to decrypt them. Looking at cryptography
’s documentation, we should import needed functions.
And we solved all challenges.
Thank you for reading! :)