I’m super excited to be writing my first CTF challenge writeup! This CTF was a lot of fun, and I learned some new skills!

If you have questions about a challenge or one of my explanations feel free to poke me: @CharCharBonkles

Table of Contents (The challenges I solved):

Linux

Talking to the Dead 1

Talking to the Dead 1 Challenge Description

First, log in to the SSH Server using the given credentials:

ssh hacktober@env.hacktober.io

Then, figure out what’s in our current directory, and use the linux find command to locate the flag.

Cat the file and submit the flag!

flag{cb07e9d6086d50ee11c0d968f1e5c89418c}

Talking to the Dead 2

Talking to the Dead 2 Challenge Description

Log in and poke around… This time, run ls -al to get a bit more information than we did last time…

flag{728ec98bfaa302b2dfc2f716d3de7869f3eadcbf}

Talking to the Dead 3

Talking to the Dead 3 Challenge Description

This challenge is a little more complicated… First, let’s find the flag!

This time, the flag is in someone else’s documents folder. Let’s try to cat it:

Hmmmmmm, that didn’t work. We don’t have the correct permissions. Only spookyboi and members of the spookyboi group can access the flag 1 :

We aren’t in the spookyboi group either:

We have to figure out how to log in as the spookyboi user… If we look at the challenge titles, there’s another challenge that might give us some information on spookyboi… Check out Past Demons and then come back!

Now we have spookyboi’s password: zxcvbnm, and can su to his user and read the flag!

flag{445b987b5b80e445c3147314dbfa71acd79c2b67}

Talking to the Dead 4

This challenge writeup is by one of my teammates, @Geeg007!

Talking to the Dead 4 Challenge Description

So obviously its READ questions first…

Ohh there are ssh detials provided aha that saves dude from bruteforcing (weak passwords)

So let’s login.

hehe we’re IN, so i’m laying hands where possible

So i searched and aha FIRST sight at flag4.txt And yes it’s in /root directory so let’s goooo!!!

find / -name flag4.txt

Ahhh I thought I had you (flag4.txt)… I probably need root access to view this file!

So let’s cd to / and look for setuid bits using:

find . -perm /4000 &2>/dev/null

So everything looks pretty standard yeah? Not quite - I’m interested in finding out what ouija is in this box…

So cat ./usr/local/bin/ouija apparently gave us a clue for how to use the setUID binary.

Because the ouija binary has extra permissions, we can use it to view the contents of flag4.txt even though our user doesn’t have permissions!

flag{4781cbff13df6622565d45e790b4aac2a4054dc}

Gotcha!!! Thanks to CyberUp & Cyber Hacktics for this wonderful challenge. Also to my teammates CharCharBinks (C), J0hn_W1ck & HarleyHacker for having me in the team also providing moral & technidcal support. LOVE YA

Programming

Message in an Array

Message in an Array Challenge Description

At first, I didn’t see the code in the challenge description, but when I did I copied it to vistual studio code to make it more readable:

This code looks like c++, and it creates an array of strings of length 4:

string[] str = new string[4] {"DEADFACE", "Nothing", "Stop", "Will"};

And then it prints the contents of the array in a specific order:

Console.WriteLine("{1} {3} {2} {0}", str);

When we re-order the words from the string in the order specified in the Console.WriteLine statement, we get:

Nothing Will Stop Deadface

So our flag is:

flag{Nothing Will Stop DEADFACE}

Remember that programming array indices start at zero!

Stego

Ghost Hunter

Ghost Hunter Challenge Description

Because the challenge description mentioned that it was intercepted on the Ghost Town forum, I decided to look around to find more information. On one of the threads, I found this comment:

https://www.ghosttown.xyz/t/haunted-pictures/33/7

Then I searched google until I found a stego tool that worked!

http://manytools.org/hacker-tools/steganography-encode-text-into-image/

flag{8862a805a3140996343da91bdcbda79e}

Blasphemy

Blasphemy Challenge Description

The challenge description mentions “some kind of tool” and the most common steganography tool for .jpg files is steghide!

