Tenable CTF 2021

Another great CTF experience!

This was the first CTF hosted by Tenable and it was really well done. A great range of challenge difficulties across many categories. Our little two person team SKUA came in 56th with 3825 points. We solved 56 of the 79 challenges.

SKUA 56th place.
Screenshot of CTF challenges

There were definitely some favorites in here, some really creative problems. Alex solved some, I solved others and we worked together on a lot of them. We approach things differently and have different skills, so some of the challenges really required both of us to solve.

Getting Started

First off, I’m the non-programmer of the team. All the code based challenges were solved by Alex. However, there were a bunch of puzzles, steganography, and just plain googling type challenges that I was quite capable of tackling by myself. Then there were a bunch of challenges that required both of us because we come at things from different angles.

I used a number of tools to solve challenges, including:

  • Cyberchef: Lots of decoding, hex translation, text wrangling, etc.
  • Gimp: Several image based challenges
  • Audacity: For the audio challenges, but it didn’t actually help me solve any of them!
  • Google, textedit, etc.

The challenge ran from Thursday (1pm our time) to Monday (1pm our time) and another wave of challenges was released on Saturday. We spent a lot of hours on it and were pretty braindead by the end!


These ones were solved (generally) by me and are written up below.

These ones were solved by Alex. See Alex’s writeup here

  • Reverse Engineering
    • The only tool you’ll ever need
    • Pwntown 1
  • Crypto
    • Easy Peasy
    • Netrunner Encryption
    • ECDSA Implementation
  • Code
    • Short and Sweet
    • Hello ${name}
    • Print N Lowest Numbers
    • Parsey Mcparser
    • Random Encryption Fixed
    • Find Largest Triangle
    • We Need and Emulator
    • Is the King in Check?
  • Web App
    • Various
    • Spring MVC 1, 2, 3, 4, 5, 6, 7, 8
    • Follow The Rabbit Hole
    • Phar Out!
  • Misc
    • Reggie McRegex
    • Find the encoding
    • One Byte at a Time
    • Not JSON
  • Forensics
    • H4ck3R_m4n exp0sed! 1, 2, 3
    • Cat Taps
    • Fix Me


Easy Stego

Easy Stego Screenshot
Easy Stego Challenge

The PNG image appeared to be mostly white, but with hints of an image. Opening in GIMP I increased the contrast, but still couldn’t decipher the flag. There weren’t extra layers in the image, but when I checked the channels I could see there was a different image in each color channel. Using Colors > Decompose, I could separate the channels into layers and the flag became clear. I suspect there was a way to do and get clearer results, but this was good enough.

Challenge image decomposed into pieces showing flag
blm1.png with increased contrast on the left. Hidden message in the layers on the right.



Hackerman Screenshot
Hackerman challenge

A vector graphics image this time. Long ago I downloaded Inkscape to draw vector graphics, but never got very far with it. When it took too long to load up, I tried an online editor. I could show and hide the layers/components of the image and found some text. However, the text was tiny and I couldn’t wrangle the online editor into making it larger.


Vector image of a hacker with a mask and computer.

By that time Inkscape had loaded on my Mac. I couldn’t figure out how to view the layers and hide them, so I just dragged them all out of the way. This program let me just click and drag to resize the text. Easy.

Screenshot of Inkscape showing vector image pulled apart to reveal the flag.



Numerological Screenshot
Numerological challenge

I am very proud to say I solved this, almost entirely by myself too! The image was that of a crest/shield. When I googled the text, I found the Wiki page for Cistercians which are an order of monks! Plus, the shield picture was right there on the wiki page. I downloaded that to compare, but I had to convert it to png first. The files were very similar, doing a difference in GIMP didn’t reveal much. The one from the challenge was a little larger, but I wasn’t sure if that meant anything. Turns out it did!

Shield crest from challenge, has cistercium mater nostra on it.

Next I tried opening the png in textedit, and Cyberchef, and scrolled through the file hoping something would stand out. Generally no, but wait, there was some odd stuff at the bottom. There was some code, metadata code which didn’t match the image dimensions. Then I noticed another .PNG header… well that is odd.

It was a second PNG concatenated on to the bottom of the first. When opened, only the first one would display and the second was hidden in the file. I tried to use textedit to separate them, but it was messing with the code. Alex tried on the command line, changing to hex first, but still had some troubles.

Finally we loaded it into Cyberchef, converted to hex, found the hex PNG header and deleted everything above it. Tada! Another PNG file.

Code numbers

It was more code. What now?!

This looked vaguely familiar. On a hunch, I did a reverse image search and found it. A Wiki page on a book someone was writing about monks!


It presented the number system which I used to translate the image into digits.

Code numbers explained
Code numbers decoded

