Write-up author: Austin Tapia (Perfect.exe)
Team: Hackers N' Hops
Challenge: Tiger Companion
CTF Files: https://ewhitehat.com/open-source/

Today's beer:
This track of challenges were completed while enjoying a delicious Rolling Rock Extra Pale by Latrobe Brewing Company!


This challenge was designed to exploit reverse engineering, the method that I approached during this challenge. As an avid learner of reverse engineering, upon approaching this challenge immediately we can encountered an Android application file (APK). An Android application always uses the Java programming language or otherwise known as an object-oriented programming language due to its structure.

When doing reverse engineering it's important to understand the concepts of how it's laid out such as the syntax, memory storage, and how it works.

I'd like to first begin by explaining how the Java Virtual Machine works (JVM) to keep it simple, it's the bread and butter when directly coding in Java. The JVM enables Java to be a write once, run anywhere programming language. JVM can do a variety of functions such as compile to bytecode then translate it which is somewhat similar to your postal service packaging items for delivery. Instead of the machine receiving Java source code directly, it receives the package from the JVM environment virtual CPU that compiled the Java source code into bytecode. In more technical terms, the virtual CPU turns bytecode into machine code that the hardware CPU can read.

There a four pieces to the JVM that are critical to know:

Class loader:
Your class loader will begin the process of the program and load the computer software developed in Java in the random access memory (RAM).

Bytecode verifier:
As we referred earlier bytecode is the language that the JVM compiles the source code into, the bytecode verifier ensures there are no issues with the programmed application such as security. Keep in mind, that this isn't a debugger.

Execution engine:
The execution engine uses JIT compilation (Just In Time) with Ahead Of Time (AOT) and an interpreter supporting JIT. Between the machine CPU and virtual CPU is machine code that gets crafted within the execution engine using instructions per the machine CPU architecture that the virtual CPU compiles, but that isn't important for this challenge since we're dealing with the source code of Java.

Above all, what's important is the way the execution engine compacts and creates efficiency from the source code which enables faster execution by code optimization therefore allowing real-time execution using JIT.

The more user-friendly a programming language is, the easier it is to reverse, for example a programming language like C deals directly with the memory storage thus it will be hard to reverse engineer. Whereas, Java when defining an integer or variable automatically allocates it for the computer programmer. This is the beauty of the language, but also its downfall.

For syntax, it's different for each language explaining this can take up an entire book. Although, it is a practical thing to know such as how integers and variables are declared since it will make a call to the memory register automatically assigned by Java.

Java APK decompiler: http://www.javadecompilers.com/apk
Eclipse IDE: https://www.eclipse.org/downloads/
Java SE: https://www.oracle.com/java/technologies/javase-downloads.html
Sonic Visualiser: https://www.sonicvisualiser.org/download.html
Kate text editor: https://kate-editor.org/get-it/


Let's first download this file, which can be found here:

Upon opening this file we see a file named "app-release.apk" so we're going to extract this file and use a decompiler since it's already compiled to get a good overview of the Java source code. Java is well-known for its ability to easily read its source code when decompiled.

We're going to use the website: http://www.javadecompilers.com/apk


Once decompiled it will break up the compiled application into various files that make up the program. We have three options, opening the files in a text editor, viewing images/audio, or drop all the files into an integrated development environment (IDE). I chose all four for the sake of time management. Let's start with just dropping the files in an IDE.

I'd suggest using the Eclipse IDE, but you can use any one you're comfortable with that supports Java: https://www.eclipse.org/downloads/

Start a new workspace and click File -> Open Projects from File System... this is where you're going to point the Eclipse IDE to the folder containing the main parent directory of the application.


Bingo! We've got the decompiled application loaded into the IDE we're using.


Now using a keyword from the text given I've chosen "accept" since it seems like it's an authentication process.

Use CTRL + H to search, click File Search to search for content within all files within the decompiled application.


You can find the flag this way, but we like the hard way.

Upon searching, what stood at to me is the Extensible Markup Language (XML) files since this is a markup language used to structure data in a human presentable way.


