Hackrocks / HackArmour May 2022 CTF

Hackrocks / HackArmour May 2022 CTF

Firstly, this was our first CTF we had entered, and with very little preparation. I want to fully acknowledge the amount of effort the organisers have to put in, and the support that they have to give during the competition. Being new to CTF, I have my opinions on how I found it, and there were some challenges we faced due to just our inexperience at competing. We knew going in, that our binary exploitations would be weak, and a significant number of exploits were binary based, but we had a lot of fun, we learnt a lot, and personally I'm looking forward to future competitions.

We positioned 19th out of 130 teams, which puts us very mid-field and a great place to be starting from.

If you want the movie version of this:

Onto the puzzles that we solved:

Selfies From Mars

This was a collection of four jpgs and one sound file. Whats interesting here was our approach to look at the data - we used exiftool to look for obvious meta data. Interestingly one of the files pointed us towards a private flickr account, but this was a red herring (or a mistake to have left in). We also analysed the files using forensic tools, to see if there was data hidden in them. Just by listening to the audio, I could not spot any obvious audio encoding i.e. I'm used to listening to radio data signals. There is the possibility it has some low signal-noise data encoded in there such as Whisper, but I feel that would be unfair and this would have been something to come back to as there are easier analysis's to do first.

Our next approach was to use the stegseek application with a brute force standard password file - opting for rockyou.txt. Running on each of the files in turn provides nothing, but I knew the stegseek also works on other file content types, so I ran it on the wav without even thinking that I couldn't:

~/selfies$ stegseek rover_sounds.wav rockyou.txt
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek

[i] Found passphrase: "sol16"
[i] Original filename: "secret.txt".
[i] Extracting to "rover_sounds.wav.out".
the file "rover_sounds.wav.out" does already exist. overwrite ? (y/n)
~/selfies$ cat rover_sounds.wav.out
We've found some life evidences! We'll send more info in next messages.

By the way, the token of this game is MARS_IS_ALIVE

I do wonder if there is data in the other files, especially mars_03, but the flag is captured and time to move on.


The give away here was the extra data on the end of each line, which if you had cat the file you wouldn't notice given the short length of lines (sub 80 chars). Spotting this leads to one of two routes - either you know there is a tool called stegsnow or you spend a lot of time trying to decode the spaces and tabs. Our first reaction was 'ooh its a whitespace program', it is not, nor does it map to binary or any indexing. Our mistake here was to completely over think the problem, where the solution was to use the stegsnow app (Which is the goto steganography tooling for text files).

$ stegsnow -C -p "bladerunner" handwritten_note.txt

The password bladerunner would have taken a few guesses - the meta clue in the description pointed towards the director (Ridley Scott), so variants of that were tried first.

I think I was a bit disappointed that there were two steganography puzzles which were very alike - this one had the potential to be a real brain tickler, but ended up being a script kiddy approach. I spent hours on this one, and could be solved in seconds if you knew the tool.

(As an aside, we tried so many things on the spaces and tabs - removing the text, counting the spaces and using the tab as break points, using those numbers on corpuses (e.g. on Ridley Scott, ridleyscott etc), encoding them as binary numbers with different endians etc HOURS of work).

LeChuck is Back!

This was a simplish web app - we were given a url: https://challenges.hackrocks.com/lechuck along with a couple of minor meta hints from the setup, that he's left his 'signature' on the site, and we have to look for his 'footprints'. Because this is my first CTF, it wasn't necessarily clear what to do here, and whats more, one of the clues dropped in the discord was that we didn't need to brute force anything.

Now, I don't think thats true. Arguably we didn't need to script a brute force attack, but there were no clues on that page, or any other, that would lead you to the next url. You would have to try, arguably randomly, or from a list, urls.

Because the clue had been talking about signatures, we checked things like the headers and the certificate used to sign the site (which is a standard cert), as well as other things like the presence of cookies etc. All of this is over thinking it.

In this one, we used a clue, and the clue was "what common endpoints have you tried", and again, we over thought this - the terminology here is tricky, because endpoints can refer to individual path's in the URL, as well as ports on the server - nmap returned another web service running on 8080, which I checked with the admins was out of scope (it was the docker orchestration manager). It wasn't obvious to us either (again, this could be experience of the CTF puzzels) as to what was in scope - if /lechuck was, was (for example) /~lechuck/ ?