Then back to Cyberchef of course. First a conversion from hex… and… the result looked a lot like hex, so I converted a second time. The result was slightly puzzling, but eventually I guessed it was a shortened url. Going there showed me the flag.

Screenshot of Cyberchef decoding the numbers


Secret Images

Secret Images Screenshot

Two images that just look like pixel noise. When viewed one after another, there is a slight change though. Loaded into gimp as layers, I changed one layer mode to difference and the flag jumped out right away.

Image of multicolored pixels
Another image of multicolored pixels
Processed images showing flag


Look at all the pixels, where do they all come from

Look at all the pixels screenshot

This one was hard, and pretty interesting. It involved a lot of googling and dead ends. In the end, it was solved with Cyberchef, but only once we found the right recipe!

Square image showing multicolored pixels

Again, an image full of what looks like random pixels. I tried layering it in Gimp, flipping, rotating, doing the difference. Nothing came out. I loaded it into stego websites, nothing worked. Tried extracting the least significant bit, in several ways, nothing. There was a black line of pixels at the bottom that seemed important. Maybe a key length? But nothing was panning out.

The title of the challenge seemed familiar, so I googled it. It was a line from the Beatles song, Eleanor Rigby: “Look at all the lonely people, where do they all come from” That was all well and good, but didn’t seem to have anything to do with cryptography or stego. However, much later I wondered if song lyrics could be encoded as an image. That lead to a breakthrough.

Screenshot of website


A piece of code that would encode text into RGB values to create pixels. The image in question looked just like mine, right down to the black line at the bottom where the data ran out. Now, how to decode it?

That is where Alex and Cyberchef came in. I had already been extracting RGB values in Cyberchef, but couldn’t extract anything meaningful from them. Alex understood the code on the website and knew the RGB values needed to be converted from decimal.

We got the PNG back. At first we thought something was wrong, Cyberchef was messing up. Then we figured out it was a different PNG, a picture in a picture! Now the name pip.png makes sense. We were very excited to get this one because I had been stuck on it for ages and it was super tricky.

Screenshot of Cyberchef decoding the pixel image
Resulting image showing the flag


A3S Turtles

A3S Turtles screenshot

Phew, another hard one. This was probably the problem that involved the most team work. We both had parts to play in solving it and wouldn’t have gotten it otherwise. Even so, we kept putting it aside and coming back to it later and it was a long time before we finally solved it.

The zip file was password protected. Looking at it in textedit didn’t seem to help, Cyberchef was similarly unhelpful. Googling took me to the A3S phone by Oppo, and A3S turtles resulted in Ninja Turtles cases for the phone… I even found a website for a company in Vietnam that was A3S. Nothing to help with the .zip though. Apparently there is an extension for password crackers to crack .zip passwords though, so that was somewhat helpful.

After a lot of poking and prodding, I noticed that there was reference to a turtles127.zip in the file. In fact, when it asked for a password, it asked for the password to turtles127.zip even though the file name was turtles128.zip.

Screenshot showing password protected zip

Alex figured that was what the challenge description was referring to, turtles all the way down, rather than the saying and stories I found on google. Probably the file contained more zip files. He loaded up a password cracker and started working on the file.

The password was 0, and inside there was another .zip, turtles126.zip! The password for that was also 0, then the next one or two had a password of 1, then… no not 2…. the password was 0 again. Ah hah! Binary.

Alex wrote a program to cycle through the zip files and save each password until it got to the bottom.


The final .zip contained an image called key. It was a string of hex characters.

ed 57 0e 22 d4 58 e2 57 34 fc 08 d8 49 96 1d a9

That decoded to… nothing. Alex tried several things in Cyberchef with the hex ‘key’ and the binary passwords, but got nowhere.

Then I had a crack at it. One thing that still puzzled me was the title, A3S Turtles. Plus, the hex was called a key, which sounds like cryptography to me. So I did some more googling with a3s crypto and it tipped me off. It was AES in leetspeak! We had just been working on another problem that used AES encryption, so I recognized it right away.

I tried to decode it in Cyberchef, but I was still struggling. I didn’t understand that it needed to be translated from binary first or what mode of AES to use, etc. Alex knew right away what to do and it worked!

Cyberchef screenshot of decoding binary



I tried so hard to solve the audio challenges. Unfortunately I just didn’t have the right experience. After looking at the solutions, I was way out of my depth. They required tools that I couldn’t find, and techniques that I didn’t know. I actually did find one of the tools required, but it was Windows only so I was out of luck on my Mac. If I had known that it would help then I probably could have run it in Alex’s virtual machine.

In Audacity I tried the spectrogram view, tried playing the audio fast, slow, backwards. Inverting part of it, etc. I captured the Weird Transmission from the discord channel and figured it sounded like dial up. However, I couldn’t find anything to analyze or decode it.