Viewing the XML file we can see it's making multiple calls to various strings, I've chosen the "@string/SleepQuote" since it's before and after the strings "@string/accept" and "@string/ConsentWarning" meaning the user would have to accept a condition and be warned after displaying an important string that the application programmer provided.


The XML is written in a robotic way due to compiler construction of the markup language, this is a prime example of how optimization works.


Opening the file "strings.xml" located in the values folder gives us the string called.

<string name="SleepQuote"> Doc says, “You’re this garbage person, but if you listen to me, I’ll make you great. If they wanted to get to the top really quickly, they should sleep with him. I certainly didn’t want to sleep with him, but I was thinking about it. -Barbara Fisher derp{ReallyAppreciateTheFactThatNoneOfThesePeopleLikeMe}</string>

FLAG: derp{ReallyAppreciateTheFactThatNoneOfThesePeopleLikeMe}

Nice guys question:


Using the same method in "Don't Move & Don't Blink", I've chosen the keywords Nice, Guys, John, Ray, Arnold, and Yell. The one that got me a hit that I wanted was "Nice" as shown below:


We can see some compiled Java source code and a string called "str2" being created and initialized on the same line.

String str2 = "Oh... I didn't really mean it, but here's a flag: derp{NotAllNiceGuysFinishNull}";

FLAG: derp{NotAllNiceGuysFinishNull}

Here Kitty Kitty 2 question:


