YTread Logo
YTread Logo

Analysing a Collection of Windows Binaries and Embedded Resources - FLARE-On 2018

May 31, 2021
Let's take a look at the third

flare

challenge. PHLEGGO. When you're done with your media interviews and talk show appearances after that crushing victory in the Minesweeper Championship, I have another task for you. Nothing too serious, as you will see, this is child's play. Let's download the FLEGGO 7zip, unzip it and inside we find a FLEGGO zip, which contains dozens of binary files... urgh... this seems to be very time consuming. There are so many

binaries

but we have to start somewhere. So let's load one into IDA. Unlike the previous challenge, this is clearly a normal compiled PE binary.
analysing a collection of windows binaries and embedded resources   flare on 2018
Normally, especially when you don't have much experience yet, you have no idea where to start. There are quite a few functions and you have to start somewhere. So one idea you can try is to look for features that were recognized here or, in the case of Windows, look especially for imports. So this binary imports these functions. And some of them could provide an interesting starting point. I immediately get the present debugger feature, so maybe it's something we should avoid. But also opening, reading and writing files can be very useful. The external references, the cross references where these functions are used, are likely implementing something significant.
analysing a collection of windows binaries and embedded resources   flare on 2018

More Interesting Facts About,

analysing a collection of windows binaries and embedded resources flare on 2018...

Another strategy is to look for strings that are referenced in the assembly. But looking at the ropes here doesn't look promising. Nothing really special. Although the problem here is that the free IDA software is a bit bad with parsing, the proper Pro version would have done it for you, but in this case we have to specify the string type by hand. In Linux

binaries

, a string is usually just bytes long and then null-terminated. On the other hand, on Windows it is usually 16 bits, so a string is always based on a character, null byte, character, null byte, character, null byte, etc.
analysing a collection of windows binaries and embedded resources   flare on 2018
As you can see, if you were to search for Linux C strings, you wouldn't find them. But in IDA preferences we can select how we want to search for strings. And in this case C 16bits will work for us. Now we find significant chains. As you know, IDA is not the only tool and I usually use Binary Ninja. But also the normal version at the time of making this video would not recognize it directly, although I was told that the current development version, which you can switch to in preferences, handles it. So by downloading it and then checking the strings, we also found them here.
analysing a collection of windows binaries and embedded resources   flare on 2018
So this is also a great way to find meaningful starting locations when backing up. Now, if we look closer at what we find here, we can see that we are prompted for a password. And in the function where that string is used, you can see here the address it was loaded at and then call this sub, which is probably printf. And then this format string %s follows. And if we look at this sub, we follow it a little we arrive at a scanf. So these are just some strange Windows configurations around a scanaf implementation. So here we read a string.
Then down here we see that a decision is made whether to pass or not, so the function just before must verify the password entry. And right at the beginning inside that function we load the string "IronManSucks". And you can also see that there is a loop and something is compared, so this is VERY likely to be the password. We can also run this binary and we get the expected password prompt, where we can enter IronManSucks. And we see "Hey Batman," which looks cool but is followed by "Step over a brick!" and otherwise nothing happens. Mhmhm... There's a second thing we need to explore.
Why are there so many binaries? How are they related? Are they the same or how are they different? In fact, I introduced it in the video. The file we opened in IDA was different from the one we opened in Binary Ninja, but both had the same strings and password. And the binary we ran was also different and apparently worked. So they are definitely very similar. So I switched to my macbook because I prefer to code there to explore this further. First I did a quick hex dump comparison. I take the binary, pipe it to hexdump and write the result to a.hex and b.hex and then use vimdiff to compare them.
And they seem very different. One possibility could have been that they are all direct copies of the same binary and then simply patched after the fact. Only a few bytes changed. But with this test we get evidence that this does not seem to be the case, as there are too many changes. So it's probably completely compiled with changes. Interesting though. Since I didn't really have a good plan on what to look for, I also opened a binary in the Hopper disassembler. And the strings were found right away, with proper cross-references. And the decompilation of that function that asks for the password also looks great.
Good job, jumper! But then something clicked. Do you remember the mistake, going to step on a brick? It's right here. On password verification. This should print, this is the scanf and then it verifies the password, right? I thought we figured out the password is IronManSucks. No? So let's look at it again. In this function, the hopper actually fails. Oh man. Decompilation is very difficult. It can work so perfectly in one role and then another that it's pretty terrible. But then I realized that this function is much bigger to be just a simple string comparison. And looking at the call graph we see that after the comparison it seems to successfully print Oh hello batman.
But then there is more code. And if you compare the beginning where IronManSucks is compared to this part below, put them side by side and you'll see that they're basically identical. There is a second string comparison function. And that value for the string comparison comes from an address that is currently unassigned. So this means that it comes from dynamic memory when the program is executed. So there is a secret password. When we look at the cross reference of where else this address is used, we find this location here and it is a memcpy. So, a string is copied from somewhere to this address.
And the string address that is copied is in eax and I assume that eax is the return of this function here. And this function, let's decompile it, runs FindResource and then LoadResource. Then this function looks for a resource in the executable and loads it. Then load that data. And then it is copied to that area. So let's give that address a proper name. The loaded resource was named BRICK, so let's call it BRICK. At this point, I went into my Windows virtual machine and used x64dbg to investigate this dynamically. I load the binary, let it run until we see the password prompt, then I look at the stack around that string and find this return address.
In this way we find the important part in the disassembly. It's very strange because it is a debugger. It's not a disassembler with fancy, extravagant features like IDA, Binary Ninja or Hopper. So there are no cross references and so on. So it's a little more complicated, but that's why you first use a disassembler and then based on that you look for the stuff in the debugger. Anyway. Here we have the password comparison function and the disassembler already shows us that, down here, that password is references. So this looks like the secret password. We can set a breakpoint here, then continue the program, enter our password, we reach the breakpoint and we can move forward slowly.
And now we can slowly look at the string comparison here. Each loop compares more. And then? We can go a little further, look at the result of the program and there we have it. It's all awesome, along with a .png file reference and a script... So we've seen the writeFile imports before and looking in the FLEGGO folder we now find a 72562746.png. Which is a Lego page with the number 42. But to be completely honest with you, when I did that the first time I didn't get far enough into the debugger to get this result. I received the image but I didn't see this.
You'll face the palm of your hand in no time. So, imagine this wasn't there and I just got the image. This meant that I was actually reverse engineering more parts of the program and saw that the loaded BRICK resource is quite large, and the password we use is super short at the beginning. And I saw that there are other parts that refer to data from the interior of that region. And looking around I found this XOR function. Here you see a loop and xoring with a constant value. Upon exit, you see the xor key constant pushed onto the stack and the address of what is xored.
And there are actually two different things. And then they both point towards the inside of what is loaded from BRICK. And based on its address and BRICK's initial address, we can calculate its offset within BRICK's data. This becomes important in a moment. Right now I knew that there is a hidden password loaded from a built-in resource called BRICK. This password can be used when running the binary to obtain an image. And we have two more hidden XOR encrypted strings. So I went ahead and wrote some Python code. I knew I wanted to read the BRICK resource from the file, so I looked for a module that could work with PE files.
And I found one, profile. And here in the project description there are also some examples and working here with