Screenshot of audio spectrogram
Beginning and ending of Weird Transmission in spectrogram view shows what looks like code.
Screenshot of Audacity showing audio
Funny Sound in Audacity.

I even got fairly close with the written sheet music. I transcribed the notes to numbers, counted the semitones and figured out that each measure must represent a character in the flag. However, I still didn’t solve it.

Written music


Classic Crypto

Classic crypto screenshot showing cipher text

We both took a look at this one initially. It seemed like a basic substitution because all of the punctuation and such was in there. However, none of the automatic decoders seemed to work. Some things were funny about it, there were more double letters than expected, and in funny places.

Eventually I googled classic crypto and read about some different techniques on wikipedia. One section stood out, cyphers that prevent frequency analysis. Well there is one quick way to figure that out, Cyberchef! Index of coincidence resulted in this:

Cyberchef screenshot showing index of coincidence is below normal english text.

So our cipher text is not normal english text, not a simple substitution. I used a website to run a Kasiski test first, then the same website had a Vigenère cipher breaker.


With the right boxes checked, it spit out a solution. The key was ANONYMOUS and the text was a speech. Inside was the flag.

The flag is “flag{classicvigenere}”


Random Encryption

Random Encryption screenshot showing code and giving away the flag

This challenge had a mistake, and a fixed challenge was released. However, they left up the one with a mistake. I didn’t realize this when I read it, but was still suspicious of the flag in the code. It sure looked like a real flag to me, so I just tried it. Success!

Then I figured out that there was a fixed version and found the announcement about it on the discord channel. Free 100 points!


Web App

Alex and I worked together on a lot of the web app challenges. When the competition first opened we blazed through the first set on my account (all the points are belong to me!). I will just offer a brief overview here. We got almost all of the flags on the Doc Jones site and Alex got all the Spring MVC flags on Saturday morning while I was working on Stego.


Screenshot of Doc Jones website
Stay Away Creepy Crawlers screenshot

A flag in the robots.txt

robots.txt in browser showing flag
Source of All Evil screenshot

Flag in the source code (right click and ‘show source’).

Can't find it screenshot

Flag on the 404 page. Tip: Web hacking is all about trying stuff and trying to make things break!

Page not found showing flag
Show me what you got screenshot

Flag on the directory indexes, Alex found this one.

index of images on webpage
screenshot of flag
Certificate of Authenticity screenshot

Alex found this one, it was in the certificate. You can access that from the browser, usually up on the left of the url. Click on the lock by ‘secure’ or in the case of this site the little ! point. Then click on certificate and search through to find the flag.

Headers for you inspiration screenshot

Another one by Alex, he does a lot of web stuff after all. It was in a header that you could view using the inspect tool on a browser. On the network tab reload the page to see all the requests and things. Open them up to see the response headers.

Ripper Doc screenshot

Another quick one by Alex. This involved an authentication cookie (can view and edit using the inspector in the browser, application tab) that was set to false. When Alex set the cookie to true he was allowed to access the page.

Certified rippers screenshot. Sorry, gotta be in the club to get this list.
Screenshot showing inspector changing cookie to allow us to view the flag


There were several other web challenges that we solved that Alex will probably write up (Rabbit Hole, Phar Out!) but also some that we didn’t solve.

The protected directory was a very frustrating challenge that we didn’t get. We found the .htpasswd file with the admin hash. However, we didn’t get anywhere when we tried to crack it with hashcat and a wordlist (after figuring out what type of hash it was with google).


Plus, there was some confusing information on the discord channel. Folks that said they had no luck cracking the password and mods suggesting it wasn’t necessary to brute force? Seeing this we figured that cracking wasn’t the solution and hunted for other ways in. We didn’t find any. Afterward it sounded like people did crack the hash using a brute force method without a word list. I guess we should have kept cracking!

We also looked at Send A Letter (maybe command execution of some kind?), Thumbnail (we found the uploads directory) and Hacker Toolz (probably needed some nasty javascript on a webpage to feed into the PDF tool).



Esoteric screenshot showing odd code

Hmm, what odd looking code. Googling the whole thing, or even a snippit didn’t seem to give me anything. When I came back to it later I tried googling esoteric code and quickly came up with a wiki article that contained this code. Really? Brainfuck?

It is kinda neat looking actually. Googling for a decoder took me to one of my favorite code websites. It made short work of the code and revealed the flag.



Quit messing with my flags

Quit messing with my flags screenshot

This took us embarrassingly long to get. It was so frustrating, sitting there taunting us. Everyone else was solving it, but we were stuck converting it from hex over and over again. What is that saying about trying the same thing over and over and expecting a different result? That was us.

We tried it backwards, tried converting from Base64, tried the other bases too, then tried that in reverse. Nothing seemed to work!