(Same file extracted later on manually, this is the easiest way since it's provided.)

Unsolved question, no teams have been able to solve this even well after the competition.

"Can you help me find it?" question:


This challenge was guessed as to where it went, I used "Don't look at it though. It's for my eyes only. =)" as a hint to assume which question the flag went to based off of the ones we've already solved.

I found the flag by doing a search of the flag format using the keyword "derp{" while looking for another flag during challenge "Get Turnt" during the last ten minutes of the CTF in hopes of desperation.


The hits from the keyword that I provided gave me multiple flags and I just used the process of elimination from there:


FLAG: derp{Comehereyousexybeast}

Here Kitty Kitty 1 question:


This one was solved through my process of digital forensics during CTFs:

  1. Identify what type of file extension it is.
  2. Verify file extension header.
  3. Run the strings command against the file.
  4. Identify any flags, hashes, or ciphers.
  5. Decode.
  6. Run the file through various digital forensic tools.
  7. Extract files and repeat step 1.

This procedure is very basic and sums up the usual process that I take, that is very effective against CTF questions.

Let's fire up our terminal in Debian 10 buster:


Let's run the "strings" command against herekittykitty.wav, it's usually the first thing that I do when trying to solve a steganography challenge to get an overview. Then we're going to use the greater-than sign pointing to a file we want to save the strings output to, we're going to point our destination to a file that doesn't exist and thus will be created as shown below:


Upon opening up the file it describes the header of the file essentially what type of file it is, this is great to know for forensics if someone has changed the file extension to something else to help disguise the file or make it unreadable.


Generally in most CTFs the flag is usually hidden inside near the top or just in one line at the bottom. We can easily see it at the bottom of the "output.txt" file:


Or we can run the following command for a quicker way using a pipe with tail:


The "cat" command stands for "concatenate" used to do a variety of line manipulation(s) which extends past this write-up or view contents of a file. In addition, the pipe command (|) runs the second command (right) when the first command (left) is finished (left to right); it supplies the information from the first command to the second command. Then, the "tail" command executes to get the bottom of the file generally the last 10 lines by default.

FLAG: derp{thismetaisalittletooeasy}

Here Kitty Kitty 3 question:


Same file provided to the players the easier way. In this challenge, I will show you the hard way.

In this challenge, it gives us a dead giveaway of the way to retrieve the flag: "is he on the spectrum or something?" meaning that we must find an audio file within the Java application and look at the frequencies over time in a spectrogram. A spectrogram according to Wikipedia:

"A spectrogram is a visual representation of the spectrum of frequencies of a signal as it varies with time. When applied to an audio signal, spectrograms are sometimes called sonographs, voiceprints, or voicegrams."

Let's first find the audio file by searching through the directory of our decompiled APK program and we're going to do this by searching the file extensions of audio files. Wikipedia has a great article on this that I would suggest following: https://en.wikipedia.org/wiki/Audio_file_format


However, a majority of the time ".mp3" and ".wav" files are mainly used when creating audio files. Thus, we will use these two as a ground foundation to maximize productivity and time.


Another way to get the audio file, the hard way.

We know this is the file that has the encoded flag due to the fact that we can hear background noises in the song that sound like static, meaning that there are frequencies spiking and dropping.

Therefore, we're going to use Sonic Visualiser to view and analyze the content of the audio file: https://www.sonicvisualiser.org/download.html

In Sonic Visualiser go to File -> Open -> herekittykitty.wav -> Open.


This is the visual representation of the audio we were just listening to, but still, it's not what we're looking for. Thus go to Layer -> Add Spectrogram -> Here Kitty Kitty: All Channels Mixed.


There's our flag, but it's a bit hard to see I'd suggest messing around with the options until you can visually see it better:


Final result:



Login question:


This was one of our teams unsolved questions during the competition, due to time constraints of the CTF with less than an hour.

Full Version question:


Using the same method in "Don't Move & Don't Blink", I've chosen these keywords Cats, Members, and Joe. The one that got me a hit that I wanted was "Cats" as shown below:


Remember, it's important to dig through these folders/files and read the hits, one keyword could lead to the source code of the flag in question. Keep in mind, file extensions and folder names are also important to help decide where to look to close in the scope of focus.


While digging through the folders, we got a match of what we're looking for a Java file named "RareCats.java" which was briefly mentioned in the challenge question description as "rare cats" with multiple string hits.


Opening up the Java file "RareCats.java" we see the following flag in the source code:


FLAG: derp{NeverGoingToFinanciallyRecoverFromThis}

Get Turnt question:


Using the same method in "Don't Move & Don't Blink", I've chosen these keywords COVID, Turnt, and Joe. The one that got me a hit was actually none, in fact, there's no good hints for this one.

In relation, we must dig through the decompiled APK directories manually and try to find some hints; specifically what could give us a keyword to search.


There's doggone, Joe Exotic! Seems like he's dancing, based on the behavior of the files and patterns of supplied content this sticks out like a sore thumb in the directory:


In the real CTF under time constraints, I just used relative file extensions without even finding this such as png, jpg, and gif to search through the directory for files that might give me a hint.


Based on this image, I can assume a great keyword to search for would be "dancing" to find a relative XML or Java file that encapsulates some sort of string or variable.

NOPE! There were no matches, let's look at some our flags that we've already solved.


See a pattern in all of them? I do "derp" and "derp{", we don't want to use "}" due to the fact that Java uses this to delimit compound statements and various other things.


We got a few hits, great! In addition, this is also another method to solving a good majority of these questions.


Looking through the files, I really didn't see much out of the ordinary except a new XML file about the home screen called "screen_home.xml" and "strings.xml" which we've already seen. In hopes of desperation literally during the last 10 minutes of the CTF I started to dig through these files and actually found the flag which is worth 200 points.

To solve this flag, we're going to use the method of the "Don't Move & Don't Blink" challenge. By way of example, I went ahead and opened both XML files and analyzed them to find the following:

The following discovery gave me a huge hint on how it's organized on-screen for the Android application the format for the text arranged in the XML file was the following: @+id/textView**

@+id/textView8 - And
@+id/textView2 - Lov
@+id/textView11 - }
@+id/textView9 - Hav
@+id/textView - derp{
@+id/textView10 - eFun
@+id/textView7 - arty
@+id/textView3 - eToP

Arranging this in chronological order gives the following:
FLAG: derp{LoveToPartyAndHaveFun}

I want to personally thank DEF CON for hosting the village CTF and their sponsors during this pandemic. Also, Randori for giving away one of their WiFi pineapples that I won through their raffle. Looking forward to the next DEF CON CTF Hack-A-Sat.

If you enjoyed this write-up follow us on Twitter: @HackersNHops