![article-featured-image](/media/posts/5JcZjEbesrCTF5JcZjEbesr.webp)
picoCTF is an open-source project. It's an enhanced platform for education and organizing competitions related to Cyber Security, Forensics, Cryptography, Web exploitation, and many other fields. This post will contain picoCTF challenges and solutions from all categories. There are beginner-level challenges and if you are just starting to step into the cyber security or hacking field, then this article is for you.
However, I won't be providing any kind of files, scripts, or material regarding the challenges themselves. For that, you can visit picoCTF Practice and page get the required material. This article will provide only solutions.
Keep in mind that there are multiple ways to solve any problem. So the solution provided for particular problem is just one way to solve it, there might be another way or perhaps the easy one. If so, do comment below.Mod 26
Cryptography can be easy, do you know what ROT13 is?
cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}
This challenge is about Cryptography. Rot13 is a Cipher. It actually means Rotate by 13 places. As per Wikipedia, "Rot-13 is a letter substitution Cipher that replaces a letter with the 13th letter after it in Latin alphabets". See the below image for a better understanding:
![rot-13 working](/media/uploads/2023/05/02/img1.png)
In our challenge, we get "cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}". By applying the same Rot-13 rule of replacing every character with the 13th character after it, we can decode this message. You can try it yourself if you want or you can use a simple tool that will convert and replace the characters.
Go to Rot13 decorder and paste the text
there. Select 'Rot13' from the list and you'll get your text decoded. So the flag for
this challenge is: picoCTF{next_time_I'll_try_2_rounds_of_rot13_aFxtzQWR}
Python Wrangling
Python scripts are invoked kind of like programs in the Terminal... Can you run this Python script using this password to get the flag?
This challenge is about Python. It's pretty simple actually if you basic Python. You will
get there three files in this challenge: ende.py, pw.txt, and flag.txt.en. But first, you need to install pip package for cryptography, otherwise, the script will give error. Use pip install cryptography
to install the
required library.
Now after running ende.py using python ende.py
, you will get to know about the
usage of this script, like this: Usage:
.\ende.py (-e/-d) [file]. It tells that this script takes two or three
arguments and the last argument is file. That file is flag.txt.en
Options are simple. -e for encoding and -d for decoding. As per challenge, you can use the below command to decode file and extract flag:
python ende.py -d flag.txt.en
You will be asked for password input, get the password frompw.txt file. And there it is, your flag for the challenge is:
picoCTF{4p0110_1n_7h3_h0us3_6008014f}
Wave a flag
Can you invoke help flags for a tool or binary? This program has extraordinarily helpful information...
As you might be aware that there is never one approach to solving the problem. So is this challenge. There might be many other ways but I'll be explaining two ways to solve this challenge. The problem is simple, we have a file named warm, which is a binary file. There is a flag inside the file that we need to extract. Use Linux or Mac for this challenge.
First method:This method is straightforward. if you have some expertise in Linux, then you know that you can read binary files using less command. So, that is what we are going to do. Run the below command:
less warm
![flag in binary](/media/uploads/2023/05/02/img2.webp)
This method took a different approach to solving the problem, which is little bit more
appropriate than the first method. First change the permission of file using
chmod 754 warm
. It is necessary to execute the
file. Then use this command to execute the file with -h option.
./warm -h
There you will get your challenge flag, which is: picoCTF{b1scu1ts_4nd_gr4vy_d6969390}
. You can check
that the flag is same in both methods.
information
Files can always be changed in a secret way. Can you find the flag? cat.jpg
The task in this challenge is same as others: find the CTF flag. This one is a little bit tricky if you are not familiar with metadata. A file named cat.jpg is given. Now you can open the image file and go through with that scala code if you want and try to make sense of it OR you can find a different way.
SolutionOn Linux, you can use exiftool to extract the metadata of any file. First, install the package in the system using below command:
sudo apt install exiftool
Now to check the metadata of 'cat.jpg' using ExifTool, run exiftool cat.jpg
command. You will all the detailed metadata of cat.jpg image file. Copy the value of 'Licence' field because that simply looks like encoded text. Use the below command to decode this Licence value text:
echo cGljb0NURnt0aGVfbTN0YWRhdGFfMXNfbW9kaWZpZWR9 | base64 -d
After decoding, you will have your challenge flag on the terminal. picoCTF{the_m3tadata_1s_modified}
Nice netcat...
There is a nice program that you can talk to by using this command in a shell:
nc mercury.picoctf.net 22342
but it doesn't
speak English...
This task is based on Netcat tool. A command is given where Netcat is used to connect and receive data from mercury.picoctf.net server on port 22342. But first, you need to check if Netcat is installed in your system. It usually comes pre-installed in most Linux distributions. If not, use the below command to install Netcat:
sudo apt install netcat
On Linux, use nc mercury.picoctf.net 22342
command given in the
challenge. It will present you with some random numbers and the challenge is to find the
flag in these numbers. Now if the text is encoded we can decode it using tools like 'base64' but
In this case, it's numbers and they do not look encoded. That's why we have to convert
these numbers into hexadecimal form and then we will convert these numbers into ascii text to extract our flag from it.
echo | nc mercury.picoctf.net 22342 > netcat.txt
Now that we have a file named 'netcat.txt' that contains all the numbers served by the challenge server. Run the below command to convert all the numbers into hexadecimal and then convert hexadecimal into ascii text:
for i in `cat netcat.txt`;do printf "%x" $i;done | xxd -r -p
In the above command, we used some bash scripting to ease the process. We applied
for loop on the content of netcat.txt file and convert all
numbers into hexadecimal using printf "%x" command inside the loop. Then we process the output of previous command using xxd -r -p command to convert hexadecimal into ASCII text, which is our flag for the challenge. picoCTF{g00d_k1tty!_n1c3_k1tty!_5fb5e51d}
Transformation
I wonder what this really is... enc
''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])
For some, this task was easy. But I was kind of stuck in this challenge because I had no prior knowledge about text transformation and characters' decimal value and byte sequence. This task provides a file named 'enc' that contains some Chinese characters. Let me show you what I tried and what works for me to extract the flag.
Attempt 1Almost everyone who knows nothing about Chinese or any other language that they don't Understand, first option is to translate the text. That's what I tried. Copy the Chinese text and paste it into google translate, that's what I got:
![google-translate-result](/media/uploads/2023/05/16/post1.webp)
As you can see, the translation does not point anywhere but it does tell that it's Japanese not Chinese. Then I pay attention to the challenge itself and found out that 'Reverse Engineering' is used in the tag. So I google 'Reverse engineering decoder online' and open CodeBeautify. Paste my Japanese text there and this tool just reverses the string. Now I paste the new text again into Google translator, and I got this:
![google-translate-result-2](/media/uploads/2023/05/16/post2.webp)
At first, I thought it is surely something. As you can see there is python code
''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])
also given in the challenge. So I try to use this translated text with Python code like this:
# attempt.py flag = "The shape" print(''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)]))
![google-translate-result-2](/media/uploads/2023/09/23/1c5e6ctsrfr.webp)
It clearly shows there is an issue with the code. Either the passed flag is not correct or there might be issue with the code provided in the challenge. So after trying many things and using 'The shape' as input (I even used Japanese text as flag variable instead of 'The shape' in script, but got the same error), I came to the conclusion that maybe it's not the right approach. So I leave it here and move on to the alternative.
Attempt 2After first attempt, I tried to check the metadata of 'enc' file to get some information. Used this exiftool command for metadata:
exiftool enc
![google-translate-result-2](/media/uploads/2023/09/23/2cdrge5tce.webp)
Nothing much information except the Encoding type used is 'UTF-8'. I'm not familiar with Japanese, so by just looking at Japanese, I could not figure out if the text is in an Encoded or Decoded state. I tried UTF-8 text decoding to see what output it produces and I got this:
echo -n "灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽" | iconv -f UTF-8 -t UTF-8
The output was also in Japanese and looks like the text is already in the decoded state. So if decoded text is in Japanese then I should try encoding it because the encoded text is usually in English and since our flag is also supposed to be in English, It seems the right approach to follow.
- Encoding or Decoding characters is a pretty crafty skill and sometimes a little bit confusing too, especially if you are a noob in this field like me. To be fair, I did not know much about character encoding schemes before this challenge. I only knew about UTF-8 and ASCII. As I get to know more about encoding schemes, I found out that UTF-8 and ASCII are somewhat related. Long story short, characters encoded using ASCII scheme will appear the same if decoded using UTF-8. So I decided to encode this Japanese text using various encoding schemes to see what output it produces.
- There is no point in using the ASCII scheme to encode UTF-8 characters because the number of possible characters in both encoding schemes are very different. ASCII only has 128 possible characters (A-Z, a-z, 0-9) including punctuation marks. But UTF-8 has about 1 million defined characters for different languages. So encoding UTF-8 characters using ASCII is not possible.
- So I gather a list of some known character encoding schemes that I'll be trying on this Japanese text to encode it and try to make sense of the output. I tried: UTF-16, UTF-32, EUC-JP, ISO-8859 to encode our Japanese challenge text. While encoding characters, Some schemes give errors while some produce output that does not make any sense. But only UTF-16 produces output that was appropriate and verified that I'm on the right track. Below is the Python code:
chars = "灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽" encoded_text = chars.encode('utf-16') print(encoded_text)
![python-text-decoding](/media/uploads/2023/09/23/3xfoumxf8.webp)
Now that does look like flag, but the format is not correct. Characters appear to be shuffled back and forth. I only get this result using the UTF-16 encoding scheme, other schemes do not produce valuable output.
So I search more about UTF-16 and get to know that there are actually two variations of UTF-16. One is UTF-16le means 'UTF-16 Little Endian' and second is UTF-16be means 'UTF-16 Big Endian'. So I give them a chance to encode the Japanese text using the following script:
chars = "灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽" encoded_text = chars.encode('utf-16be') print(encoded_text)
![python-text-encoding](/media/uploads/2023/09/23/4pl9aidaw9d.webp)
And there it is, our challenge flag. I also tried 'UTF-16le'
and the result was better than 'UTF-16' but flag was not correct. But only using
UTF-16be as an encoding scheme, I was able to extract the flag from the Japanese text. The flag itself says '16 bits instead of
8'. So here it is, your challenge flag: picoCTF{16_bits_inst34d_of_8_e141a0f7}
Even though I managed to find the flag from Japanese text, I could not get this ''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])
Python code out of my head that is given in the challenge. There has to be some way to
extract flag from Japanese text using this code.
So I again try the code by passing the text 灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽
as input. But the code
gives "IndexError: string index out of range" error again, same as
before. Now the reason for this error is that
I am iterating through the string with a step of 2 (range(0,
len(flag), 2)), but the length of the string is odd (there are total 19
characters in given Japanese text). This means that there is an odd number of characters,
and when you try to access the character at the last index plus one (flag[i + 1]), it goes beyond the valid range of index and
gives error.
So far, I reach the conclusion that the given code is not correct (as per the given Japanese text). So I break down the Python code and try to modify it. After getting to know about binary sequence left and right shifts in Unicode character decimal value, I managed to write a Python script that successfully convert the given Japanese text to a challenge flag. This is my Python code:
enc = '灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽' flag = '' for i in range(len(enc)): # Shifting the character decimal value by 8 bits to manipulate the binary representation of the character highest = ord(enc[i]) >> 8 # In right shift, decimal value is divided by 256 lowest = highest << 8 # In left shift, decimal value is multiplied by 256 char_sec = chr(ord(enc[i]) - lowest) # converting decimal value to it's respective character flag += chr(highest)+char_sec print(flag)
Now i have also try to describe how this code works. So the idea behind this code is shifting the binary representation of particular character to either left or right by 8 bits. Based on the direction of shift, we get new decimal value (by multiplying or dividing
the old decimal value based on the shift direction). Then we convert the decimal value into
it's respective character and there it is, our challenge flag: picoCTF{16_bits_inst34d_of_8_e141a0f7}
By understanding the decimal values of characters actually made it easy for me to write this
script.
Stonks
I decided to try something noone else has before. I made a bot to automatically
trade stonks for me using AI and machine learning. I wouldn't believe you if you told me
it's unsecure! vuln.c
nc mercury.picoctf.net 33411
This challenge is about the C programming language. If you know C, then it'll be easy for you to complete this challenge and acquire the flag. However, I did not know much about C language. My poison is Python and which is why I struggled to find the flag.
SolutionOn Linux, use nc mercury.picoctf.net 33411
command given in the
challenge. After selecting option 1, It asks to enter API
Token, and finding this API Token is actually the challenge here.
File named vuln.c that comes with the challenge, is actually the code of this bot, written in C language. If we check closely, even not knowing C much we can still see that the API token required by this bot does not do much. It just prints back the API Token that you enter. It does not matter what API Token you enter because the code does not check the API Token entered by the user.
So after bashing my head in this code for some time, I come to realize that either I learn C language or have little help from someone who know their stuff.
I came across this similar challenge on GitHub. The code is different but the idea behind soluiton is similar. It turns out that printf function is vulnerable to a string format attacks using string specifiers such as %x or %p in the input. It happens when we don't use static format string like "%s" which explicitly specifies that user input should be treated as a string and not as a format specifier.
Long story short, If you enter "%p" in API Token input, the output by printf function will be in hexadecimal values. Make sure to enter "%p" at least 32 times like this:
![challenge-image-1](/media/uploads/2023/05/18/post1.webp)
Copy this hex value in a new file. And run the below command to reformat that hex file in readable manner:
sed -i 's/0x/\n0x/g' hex_file
0x8515430 0x804b000 0x80489c3 0xf7f73d80 0xffffffff 0x1 ... ...
Now if you see, there are also some ASCII characters in hexadecimal values which are unusual. Hexadecimal is usually represented by numerical values from 0 to 15 and it does not inherit ASCII characters. So i opened CyberChef and paste our hexadecimal value in input and by using From Hex operation, i get this value:
![challenge-image-2](/media/uploads/2023/05/18/post2.webp)
You can clearly see the flag in the output. But the format of the flag is not correct. To correct the format we need to know which hex block containing ASCII characters translates into which character. I have written this Bash script (named 'hex_binary.sh') for this purpose. Copy this script into a new file.
#!/bin/bash hex_sequence=$(cat hex_file) for i in $hex_sequence do echo -e $i | xxd -r -p >> clear echo >> clear done echo "File saved in $PWD with name: clear"
Run this bash script using below command. It will create a new file by the name of "clear". This file contains flag along with binary data reversed from the hex file.
bash hex_binary.sh
Now open the file named clear which is generated by the script. Remove all the binary characters from the file. Make sure you do not change the formatting of the file or remove any non-binary characters. After saving changes, your file should look like this:
![challenge-image-3](/media/uploads/2023/05/18/post3.webp)
Make sure your file looks exactly like this and there are no binary characters in the file otherwise next part will not work. Now run the below command to correct the format of the flag:
cat clear | rev | tr -d '\n'
![challenge-image-3](/media/uploads/2023/09/23/5aodkaw9.webp)
And there it is, your challenge flag in the correct format, extracted from the C language bot by exploiting printf function vulnerability.
Warmed Up
What is 0x3D (base 16) in decimal (base 10)?
This challenge is about general decoding skills. Hexadecimal number is provided that need to be converted into its decimal representation.
SolutionIn Linux, the solution to this challenge is very simple. Using this simple command we can get the decimal representation of any given hexadecimal number. Run the below command:
printf "%d" 0x3D
echo picoCTF{$(printf "%d" 0x3D)}
This command will produce picoCTF{61}
as output and that is your challenge flag.
Static ain't always noise
Can you look at the data in this binary: static? This BASH script might help!
This challenge is about general skills. Files provided in this challenge are a binary file and BASH Script. The challenge is to find the flag from the Binary file.
SolutionUsing Linux, the solution for this challenge is very simple and easy. First, open the BASH Script that is provided in the challenge. You will notice that the script takes a command line argument. Pass the binary file as an argument while executing the BASH Script or use the command below:
bash ltdis.sh static
This Bash Script will create two files in the current working directory. Open the file with name static.ltdis.strings.txt and look for the flag in the file or you can use the below command to print the line containing flag:
cat static.ltdis.strings.txt | grep pico
And that is your flag picoCTF{d15a5m_t34s3r_98d35619}
, in the file created by BASH Script.
Tab, Tab, Attack
Using tabcomplete in the Terminal will add years to your life, esp. when dealing with long rambling directory structures and filenames: Addadshashanammu.zip
This challenge is about general skills. Addadshashanammu is the ZIP file provided in the challenge and the task is the same, to find the flag.
SolutionFirst, we need to unzip the file. In Linux, we can use unzip to extract the ZIP file. You need to have unzip installed in your system. Run the below command to install unzip the package and extract Addadshashanammu file:
sudo apt install unzip$
unzip Addadshashanammu
Now the challenge is all about the understanding of terminal. When we are exploring the filesystem from terminal, we always use TAB to autocomplete our initial text to the most appropriate match from the present directory. Same principle applies here.
After extracting the ZIP file, a directory should be created by the same name. Type
cd Addadshashanammu/
in the terminal and then press TAB repeatidly until there is no
autocomplete. At the end of the directory, there should be a file named
fang-of-haynekhtnamet which is a binary file containing our challenge flag. Run the below command to extract flag from the binary file:
strings -a -t x fang-of-haynekhtnamet|grep pico
This command will output the challenge flag. That is how you get the flag from binary file which is at the end of the directory tree.