picoCTF 2021 Writeups: General Skills

·7 mins


These are my writeups for the “General Skills” category from picoCTF2021. These were not hard, but they offer some important background knowledge for solving more difficult challenges.

Obedient Cat (5 points) #

Description #

This file has a flag in plain sight (aka “in-the-clear”). Download flag.

Solution #

This problem was just a sanity check, download the file and open to get the flag picoCTF{s4n1ty_v3r1f13d_4a2b35fd}

Python Wrangling (10 points) #

Description #

Python scripts are invoked kind of like programs in the Terminal… Can you run this Python script using this password to get the flag?

Solution #

For this problem we are given 3 files: a python script, a password file, and an encrypted flag.

Looking at the program, we just need to run it, supplying the encrypted flag file, and then entering the password.

[email protected]:~/python-wrangling/$ python3 
Usage: (-e/-d) [file]
[email protected]:~/python-wrangling/$ python3 -d flag.txt.en < pw.txt
Please enter the password:picoCTF{4p0110_1n_7h3_h0us3_68f88f93}

Wave a flag (10 points) #

Description #

Can you invoke help flags for a tool or binary? This program has extraordinarily helpful information…

Solution #

For this challenge we are given a file, so first thing to do is figure out what it is using file.

[email protected]:~/wave-a-flag$ file warm 
warm: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, for GNU/Linux 3.2.0, BuildID[sha1]=7b3da2efd83a2b9154697b6c7f6474042e1fd033, with debug_info, not stripped

So now that we know its an ELF binary, we can mark it as executable chmod +x warm and run it.

[email protected]:~/wave-a-flag$ ./warm 
Hello user! Pass me a -h to learn what I can do!

We can see that there’s a help function… let’s check it out!

[email protected]:~/wave-a-flag$ ./warm -h
Oh, help? I actually don't do much, but I do have this flag here: **picoCTF{b1scu1ts_4nd_gr4vy_6635aa47}**

Et voila! We have our flag. Alternatively this could’ve been solved using strings or opening the binary in Ghidra or some other disassembler.

Nice netcat… (15 points) #

Description #

There is a nice program that you can talk to by using this command in a shell: $ nc 49039, but it doesn’t speak English…

Solution #

We are given a command for this challenge nc 49039. It wants us to use netcat which is an incredibly versatile tool that allows you to do a bunch of fun stuff with TCP and UDP.

When we connect we are given these values, which look like ascii codes!

112 105 99 111 67 84 70 123 103 48 48 100 95 107 49 116 116 121 33 95 110 49 99 51 95 107 49 116 116 121 33 95 51 100 56 52 101 100 99 56 125 10

I wrote a quick little solve script to grab the info and then spit out our flag!

from pwn import * 

#Setup a connection to the server with pwn
server = remote("", 49039)

#Read the numbers, decode the output, and split on the newlines
numbers = server.recv().decode("utf-8").splitlines()

#Create a string of the decoded ascii values and print!
print("".join([chr(int(i)) for i in numbers]))

#[+] Opening connection to on port 49039: Done

Static ain’t always noise (20 points) #

Description #

Can you look at the data in this binary: static? This BASH script might help!

Solution #

For this problem we are given two files, static which is a 64-bit executable, and which is a bash script. Running file on static we can see the details…

$ file static 
static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, for GNU/Linux 3.2.0, BuildID[sha1]=7eb9ee1907cc878f15f9949988893b1f0ab1ebdf, not stripped

Next, we can examine the contents of the bash file we are supplied…


echo "Attempting disassembly of $1 ..."

#This usage of "objdump" disassembles all (-D) of the first file given by 
#invoker, but only prints out the ".text" section (-j .text) (only section
#that matters in almost any compiled program...

objdump -Dj .text $1 > $1.ltdis.x86_64.txt

#Check that $1.ltdis.x86_64.txt is non-empty
#Continue if it is, otherwise print error and eject

if [ -s "$1.ltdis.x86_64.txt" ]
	echo "Disassembly successful! Available at: $1.ltdis.x86_64.txt"

	echo "Ripping strings from binary with file offsets..."
	strings -a -t x $1 > $1.ltdis.strings.txt
	echo "Any strings found in $1 have been written to $1.ltdis.strings.txt with file offset"

	echo "Disassembly failed!"
	echo "Usage: <program-file>"
	echo "Bye!"

The script is basically just a wrapper around objdump which is a tool that extracts information from object files (the things that get linked into executable binaries!). It is getting the readable strings from .text which is a section in executable files containing well, text!

