 Hello. And welcome to my talk about the thorny piece of malware. My name is Marion. I'm a malware analyst. I'm going to spare you my second name now because people seem to have problems pronouncing it anyway. And I work for the Austrian software company ECO security software. My talk is going to be about one specifically thorny piece of malware I analyzed in and out. And I'm going to start over with some fancy fun facts about that sample. And the rest of the talk is all going to be about analyzed issues when looking into that. I'm going to bring two anti-analysis techniques I encountered in the sample. And two more analyst headaches that still provide problems for reverse engineers. First one of that is exception handling that can upskate the execution path. Second one is chunk code I encountered in there. That was pretty nasty at first glance but then easy to pass by after all. I'm going to talk about binary analyzes of C++ executables and about multi-threaded applications for reverse engineering. All right, let's start over. Now all together this is my favorite piece of malware. Now why would it be my favorite piece of malware? Well, I reversed it in and out from top to bottom and I really had a lot of fun. It is a challenging piece of malware but not impossible to pass by even for beginners. It's not packed or encrypted but still provides a lot of interesting topics to research. But what does it do after all? Well, all together I summarized it here. It's an Asian multi-threaded non-polymorphic file-infecting spybot. What does it do? Like what spybots do? It can produce screenshots. It can produce screen captures and send them to the CNC server. It can delete files. It can copy files. It can execute files. Most of all it can update itself so it can download a new version of itself and execute this one. So basically it can do anything the malware controller wants to. Anyway, what are the interesting facts about it? This sample uses structured exception handling to obfuscate its execution path. That means by throwing deliberate exceptions the malware author can pass execution control from one place in executable to another one named the exception handler. And the interesting thing about exception handler says in an exception handler you can define a new entry point that's going to be executed after the exception handler. Now does this work? Well, the most accurate documentation I could find still was written in 1997 by a guy called Matt Pietrek who is one of my big heroes now because he really did a really nice documentation on this issue. Namely the crash course in depth of what you can read it. Here comes the summary of this article. Actually exception handling is implemented as a chain of exception handlers which is located on stack and intertwined with the function stack frames that are on there. And it all starts at the thread information block because every thread has its own chain of exception handlers. Every version engineer can find this through the FS register at offset zero which points to an exception registration structure which looks more or less like this. In the simplest case the structure contains a pointer to the handler which could eventually handle the thrown exception and a pointer which points to the previous registration block which looks like this and eventually in the end of the chain there comes a default handler and, well, a minus one. All right, now this is based on the stack intertwined with the function stack frames. And there's a whole science about building the stack and unwinding the stack. But what's really interesting for a malware author is of course you can register your own exception handlers and deliberately throw exceptions and control, like, put a pointer execution flow to some other piece in the code. Now this looks more or less like this. If you're inside of a binary and can spot something like FS zero and see the structure where a new reverse, sorry, a new exception handler is linked into that list that most likely has to do with exception handling. Now I told you there's a pointer in there pointing to the handler code which would be the first switch to some other point in the executable for execution. And inside of this handler someone can change the execution flow to a completely different point inside of the executable. The magic thing about this is an exception is treated as a software interrupt which means every time an exception occurs the whole context structure of the thread that's running is saved away and loaded back into the CPU when the exception handler is finished. And the interesting thing there is that someone can change this structure and point to an instruction pointer somewhere completely different. So yeah, I know there's a lot of people in here getting excited when they hear they can point instruction pointers somewhere. All right. Now I told today a lot of things have changed, especially concerning C++ and individual C++ was still based on structured exception handling. I showed you before. But the things have changed mainly is that now every function has its own exception handler and uses a func infrastructure which contains information about try blocks and catch blocks. And I think I need to take a break. You'd be correct. We have a little tradition here at DEF CON. Let me tell you all about it. It involves why are we making her drink? Do we have any first timers here in the audience? I don't. So there really nobody's a first timer? None? Wait. Okay. Who's she pointing at? All right. Get up here. I can't believe this is the only guy. That's amazing. Welcome to DEF CON. Right, yeah, yeah. Right there. Okay. Now where was I? All right. Visual C++ structure instruction handling. It's still based on the principle of structured exception handling. I showed you before. But now every function has its own dedicated exception handler which is compiler generated and uses some structure called func infrastructure that contains a lot of information. Naming information for unwinding funclets about try blocks and catch blocks and a lot of pointers to the exception handlers that eventually handle exceptions. Right. There's a built-in function called CXX frame handler which this func infrastructure is handed over to and then performs the magic around exception handling to execute exception handlers. Of course. And still as I mentioned the important thing there, the exception handler can define your entry point. Now I pointed some really nice diagram that we've seen here. Interesting, right? On OpenRCE it is painted by Igor Skukinsky. I did a lot of research on structured exception handling. And I provided some scratch book painting here. It's not pretty but let's look through that. There's a exception handler on the stack. That's the compiler generated exception handler. There's the CXX frame function where the func infrastructure ends up at. This pointer points to a try block map. The try block map points to a handler array. The handler array points to a handler offset which points finally to a handler. You got it all right. Well I provide some pretty screen shots here from either pro. Let's get back to the bot. In practice this would look like this. For example there's a registration sequence. I hope people can read this maybe I don't know. Well there's the 0 flying by and a new exception handler is registered at the beginning of a function. And sometime later there's an exception happening. If you can read that call this will almost never work, right? Because this memory address put to ECX there is somewhat likely not to be valid. So there's the exception and the registered exception handler which causes the system to execute the compiler generated handler. There the func infrastructure is handed over to the CXX frame handler which then performs the magic. Let's look into this func infrastructure. In this func infrastructure there's the values that Igor thankfully pointed out in his diagram. So there's the try block map and the handler array and finally the pointer to the handler that the user registered. So there's the user generated handler and in there you can find the offset to the new entry point. If you have a look at the user generated handler it is really obvious that this handler is just registered for obfuscation because there's nothing else happening there then the setting of this offset for the new entry point. All right so much about exceptions. The second point, the chunk code in the file. There was really quite a lot of chunk code to find the sample which is pretty scary for a young analyst if you see a lot of source and a lot of shifting operations and a lot of loops that actually don't perform any really useful information in there. So I was kind of overwhelmed by this chunk code until I found the principle of the chunk code in my sample. There's a whole lot of research about chunk code in binary files and the principle of this chunk code was pretty simple. It was a park predicate. Now a park predicate is something that just well a branch statement that always returns true or always returns false and so it's always going to be just execute one branch of the branches that there are and the other branches gets chunk code. So, well, in the sample analyst it looked somewhat like this. On the right side you see the pros screenshot. On the left side there's the simplified version and if you think through that the compare statement in Yand is never going to produce any zero flags so the chunk not zero is always going to take the green branch. Right. You think now this is simple? It's true. It was like this all throughout the sample. It was just as simple. So what did the analyst do? I just put the normal dawn and green branch for president. If you can see these graphics I'm not sure how the person, I am right. The yellow boxes are the productive code and the white boxes are just chunk code. So this was really pretty simple to get by. Analytics. I spent a lot of time in the sample and had a lot of headache especially because of the threads in there. People have seen the movie drag me to hell and know what I've been through with that application. The author of the sample actually has all my respect because he produced this in C++. This is a simplified version of the threads that I found in there. There's actually a lot more but it boils down basically to one thread that manages the whole instance. Namely the, well, the finding, the both instances that could start up in the system because eventually there's more than one file is infected that could start up. Second thread there was the file infector always infecting processes that would start up. A thread machinery that would handle the sending side of the bot which could send messages and data to the CNC and one side there was the receiving side of the bot. And of course the CNC command switching. Now how did I get to that information? That was pretty tricky and I spent a lot of trying the error time in there but actually what I did was in four steps I realized that I have to spot the really interesting threads because there was a lot of timing overhead and synchronization going on. After doing this I had to spot the interface communication and the synchronization methods which actually told me a lot about what threads were about were triggered by specific events. I will talk a little bit more about this pretty soon. In the third step of course I had to analyze somewhat the function bodies of the threads to really find out what they do, what information they generated and where this information would eventually flow to. Knowing all of this in the first step I could bring down this big picture of where this information generated which thread sorry accepts this information processes it and eventually it takes any action. Alright so if you go back to that diagram I found four different methods of synchronization in there which were events for triggering the file and factor and for managing the different instances that were started thread messages which were mainly used at the receiving side of the bot I a completion part which was used to manage the receiving side of the bot the sending side of the bot and the critical sections for data exchange between the threads when I had that I could paint the threads around the synchronization methods alright now here comes the last nestiness for today C++ there's actually a lot about reversing of C++ there's a whole science for people who are interested in that I collected a lot of links on that research on the last slide of this project but what I actually want to talk about are virtual function calls and virtual function calls are really reverse because they're indirect calls and they're only fully determinable at runtime they stem from the multiple inheritance feature of C++ so one of these virtual function calls can actually call into several different methods at runtime they're translated using virtual function tables which also have a lot in reversing these sorts of binaries I provided an example here in this example there's a virtual function table actually loaded into the registry EX and at offset 4 of this virtual function table there's a method that's going to be called with this call statement there was really sort of a catch me if you can actually I collected another sample from OpenRC and Igor Skukinsky because he did a lot of research on this as well here's one class A where there's two virtual functions defined in there underneath this class definition you can see the memory layer of class A where there's a virtual function pointer actually pointing to the virtual function table of class A now a virtual function table is something that just class have that have virtual functions defined in there alright and here's the second class B which also has a really similar layer with two virtual functions defined in there and another interesting thing class C because class C inherits probably class A and class B and implements one virtual function each now the memory layer of class C is somewhat bigger because as it inherits other classes it has to include their class layout and also the virtual function pointers in there to the virtual function tables just that these virtual function tables are now adapted to fit the needs of class C and point to the actual function offsets that class C implemented alright this is really dry to look at at code now back to business here's the CNC command switching function which is a really good example for virtual function calls on there you see a lot of yellow boxes this is all memory allocation for objects that are going to be instantiated in the green boxes and then you see this one pink box which is the virtual function call which was actually used to call into the bot functions the bot functions are implemented as derived classes from one bot action superclass and all had one function overloaded sorry implemented that was the bot action now provided here another example with the move file object here in yellow you see the object instantiation sorry the memory allocation whether space reserved for the object that's going to be instantiated a little bit later in the green box and what you see there is a call to a constructor now this constructor actually has call into the superclass constructor as it work with derived objects and there you see the first VF table flying by I will talk about this in a second as I mentioned this constructor has to call into the base class constructor and there you see another virtual function table whether space reserved for two virtual functions now another pro if you check the cross references of this base class constructor there are 23 cross references and now get surprised there's like 23 bot actions that can be taken by the bot alright now knowing this the final step is the instance sorry the call into the function method of the move file object and what you see there is that the function table of the move file object is loaded into the register and the function offset4 is called now if you have a look at the virtual function table of the move file object and offset4 there is the move file function so theory approved using these virtual function tables you can not easily but pretty fast determine which functions are going to be called at these virtual function calls alright this was my presentation here the promise to yourself links the sample is to be found online under the first link and well if there is any questions you can contact me on twitter or I will be out in the hallway to answer your questions or receive critics or anything you want to tell me now thank you