KoreLogic Blog
How I Solved (Most Of) the Yara CTF Puzzles: Puzzle #9 – #11 2015-08-21 11:20

So far I've discussed how puzzles #1-#4 and puzzles #5-#8 in the Yara CTF for Black Hat 2015 contest were solved. In this post, I'll go over the final three puzzles.

As noted before, the puzzles are still accessible at the CTF page, so there are spoilers if you plan to go through them.

Puzzle #9

Puzzle #9 contained a single file named strangers composed of one long base64 encoded string. A "key" was required for the answer. Decoding the string returned 571 bytes of binary data.

I initially opened the data in a hex editor and started looking for patterns. Patterns can often be indicative of XOR obfuscation and may lead you to an XOR key. Unfortunately, after a few minutes of this I hit a wall and needed to change my train of thought.

I had run the UNIX command file over the binary data in the hopes it might identify a specific file type. This didn't work, so I decided to google the first few bytes of the data in case it was a known file header that file didn't detect. Fortunately, searching for "78 9C" had a number of hits indicating this was the header for data compressed with the zlib algorithm (with default compression)!

Zlib is a commonly used data compression algorithm. Many tools are available to decompress encoded data, such as gzip. However, tools like gzip require a gzip header to decompress the data, which wasn't present here. The solution? Add our own header and decompress:

The result of the command above returned another base64 encoded string. Decoding that gave the following message:

Oooh \ We're no strangers to love \ You know the rules and so do I \
A full commitment's what I'm thinking of \ You wouldn't get this from any other guy \
I just wanna tell you how I'm feeling \ Gotta make you understand \ Never gonna give you up \
Never gonna let you down \ Never gonna run around and desert you \ Never gonna make you cry \
Never gonna say goodbye \ Never gonna tell a lie and hurt you . Oh yea, about The game. And for
those who know "The game"...yup, you just lost. But back to this game. The real game. What is
the MD5 hash of a1d0c6e83f027327d8461063f4ac58a6 and 69cbe89bfa6370e0ab07df9a6096d3d2. No spaces,
no end lines...just yummy hex goodness.

Now the file name strangers made sense. However, we weren't finished. We still needed to figure out what the hashes in the message were, combine those values, and create an MD5 hash of that.

The two hashes in the output are MD5 hashes themselves. Since MD5 is a cryptographic hash, there is no way for me to reverse the hash into its original value. That means I would normally have to treat these like a password hash and brute force different values until I got that hashes I was looking for. Fortunately, there are many sites that have already generated MD5 hashes for lists of many different words and values. The solutions, therefore, were just a google search away.

Through some online searches, it turned out that "42" produces the MD5 hash a1d0c6e83f027327d8461063f4ac58a6, and the words "yesnomaybe" produce the MD5 hash 69cbe89bfa6370e0ab07df9a6096d3d2.

Combined as "42yesnomaybe", we produce our answer, the MD5 hash e71c9f0afccd29db1dc70daa9ea6e84b.

Puzzle #10

The goal of puzzle #10 was to obtain an "answer". The only file available was named "cute animal" and was the following string:

1b2d37622f37313662252d62243730362a2730622b2c362d62362a2762302320202b36622a2d2e276e620a23
2c6c620d2c2e3b62362a272c62352b2e2e623b2d3762242b2c2662362a276236303727622130272336373027
78627b2172777370747026727b7b26267b7076772026777026247a717b74737074754242

This string consists only of hex characters - 0-9 and a-f. While this could have been a base64 encoded string (it does decode properly, albeit into binary goo), it was more likely this was a string of hex bytes. This was even more likely due to the fact that by looking at them they would convert to ASCII characters. Using a small Perl script I wrote, I converted them to their byte values and got the following:

00000000  1b 2d 37 62 2f 37 31 36  62 25 2d 62 24 37 30 36  |.-7b/716b%-b$706|
00000010  2a 27 30 62 2b 2c 36 2d  62 36 2a 27 62 30 23 20  |*'0b+,6-b6*'b0# |
00000020  20 2b 36 62 2a 2d 2e 27  6e 62 0a 23 2c 6c 62 0d  | +6b*-.'nb.#,lb.|
00000030  2c 2e 3b 62 36 2a 27 2c  62 35 2b 2e 2e 62 3b 2d  |,.;b6*',b5+..b;-|
00000040  37 62 24 2b 2c 26 62 36  2a 27 62 36 30 37 27 62  |7b$+,&b6*'b607'b|
00000050  21 30 27 23 36 37 30 27  78 62 7b 21 72 77 73 70  |!0'#670'xb{!rwsp|
00000060  74 70 26 72 7b 7b 26 26  7b 70 76 77 20 26 77 70  |tp&r{{&&{pvw &wp|
00000070  26 24 7a 71 7b 74 73 70  74 75 42 42              |&$zq{tsptuBB|

With the exception of the first byte (an escape character) and some carriage returns, all the values were ASCII characters. Additionally, there were a large number of lower-case b's (0x62). This would typically mean the first thing I'd try was XOR encoding using 0x62 as the initial key. However, for some reason I got hung up on the initial escape character.

Probably due to the fact I had been working on these puzzles for about 4 hours straight at this point, my mind wasn't exactly where it needed to be. I got focused on that initial escape character, convinced that it was a clue to the solution. My mind immediately went to PJL and I started scouring the Internet for any resource I could find on it. After spending too much time on it, I decided this was the wrong path.

My next thought was that it might be some esoteric programming language and I looked up every weird language I could find. Another dead end. For some reason, I was still convinced it wasn't XOR encoding and was looking for more possibilities when a co-worker, whom I had reached out to venture a guess from, suggested XOR.

Despite my stubbornness, I tried XOR decoding everything with 0x62 and got the following:

It worked...somewhat. After momentarily getting over feeling stupid, I jumped back into the game and looked at the result. While the text decoded into words, it didn't look right. Notice how the the case is switched and not all values decoded into something readable. We were on the right path, but hadn't gotten there completely.

The switched case was a big clue. The difference in values between upper- and lower-case ASCII characters is 32, or 0x20. For example, the value of 'a' is 97 (0x61) and the value of 'A' is 65 (0x41). Therefore, if you ever perform an XOR decode and it looks like the case is switched, try adding or subtracting 0x20 to the XOR key. In this case, I subtracted 0x20 from the key to use 0x42 and got the following output:

We finally had decoded the message, but needed to go one more step. Searching for the MD5 hash 9c051262d099dd9245bd52df83961267 found that the solution to puzzle #10 was "mudkipz".

Puzzle #11

Puzzle #11 only contained a readme.txt file that stated the following:

Create an exploit for the newest version of Yara. We will be excercising responsible disclosure and
submitting this to the developers, as Yara is an awesome tool and it's something we all use. :)

I did not complete this puzzle. There are a few reasons why.

First, I did attempt it. While I looked at the code for Yara, I suspected that the most likely place a vulnerability would lie would be in the module code, such as the PE module code that examines PE specific characteristics. My thought process was that I could use a fuzzing program to fuzz the internal fields of the PE format, send it to Yara, and hope it fails. While I began to search for a fuzzing program that could do this, I started to run every file on my system through Yara in the hopes I would get lucky.

However, after two hours, I did not find anything so I decided to weigh my options. This was a timed CTF where, according to the instructions, the "First person to email in all the answers or has the highest score wins". I could take a chance and try to find a vulnerability, and then write an exploit for it, to get more points; or I could submit it now, not get the points, and hope I was either still high enough in points or the first one in.

Since I know my own skills and what I can accomplish in the span of a day, I decided to take a chance and send in the CTF as is. I wrote a small explanation at the end of Puzzle #11 about what I had attempted, and so I wasn't turning anything in, I also wrote a small haiku poem:

Yara is the best
For finding bad stuff inline
Plusvic is the man!

Conclusion

Overall, the Yara CTF for Black Hat 2015 by phishme.com and @iheartmalware was an excellent contest. While, to me, the 11 puzzles weren't overly difficult, they were challenging and required you to think in ways you may not normally go.

Most importantly, they used techniques that attackers use on a daily basis in malware and their attacks against your systems. Every one of the puzzles either used a technique that I've had to go up against "in the wild" or, in the case of the minidump crash file, used an actual infection. Anyone doing incident response should at least be somewhat familiar with the techniques used in every one of these puzzles, and should be exposed to the methods to get around them.

That being said, I would have to say I have two minor criticisms about the contest. First, some of the instructions were ambiguous and open to interpretation. There were times I had to guess what Yara rule I had to write or what information I had to get for the answer. While this may have been on purpose to see what solutions participants would come up with, I can see how it may have frustrated others.

Second, the final puzzle was a bit of an odd-ball to me. I completely understand why the creators put it in there. Yara is an excellent tool and finding vulnerabilities in it means the tool becomes better and stronger. However, I feel that its out of place because this was partially a timed contest. Finding a vulnerability and then writing an exploit for it takes time. In a contest where you may possibly need to be the first submission, this adds tremendously to that time and could cost you the game.

My suggestion for puzzle #11 would be to instead take it in one of a few directions:

  • Give the player an existing vulnerability, have them write an exploit for it, and then write a Yara rule to detect that exploit.
  • Give the player an existing exploit, such as a malicious document or Java exploit, and require a Yara rule be written for it.
  • Take it in an entirely different direction. It is obvious the creators of the CTF want to make Yara better, so have the participants create a new module for Yara with some requirements surrounding it.

Of course, these are just suggestions and my opinion. Regardless, this was a great CTF and I plan on recommending it to those who ask me what they should do to increase their skills. I hope the creators do it again next year and I look forward to participating!


0 comments Posted by Tyler at: 11:20 permalink

Comments are closed for this story.