To use this script we first need to make sure its executable, which can be done using the command chmod +x This will change the file permissions of the bash script to eXecutable (what the +x means) so that we can run it. Tidbit, if you want to remove that permission you do almost the same thing but change the + to a - so chmod -x

Then we run the script, supplying static as the first argument ./ static and see that it gives us two files as output.

[email protected]:~/ctfs/picoctf2021/static-aint-always-noise$ ls  static  static.ltdis.strings.txt  static.ltdis.x86_64.txt

We can see that static.ltdis.strings.txt and static.ltdis.x86_64.txt. The strings file contains the information from .text and the other file contains a disassembly of the .text section.

Odds are the information we want is inside the strings file so we use grep to search for it: cat static.ltdis.strings.txt | grep picoCTF{ and sure enough we get our flag!

[email protected]:~/ctfs/picoctf2021/static-aint-always-noise$ cat static.ltdis.strings.txt | grep picoCTF{
   1020 picoCTF{d15a5m_t34s3r_ae0b3ef2}

Tab, Tab, Attack (20 points) #

Description #

Using tabcomplete in the Terminal will add years to your life, esp. when dealing with long rambling directory structures and filenames:

Solution #

We are given a zip file for this challenge, containing a few directories with super long names. The idea for this challenge was to use tab completion to move through the directories without having to type out the names. In bash (or any shell), if you type part of a command and then hit tab, bash will do its best to autocomplete the rest of the thing you want. In our case we just need to type the first few letters of the directory and then we can tab to complete it.

$ ls

$ unzip 
   creating: Addadshashanammu/
   creating: Addadshashanammu/Almurbalarammi/
   creating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/
   creating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/
   creating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/
   creating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/
   creating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku/
  inflating: Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku/fang-of-haynekhtnamet  

$ cd Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku/

~/Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku$ ls
fang-of-haynekhtnamet # We have a file!!

After working our way through the directories we end up seeing a file called fang-of-haynekhtnamet. Running file on it we can see that it’s an executable! Running it gets our flag.

/Addadshashanammu/Almurbalarammi/.../$ file fang-of-haynekhtnamet
fang-of-haynekhtnamet: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, for GNU/Linux 3.2.0, BuildID[sha1]=47e898db922f38cb54ab4a08fb4e3def5a1cb6a1, not stripped
[email protected]:~/programming/ctfs/picoctf2021/tab-tab-attack/Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku$ ./fang-of-haynekhtnamet 
*ZAP!* picoCTF{l3v3l_up!_t4k3_4_r35t!_a00cae70}

Magikarp Ground Mission (30 points) #

Description #

Do you know how to move between directories and read files in the shell? Start the container, ssh to it, and then ls once connected to begin. Login via ssh as ctf-player with the password, redacted

Solution #

This challenge wanted us to ssh into a server and then move around finding parts of a flag. To login to a server via ssh use the command ssh [email protected] and then supply the password when asked.

When we first login and run ls to list the current directory, we can see two files. One of these contains the first third of our flag, and the other contains instructions on where to go next. It tells us we need to go to “the root of all things, more succinctly |”. In linux, the root directory, which is basically the beginning of the file structure, is located at /. To change directories we use the cd command.

[email protected]$ ls
1of3.flag.txt  instructions-to-2of3.txt
[email protected]$ cat 1of3.flag.txt
[email protected]$ cat instructions-to-2of3.txt
Next, go to the root of all things, more succinctly `/`

Once we are in the root directory if we ls again we can see two more files! The second third of our flag and more instructions! This one tells us to “go home” which means our home directory. The shortcut for getting there is to cd into ~, or just cd.

[email protected]$ cd /
[email protected]$ ls
2of3.flag.txt  dev   instructions-to-3of3.txt  media  proc  sbin  tmp
bin	       etc   lib		       mnt    root  srv   usr
boot	       home  lib64		       opt    run   sys   var
[email protected]$ cat 2of3.flag.txt
[email protected]$ cat instructions-to-3of3.txt
Lastly, ctf-player, go home... more succinctly `~`

Once there we can see the end of our flag! Just stick them all together and there ya go!

[email protected]$ cd ~
[email protected]$ ls
3of3.flag.txt  drop-in
[email protected]$ cat 3of3.flag.txt
[email protected]$ file drop-in/
drop-in/: directory
[email protected]$ cd drop-in/
[email protected]$ ls
1of3.flag.txt  instructions-to-2of3.txt