I always have to look up how exactly to use steghide, and I usually wind up on this page: http://steghide.sourceforge.net/documentation.php

flag{950634ccc97ca3ef03e22c759a356973}

Cryptography

Shameless plug: I wrote this blog post on beginner CTF Cryptography, and it has more information about all of the ciphers used in the challenges that I solved!

Hail Caesar!

Hail Caesar Challenge Description

The challenge name and the attached image (a code wheel) are both clues to the type of cipher used to encrypt the message! The correct cipher for this challenge is the caesar cipher.

I used this tool to decrypt the message: http://rumkin.com/tools/cipher/caesar.php

Our flag is: BOO SCARED YOU

Down the Wrong Path

Down the Wrong Path Challenge Description

The attached image contains the following text:

RMTLOBBTERSUXT
EBOLOOOHWGORTA
METSKIUETEFNAC
EREPYATNATOETK

Because the text is arranged in columns (rows) it’s likely that the cipher used for this challenge is columnar transposition.

This is the tool I used to solve this challenge:

https://www.boxentriq.com/code-breaking/columnar-transposition-cipher

Columnar Transposition Cipher Tool Results

The spacing was a bit off, but the top result is what we’re looking for!

remember to tell spookyboi about the new targets of our next attack

Because the challenge asks for the intended recipient, our flag is:

spookyboi

Cover your Bases

Cover your Bases Challenge Description

Again, the challenge title is a hint! “Bases” is referring to base 64 encoding. So, all we have to do is use a base64 decoding tool to get the flag!

ZmxhZ3tzaG91bGRhX21hZGVfdGhpc19vbmVfaGFyZGVyfQ==

The tool I used is: https://simplycalc.com/base64-decode.php

flag{shoulda_made_this_one_harder}

SQL

Have I mentioned that I love databases? If you want some foundational information about databases (with a sprinkling of SQL injection), check out An Introduction to Relational Databases for Hackers by yours truly!

Past Demons

Past Demons Challenge Description

First, let’s figure out what kind of database we’re dealing with by using the linux file command:

SQLite file type

The database dump file we have is for sqlite3.x and fortunately kali linux comes with sqlite 3 installed!

Using the information from this webpage, we can load the .db file into sqlite and run queries! I was super lazy and didn’t want to use a join, so I just ran two separate queries:

select * from passwd;

and

select * from users;

In the users table, spookyboi’s primary key is 8, so if we match that with the 8th password hash we should have spookyboi’s password hash…

Loaded file into DMBS

But the challenge asks for spookyboi’s password, so we have to crack it… My go-to first stop for cracking hashes is crackstation.

Using the hash from the database as input: 59DEA36D05AACAA547DE42E9956678E7

Crackstation Results

And voila! We have spookyboi’s password!

flag{zxcvbnm}

Address Book

Address Book Challenge Description

This SQL challenge involves another type of database dump! According to the linux file command, this is just UTF-8 encoded text… With very long lines… So, I opened it up in good ole VS Code:

shallowgraveu.sql file type

I know my screenshot is really small, but using information from the intel page (luciafer’s first and last name) I used the built in search function to locate Lucia’s email address:

VS Code display of file contents

flag{luciafer.b4vr0n@shallowgraveu.com}

Calisota

Before we can complete this challenge, we have to Load the MySQL Dump file into a DMBS so we can run queries. Once that’s done, we can start querying the database!

Disclaimer: there were scoring issues for this challenge so I didn’t end up getting points for it but I believe I did get the correct answer! Without further ado, here’s my solution!

Calisota Challenge Description

First, let’s take a look at the fields in the users table:

select * from users limit 10;
Calisota Challenge Description

And then, let’s take a look at the states table:

select * from states limit 10;
Calisota states table

Now that we know the contents of the users table and the states table, we can write a query to join the two tables together. This will make sure we’re pulling the right information out of the tables we’re interested in before we start filtering and counting:

SELECT users.username, states.state_abbrev FROM users
INNER JOIN states ON users.state_id=states.state_id
LIMIT 10;
Calisota Challenge Description