Eventually I googled it, since that seemed to be the answer to everything. And sure enough, I got hits saying it was the MD5 of a password. I got a little confused because I couldn’t get the same result with Cyberchef, but I had a new line or something in there by mistake.


Forwards from Grandma

Forwards from Grandma screenshot

This was interesting, and luckily the answer jumped out at me right away. It was an email message. The first computer I was working on didn’t have a mail client installed, so I just jumped over to a different one with Mail on it.

The message opened and I noticed the subject line right away. That is odd, and…. it is in flag format with those curly braces!

Email screenshot showing code in the subject line


I saw there were double spaces in places, and tried decoding the first couple characters manually with morse code. Sure enough it was beginning to spell flag! Then, instead of just decoding it manually I tried to do something automated. It was a bit hard to read after all.

Screenshot of Cyberchef decoding message using find and replace

It still took some messing around. In this example after the fact I included the ‘space’ after each FWD: and RE: inside my expression. Originally I still had those in there and had to mess with even more regular expressions to remove the single spaces but not the doubles… Then I had the dots and dashes backwards, so it wouldn’t decode right.

Eventually I got the flag. Probably decoding by hand would have been almost as quick.


Broken QR

Broken QR screenshot

Alright, another image based challenge that I can tackle. Alex and I worked together on this for a while, then I finished it.

QR code with pieces erased

First we tried just fixing the squares in the corners and rotating it. I used GIMP to take the complete square and copy it over onto the others. Still no scan. Then I started fixing the rest manually. Anywhere that a block wasn’t complete, I would fill it in. I didn’t do a perfect job, but eventually the scan worked.

QR Code that has been fixed



There were a number of Tenable challenges that required their free version of Nessus. My first big challenge was getting it installed! I was working with two computers, my big old iMac, and a newer laptop that was Alex’s old computer.

First I tried on the laptop. Once I finally found the download page for Nessus Essentials, I got started on installation. It finished and opened Safari… darn, default browser. Unfortunately, as expected, there was a security warning. I couldn’t figure out how to bypass it, so I tried opening it in a different browser. Unfortunately that took me to a login page rather than the welcome screen I saw before.

I ended up re-installing, deleting, re-installing and nothing worked. I finally got the url for the welcome screen, but it was broken. So frustrating! I tried googling my problem, read the documentation, downloaded another piece of software, etc. Then I gave up.

Later I tried installing it on the iMac. I figured that computer would be too old, running an outdated OS, but it wasn’t! Everything went smoothly, I bypassed the warning message properly and created a login. Then I was in!

As it turns out, Alex remembered that he had Nessus installed on something one time. It must have been that laptop and that is probably why it was taking me to a login screen rather than the setup.

The ultimate mutant marvel team-up

The ultimate mutant marvel team-up screenshot

Once the scan was imported, I started looking through it. Nothing stood out, so I tried an export. I think I tried the csv first and looked through it in Excel, searching for ‘flag’ and ‘mutant.’

Then I tried another export, xlm this time. That is a web format right? It opened in my browser and I was greeted with a yucky one-line stream of text. However, searching for ‘flag’ took me right to the mutant flag.

the “mutant” flag is: flag{1t’s eXt3n51bl3}

It’s twice as hard

It's twice as hard screenshot

More and more digging through the Nessus stuff. Alex opened the .xml in textedit and got slightly different results than I did. There were a couple more hits for ‘flag’ when we searched. No more actual flags that we could see though.

One of the hits referenced a log file, another an open file in vim.


I dug through the scan results on the Nessus platform and found a collection of logs. Too bad they weren’t in a readable list! Just a bunch of document thumbnails. Eventually I found one called get_flag.log. At the bottom a command was run, but it resulted in nothing. However, there was another get_flag.log from the other host. When I checked that one I found some output at the bottom.

Ran command: "cat /tmp/flag | xxd -p"
Returned: 2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e

Back to Cyberchef to decode it!

…………………………………………………………………………………………………………………………………………………………………………………………………………………..the “command” flag is: flag{Pr0gr4mm1ng Mu57 83 7h3 Pr0c355 0f Putt1ng 7h3m 1n}

I searched and searched for the ‘dead’ and ‘knowledge’ flags, but couldn’t find them.


There were three easy intro challenges. Two had the flag in the description.

The T-shirt Challenge screenshot
Intro 1 screenshot

The next one required joining the discord channel. Once we were in, the flag was in the … header? of the general channel. When I joined, the channel wasn’t too deep, so the flag showed up at the top quite easily. Alex was actually the one that spotted it. Lots of people seemed to struggle with this one because there was a lot of !flag going on in that channel.

Intro 2 screenshot
Discord channel screenshot showing flag at top