resources

sounds good. Basically, you have these dictionaries with entries and you can loop through this tree. It's a little strange, but I was actually doing this by hand and coincidentally the first resource I found through that, of all the directories that used the first entry, I finally found some data. And we get the offset from inside the binary + the size. And the size matched what we saw on the dismantler when loading it. So that's BRICK. This means the first part should be the password and remember the other two things referenced within BRICK.
Here I calculate its offset based on what I got from the disassembler and extract that as well. And for those I also have to do XOR decryption. And then I just print the result. The password and data A and B decrypted. WATCH THIS! This looks like passwords and here we also get the .png and the single character. So at this point I knew that I could extract images, each image has a number, each image file name seems to be connected to a single character, so I was clear on what to do. Simply place the individual characters in the correct order, based on the numbering of the images, and you will get the flag.
Since I don't want to enter all the passwords by hand, I simply installed Wine on Mac and used Wine to run the Windows binary. Pass the password and I get the image. Put it in a loop in Python with a thread to pass the password and we have them all. So it was just a matter of a little bewilderment. I typed all the image file names with their number and then wrote a few lines of Python to assemble the flag from individual characters based on that. And here is the flag. Let's submit it and unlock the next challenge.
COOL! Now I told you before that I missed this actual binary output if I had realized that all the resource analysis and xor decryption wouldn't have been necessary. And on top of that, I now realized that the password is also in clear text in the

resources

. So using strings it wouldn't find it because it would also look for null terminated c strings, the radare2 rabin2 utility can also find 16 bits. string instruments. And it turns out that the clear text password is ALWAYS after the string BRICK. Damn. All I had to do was use strings in the binary, find the password, run it so that the image matches the character as well as the png itself and assemble the flag.
I went too far in reversing this. But again I learned things. I never really worked with Windows resources and it was good practice.

If you have any copyright issue, please Contact