We’re getting usernames and state abbreviations, so far so good! Let’s add some conditions to our query - we want students from only CA and MN:

SELECT users.username, states.state_abbrev FROM users
INNER JOIN states ON users.state_id=states.state_id
WHERE state_full='California' OR state_full='Minnesota';
Calisota Challenge Description

Now our results are limited to users from CA and MN… But the challenge asks for the count!

So now we use the builtin SQL count() function:

SELECT count(*) FROM users
INNER JOIN states ON users.state_id=states.state_id
WHERE state_full='California' OR state_full='Minnesota';
Calisota Challenge Description

Voila! That query should have been a correct answer! However, because the entire query is the answer, there are many many different ways we could have solved this question… And only one right answer :(

Body Count, Null and Void, Fall Classes

Body Count

Before we can complete this challenge, we have to Load the MySQL Dump file into a DMBS so we can run queries. Once that’s done, we can start querying the database!

Body Count Challenge Description

Let’s take a look at the users table:

select * from users limit 10;
SQL Users Table

Now that we know what the users table looks like, we can run the following query to get the number of rows (or records) from the users table:

select count(*) from users;
Body Count Challenge Description

Flag{900}

Null and Void

Before we can complete this challenge, we have to Load the MySQL Dump file into a DMBS so we can run queries. Once that’s done, we can start querying the database!

Null and Void Challenge Description

This challenge asks us to identify a single command to figure out which fields in the users table can be null.

My first attempt worked, but it was not considered correct:

Null and Void Challenge Description

The DESCRIBE command was the correct answer for this challenge:

Null and Void Challenge Description

flag{middle,DESCRIBE}

Fall Classes

Before we can complete this challenge, we have to Load the MySQL Dump file into a DMBS so we can run queries. Once that’s done, we can start querying the database!

Calisota Challenge Description

First, let’s run a couple queries to figure out what kind of data we’re dealing with:

Calisota Challenge Description

The data we’re slooking for is in the term_courses table - it represents a many to many relationship between courses and terms. We’re looking for the number of courses being offered for FALL2020 which means that our term_id must equal 2. We also don’t want any duplicates:

SELECT COUNT(DISTINCT course_id) from term_courses where term_id=2;
Calisota Challenge Description

flag{401}

90’s Kids

Before we can complete this challenge, we have to Load the MySQL Dump file into a DMBS so we can run queries. Once that’s done, we can start querying the database!

Calisota Challenge Description

First, let’s take a look at the users table, and fiddle around with extracting parts of the date field into separate fields so we can filter our results:

Calisota Challenge Description

Now that we know how to extract information from the date field, we can pull out the month and year separately, which will make writing our WHERE clause much easier:

Calisota Challenge Description
select username, EXTRACT(YEAR FROM dob) as year, EXTRACT(MONTH FROM dob) as month from users WHERE ((EXTRACT YEAR FROM dob) >= 1990 AND (EXTRACT YEAR FROM dob) <= 1999) AND EXTRACT (MONTH FROM dob) = 10;
Calisota Challenge Description

Now that we’ve verified that we’re getting correct results (only years in the 1990’s and October or 10 for the month) we can clean up our query and count:

SELECT COUNT(username) FROM users WHERE ((EXTRACT YEAR FROM dob) >= 1990 AND (EXTRACT YEAR FROM dob) <= 1999) AND EXTRACT (MONTH FROM dob) = 10;
Calisota Challenge Description

Bonus screenshot: the full result set:

Calisota Challenge Description

flag{32}

Jigsaw

Jigwaw Challenge Description

This challenge asks us to match a specific pattern, and what better way to match a very specific pattern than regex! Let’s start with the information we know and what we need to know to write some regex, and then a SQL query to give us our answer!

First, let’s create some regex to match the specific pattern we’re given:

Condition Regex Explanation
The first two characters are K R or I [KRIkri]{2} We need both upper and lower case because the first letter of the name will be uppercase and the second letter will be lowercase.
Wildcard - any character except newline . Pretty self explanatory - the . character represents any character except newline.
Three letters [a-z]{3} This regex matches any letter, three times.
The last letter is e-n inclusive [e-n] This group matches the letters e-n only once.

So our full regex statement is: ^[KRIkri]{2}.[a-z]{3}[e-n]{1}

Regex is tricky, here are my favorite tools/cheatsheets:

CyberChef

Regexplained

Regexr

Regex Cheat Sheet

Here’s the “regexplanation”2 for the expression I wrote for this challenge:

Jigsaw Regexplained

If we read the information carefully we can infer that the total length of the last name is seven characters:

  • Two first letters
  • One wildcard
  • Three more letters
  • One last letter

The appropriate SQL query that makes use of all this information is:

SELECT first, last, username from users where last REGEXP '^[KRIkri]{2}.[a-z]{3}[e-n]{1}' AND LENGTH(last)=7;
Jigsaw Solution

flag{image.wa1k3624}

For more information on using regex with MySQL:

https://dev.mysql.com/doc/refman/8.0/en/regexp.html

https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/

https://www.guru99.com/regular-expressions.html

Loading the MySQL Dump

We need to be able to load the MySQL Dump file into a DBMS to be able to solve several challenges, and there’s enough content so I decided to break this out into its own section!

First, start the MySql Service and make sure your version is compatible - the same major version should do!

Loading the MySQL Dump

Then, start the service again with --skip-grant-tables because I didn’t want to bother with the “what in the world is my MySQL root password” dance…

Then, log in as root because I like to live on the edge (VM Snapshots encourage risky behavior):

mysql -u root

Create a database to load our data into, and then switch to it:

CREATE DATABASE hacktober;
USE hacktober;

Finally, load the MySQL Dump file into our new database:

SOURCE /path/to/MySQL_DumpFile/shallowgraveu.sql
Loading the MySQL Dump

OSINT

Creeping 1

Creeping 1 Challenge Description

Let’s be honest… We love some good ole internet creeping! The best place to find information about people is facebook… Unfortunately, you have to be logged into an account to be able to solve these challenges. I googled Ali Tevlin’s handle (alitevlin) that I found on the intel page, and came up with this informaiton from his facebook page:

flag{F. Kreuger Financial}

Creeping 2

Creeping 2 Challenge Description

Ali Tevlin’s job title is listed under his place of work:

flag{Senior Acquisitions Supervisor}

Creeping 3

Creeping 3 Challenge Description

Let’s find his birthday! It is also listed on facebook:

Creeping 3 Facebook Birthday

flag{17 06 1973}

Traffic Analysis

Time to show wireshark some love!

Remotely Administrated Evil

Remotely Administrated Evil

Remotely Administrated Evil 1 Challenge Description

The challenge description gives us several clues for what to look for - the most notable being that our answer will be contained in a URL. Let’s filter our traffic for just HTTP Traffic:

http

Our flag is the file name:

Flag{solut.exe}

Remotely Administrated Evil 2

Remotely Administrated Evil 2 Challenge Description

Another day, another pcap! now we’re looking for post-infection traffic, specifically a MYDDNS domain that the malware communicates with. Let’s build a bit off of our last challenge to find the traffic we’re looking for. Because of the malicious download that we’ve already identified, we know the ip address of the compromised host!

172.16.1.219

Now we build a traffic filter:

ip.addr == 172.16.1.219

Set your wireshark preferences to resolve DNS for you:

Then, just scroll through the traffic until you see something related to MYDDNS. You could probably write a filter for this, but at the time I had no idea what type of traffic would be related to MYDDNS so I just went for it.

flag{solution.myddns.me}

Remotely Administrated Evil 3

Now we have the challenge of identifying the type of malware infection! We know several critical pieces of information:

  • The initial delivery method (download url)
  • A probable C2 Server
  • We could probably even extract the malicious file!

Let’s see what virustotal says about our initial download url:

I poked around for a bit and eventually arrived at this report:

https://bazaar.abuse.ch/sample/b16b3d99441f078e081e2ac0a8f0121ce4dab264bf434e353d1e00a57e54d3aa/

flag{netwire}

Evil Corp’s Child

Evil Corp’s Child

Evil Corp's Child 1 Challenge Description

We’ve got a lot of traffic but not a lot of clues… A very common method of malware delivery is over HTTP (as seen in the last challenge) so let’s start there:

http
Evil Corp's Child 1 Challenge Description

That’s interesting…. the only HTTP request has a… jpg file? But that doesnt look malicious! Let’s extract the file and see what it really is:

Evil Corp's Child 1 Challenge Description
file picture2.jpg
Evil Corp's Child 1 Challenge Description

The linux file command confirms our suspicions… The image file is actually a windows executable!

flag{picture4.png}

They tried to pull a fast one on us…

Evil Corp's Child meme

Evil Corp’s Child 2

Evil Corp's Child 2 Challenge Description

This challenge description gives us quite a lot to go on! We know that our malware will be communicating from our compromised IP from the last challenge 192.168.1.91 and that the traffic we’re looking for is over the same port as HTTPS, or port 443.

Building our wireshark filter from this information:

ip.addr == 192.168.1.91 && tcp.port == 443

We also want to look at traffic after our initial infection, so we’ll start looking after packet No. 231

This traffic looked suspect, and as it happens it’s the right address!

flag{213.136.94.177}

Evil Corp’s Child 3

Evil Corp's Child 3 Challenge Description

For this challenge, we have to hunt down certificate! We’re given the ip address that provides the certificate: 37.205.9.252.

Let’s filter our traffic by that address and look for a key exchange:

ip.addr == 37.205.9.252

The bulk of the traffic that we see right away is TLSv1.2. We’re looking for information about a certificate, so it makes sense to look in the packet that says it has certificate information

We’re looking for the locality name, so we have to drill down a bit further:

There it is! LocalityName=Mogadishu

flag{Mogadishu}

Evil Corp’s Child 4

Evil Corp's Child 4 Challenge Description

I’ll take malware strain identification for 100, Alex!

Fortunately, we have a malware sample from Evil Corp’s Child - Part 1 that we can upload to virus total! Behold, it’s Dridex!

flag{Dridex}

An Evil Christmas Carrol

An Evil Christmas Carrol 1

An Evil Christmas Carrol 1 Challenge Description

This time we’re looking for a malicious .dll file that was downloaded over HTTP. So, let’s filter for http traffic!

http
An Evil Christmas Carrol 1 Suspicious Traffic

There’s our .dll file!

flag{july22.dll}

An Evil Christmas Carrol 2

An Evil Christmas Carrol 2 Challenge Description

We’re looking for another C2 domain, this time the post-infection traffic is over HTTPS and our infected host is 10.0.0.163:

tcp.port == 443 && ip.addr == 10.0.0.163

We should also enable domain resolution:

Enable domain resolution

Here’s our filtered traffic, we’re looking for post-infection traffic so we’ll start looking after packet No. 529:

Now that’s what I call a sketchy looking domain…

An Evil Christmas Carrol 2 filtered traffic

flag{vlcafxbdjtlvlcduwhga.com}

An Evil Christmas Carrol 3

An Evil Christmas Carrol 3 Challenge Description

Once again, we’re looking for the type of malware infection. Using logic, and brain cells, we can guess that the domain is pretty important because that’s what we had to find for the last challenge. Looking it up on virustotal, we get some domain information (which isn’t all that useful):

An Evil Christmas Carrol 3 Challenge Description

However, if we scroll down to the google results, we find a link to the Malware Bazaar:

An Evil Christmas Carrol 3 Challenge Description

https://bazaar.abuse.ch/sample/c1532b3d37ff2ec7d70d7f8037b8cdf843d3cdd24adf860f4251d045ddf9d47c/#file_info

flag{zloader}


The Cranberry Defense Team put forth a great effort! 179th out of 1062 isn’t bad!

An Evil Christmas Carrol 3 Challenge Description

  1. https://en.wikipedia.org/wiki/File-system_permissions ↩︎

  2. Image generated with https://www.regexplained.co.uk/ ↩︎