Saturday, September 11, 2021

Flare-On 2020 Question 2 - Garbage

I'm not exactly well versed in reverse engineering.  I completed the first question easily, here:  https://adventuresincyberchallenges.blogspot.com/2021/09/flare-on-2021.html.  So I thought I'd try question 2.  Oh my goodness.  The difficulty went up a bit.

The second question, I got most of the way through it, but in a really inefficient way, and I doubt I would've been able to complete it on my own.  Like I said, I'm not well versed in this.  So here's what I did.  I examine things in both Linux and Windows.  Linux more for safety purposes, and Windows because native diassemblers and debuggers seem to work better.  Also, I want to note - these are both vms, that I've snapshot and don't have any network connectivity with my host.  I make a backup of the original exe before doing anything.  When I save it, I save it with different names, so I have a step-by-step snapshot of the process.  I can easily go back to the last step if there's a problem.

The first thing I do with an executable is make sure it's an executable. (This is a Linux command, but you can have it in Windows in various ways.  I just use a Linux VM.)

file -i garbage.exe
garbage.exe: application/x-dosexec; charset=binary

Yup, it's an executable.

Then I check to see if there's any strings that can give anything away.  Sometimes the flag is in the executable.  Unfortunately, it's not that easy in this challenge.  

Also, when I'm using Linux Strings, I use different flags in strings to see if the executable has different types of encoding.  In the sysInternals version in Windows, I think by default it checks this, so extra flags aren't necessary.

I notice a couple base64 strings - trying to decode them - they aren't valid of course.

At the end, I notice some xml - I looked it up and found out this is an executable manifest.  I've seen this before in an ICS challenge, but never really looked up what it actually meant.  I'm not a dev.  I do notice it's truncated.  I file that away for later.

Then I use 7Zip to decompress the executable.  Sometimes you can see more things this way.  You can do this with exes.  I see UPX.  I know that that means it might be packed with upx.  Again, I've seen this before in a different challenge.

So I try

upx -d garbage.exe -o garbage2.exe.

I get an error: "upx: garbage.exe: OverlayException: invalid overlay size; file is possibly corrupt."

Of course it can't be this easy.

So I open it in hxd.  I really like this hex editor in Windows.

I look up what this manifest thing is, and without even really knowing what it is, I paste it in, and get rid of the other part of the manifest that was corrupt.  Try unpacking it again.  No dice.  Still an OverlayException.

I've done challenges, and remember that many times, programs work in blocks.  So I add a bunch of null characters to the end of the file.  Still getting errors.  I try to look up the error.  I don't really want to use a write-up right now, because I want to give it a good shot before turning to the write-ups.  I find that it has to do with some kind of checksum.  So I look up tools for reverse engineering.  I have the Flare VM, because the challenge recommends it, so I start opening various tools looking at them.  None of the debuggers will let me open this file.  So I find this tool CFF Explorer.  This shows I might be  right - it was packed with UPX.  I try the unpacker in CFF Explorer thinking maybe it would work - still the same error.  I look it up, and it looks like there are ways to keep upx -d from working.  There's a bunch of information about manually unpacking it, but I don't really know much about assembly.  Then I notice, the PE and File header are different.  For all I know, this is normal, so I look it up. 

Google:  Can a file size and PE size be different?

They can.  https://reverseengineering.stackexchange.com/questions/12121/how-can-file-size-and-pe-size-cant-be-equal.  However, just for the fun of it, since I have no idea what I'm doing, I calculate the size difference.  Remembering that 1 byte is 2 hex characters, I calculate the missing number of bytes, 41472-40960=512.  I open up powershell and print out '00'*512.  Then I appended it to the end of garbage.exe in hxd on the hex side.  Tried opening the file again.  No dice.  Different error this time, though.  Side by side comparison is incorrect.  Looking up this error - there are a bunch of different problems that could be this.  Most of them say, "Try reinstalling the application".  Well, I didn't exactly install this to begin with, so that didn't help much.

So I'm poking around CFF Explorer and notice the UPX utility.  I didn't try unpacking it again since the change to garbage.exe.  Duh.  So I save it and try running it again.  Side by Side configuration error.  Still something wrong.  So I look in CFF Explorer, click around, and then view Dependency Walker.  I see that the manifest that I corrected is there.  But it doesn't look right.  Part of it is truncated.  I try to fix it in CFF Explorer and save it.  Try to run it again... still side by side configuration error.