We ran a fuzzer on both / and /lechuck/ and the /lechuck/user/ url dropped out.  That in turn gave away what we had to do, and trying /lechuck/user/admin and /lechuck/user/lechuck gave us the flag swiftly.

On this puzzle, again, I was expecting something a little harder, like an sql injection, or a at least some form of clue to lead us from the first url to the second - once you have the second you have the answer.

But the learning curve on how to effectively use a fuzzer, and to slow down its request speed to fit inside the rate limiter (we had to run at 1/sec) was in its own an interesting skill to acquire.

Spin The Wheel

This puzzle is one that I enjoyed, but was annoyed with the answer. Firstly, we were told that all the flags would be obvious.

Taking the binary into our sandbox, we ran it, along side looking at a dissasembler trace. There was a very obvious data block called match which contained a random string. For a while, we tried variants of this data block as the password in the application - and each time got a seg fault. I assumed that this was a salted-version of the access code, (or flag), and had spent quite some time tracing the code in the dissasembler as to how that was manipulated before it was compared to the input.

It was actually the flag.

I had swapped to several different dissassemblers to try and work out what the code was doing, and I had been sitting on the actual flag since Thursday before it was suggested that I try it. I think 'annoyed' by this puzzel would sum it up.

Interestingly this was a medium, and I never solved sussy-malware, which suggests that again I've over thought the problem.


Oblivion was probably the one that I did fastest - when I did it right. A binary download, running strings on it returned a lot of debug pointers, the most telling was that it contained what looks like python runtime and libraries. To me, this was a give away that this was a compiled binary using probably pyinstaller. Running up a copy of pyinstaller in a venv has a application called pyi-archive_viewer which when run against the console immediatly confirms - it drops out all the contained files in the compressed folder.

We made the mistake of extracting the wrong file, which was a distraction, and when I realised I went back and spotted nestled between two other libraries the correct exfiltrator.

Snippet of the output from py-archive_viewer - mid screen the is the 'exfiltrator' fil

I believe this is a .pyc file once extracted, and could be loaded into python memory to be disassembled using the dis tool - but that isn't needed. Running strings against the extracted file causes the flag to drop out:

strings wont find that on the original binary as this is compressed inside that binary, i.e. the step of expanding the file first is needed. I suspect if this had been a jar file, people would have instinctively expanded the file to look for the flag, so the level of puzzle there was to spot it was a compiled-python file.

I said 'when i did it right'. The question for Oblivion suggested that they wanted to know where the exfiltration was going to, and how. We had tried to find out by running up a sandboxed EC2, and then executing the binary whilst watching the network with wireshark - it made DNS requests, but nothing else (the file is in effect a spoof). I was dissapointed that this was a forensics take-apart, rather then any other kind of investigation. I would have though the question of 'how' or 'where' would have been better if the flag had been part of a url it was trying to connect to e.g. https://overher.flag.hackrocks.com

Interestingly, looking again at sussy (Which I really think I should have solved), it seems to be a rust application, but I don't believe this can be expanded in the same way; i.e. my understanding of Rust is that it is compiled down to machine code, not a VM language like Python.


The puzzles were well put together and managed; there was some technical difficulty given the version of libc used on some of the things (i.e. a lot of us had older libc's that were not compatible, or caused issues), but I think this can reflect the real world situation of having to match the target architecture. I also had problems given I'm on a M1 Mac, which mean that I had to do a lot of my work on a remote machine - better prep might be to run a qemu box to work on.

We wasted time on a few of them looking for more complex answers then were needed, which in turn limited the amount of time we had to spend on the other puzzles, but thats part of our learning curve.

I reiterate, its very easy for us to criticise the competition- I was frustrated with spin the wheel where I had the flag extracted for two days before I realised it was the flag, but the other puzzles, Selfies on Mars and Oblivion both had an element of novelty of approach - applying tools slightly differently. Tannhauser however, will take me some time to get over.

I look forward to our next competition.