This is the point where I consult a write-up, because I simply don't know enough.  I don't read the whole thing - just enough to get a nudge in the right direction.  So I delete the resource.  I think I should've thought about that, because I've had to delete configs before that were rebuilt in other challenges.  I try to run it again.  This time, I'm getting a different error.  "The code execution cannot proceed because a .DLL was not found.  Reinstalling the program might fix this error."  The weird thing is that this popped up twice.  Again with the reinstalling... so I look up that error.  "Install some dubious program repair software", no thanks.

I do remember that .dll stands for dynamic link library.  From my programming classes/ctfs, I remember that in order to use certain functions, you need to call or import other functions or libraries.  (It's been a while, so if I'm using the wrong terminology, sorry.)  So I'm looking in CFF Explorer again, and I see Import Directory.  What's this?  There's two of them that are blank.  I have no idea if this is normal, So I click on one, and I see a list of things.  So I look them up.  One has to do with kernel32.dll and the other has to do with shell32.dll.  DLLs... lightbulb.  When I double-clicked, I noticed that there was a blinking cursor.  So, I typed in kernel32.dll in the top one, and shell32.dll in the bottom one.  I saved the file and ran it again.  It pops out sink_the_tanker.vbs and the flag: C0rruptGarbag3@flare-on.com.  I'm looking at the screen like O_O.  Finally.  

I don't usually attempt Flare-On, because they really ramp up the difficulty level, and it used to be, they would only give you one challenge at a time, so if you got stuck on one, you can't go to the others and try solving them.  That is one cool thing about other CTFs.  If you get more than one challenge, sometimes you can solve others even if you don't solve one.  Sometimes I find that I'll solve another one easily that's supposed to be more difficult than the one I'm stuck on.  Weird, right?  I'm glad that Flare-On does release the challenges to try later though.  And so many write-ups.  I'm interested in learning this for fun.  Have been for a while... but finding time.  Sometimes that's not easy.

Tuesday, September 7, 2021

Flare-On 2021 & Flare-On 2020 Challenge 1

My colleague said he saw that the Flare-On Challenge was coming up soon.  I've attempted a couple challenges here or there for this one in past years, but haven't really given it much of an attempt.  I wouldn't say I'm the best at reverse engineering.  I've tinkered with a couple things, but not really deep dived into it.  Here's the link:  https://www.fireeye.com/blog/threat-research/2021/08/announcing-the-eighth-annual-flare-on-challenge.html.

Today, I saw that Flare-On had some challenges from last year and solved the first one in about 10 minutes.  It was easy to me.  I remember a couple short years ago, this would be a challenge.  I didn't read any write-ups, and I don't recommend doing so unless you get stuck.  Try them, then read write-ups.  You might surprise yourself.

Flare-On 2020 - Challenge 1

Welcome to the Seventh Flare-On Challenge!

This is a simple game. Win it by any means necessary and the victory screen will reveal the flag. Enter the flag here on this site to score and move on to the next level.

This challenge is written in Python and is distributed as a runnable EXE and matching source code for your convenience. You can run the source code directly on any Python platform with PyGame if you would prefer.

I didn't run the game at all.  I went straight to the source code and found this function:

def decode_flag(frob):
    last_value = frob
     encoded_flag = [1135, 1038, 1126, 1028, 1117, 1071, 1094, 1077, 1121, 1087, 1110, 1092, 1072,
    1095, 1090, 1027, 1127, 1040, 1137, 1030, 1127, 1099, 1062, 1101, 1123, 1027, 1136, 1054]

    decoded_flag = []
    for i in range(len(encoded_flag)):
        c = encoded_flag[i]
        val = (c - ((i%2)*1 + (i%3)*2)) ^ last_value
        decoded_flag.append(val)
        last_value = c
   return ''.join([chr(x) for x in decoded_flag])

Noticed that all the characters were just encoded as numbers and that they were all four digits.  So I made it guess some.

def decode_flag(frob):
    last_value = frob
    encoded_flag = [1135, 1038, 1126, 1028, 1117, 1071, 1094, 1077, 1121, 1087, 1110, 1092, 1072,            1095, 1090, 1027, 1127, 1040, 1137, 1030, 1127, 1099, 1062, 1101, 1123, 1027, 1136, 1054]
    decoded_flag = []
    for i in range(len(encoded_flag)):
        c = encoded_flag[i]
        val = (c - ((i%2)*1 + (i%3)*2)) ^ last_value
        decoded_flag.append(val)
        last_value = c
    return ''.join([chr(x) for x in decoded_flag])

for last_value in range(1025,1200):
    print last_value
    print decode_flag(last_value)
    decoded_flag = []

The token that is sent by the game for the value of last_value is 1030.  The first flag is idle_with_kitty@flare-on.com.

I can see the next challenge is packed.  I haven't really messed with a packer that I can remember.  Looks like UPX.  I'll give it a shot.