 All right, we're going to be kicking off the first of our normal talks today right now in track one John Stroeschein is here who's going to be speaking about following a trail of confusion. So please welcome him to the tour con stage All right. Well, thank you and thank you to Tim and David and all of the tour con crew that put this on and Allowed me to come and speak to you for about 50 minutes I definitely will do my best to keep it to that timeline because I know now I'm going into some of the lunch period So I titled this calling this this presentation I titled it following a trail of confusion because it seemed the most appropriate title for what I want to talk about and Part of what I do on a somewhat regular basis is to look at malware and try to understand its behaviors it's intense some of the tricks that it employs and That's usually what I end up doing is trying to solve these puzzles and try to identify these Obfuscation techniques so that I can unwind them so that I can see what that malware is actually up to and then I can provide intelligence indicators report summaries to whoever is asking me to do this work or in some cases making some training material so My contact information. That's my email if there's anything from this presentation that you'd like me to provide you send you the slides I think they'll be available after the talk Questions on the samples I'll talk about some plugins that I didn't link to and I don't even think I've got up on github yet But if I can send those to you as well, please feel free to contact me at my email account I'm here representing quite a few different Organizations and places that I work first and foremost BDA labs Which is with Jared DeMott and we also do training so I was fortunate to be here earlier this week and did a couple days on malware So I think I saw a couple familiar faces here earlier. We both also author at plural site I work with the ISF I work with bromium and then I teach full-time at a university in the Midwest So the basic flow is that we're gonna start with these delivery mechanisms Whether it's an office document or a spearfishing link or some other content, but some sort of a delivery mechanism We're gonna begin in this talk with the office doc and that those office documents then will employ some sort of Method to get code to execute oftentimes. That's through macros. So The idea is that there's multiple stages and that these stages continue to unravel Maybe we then go to a batch script or some power shell. Maybe we get some shell code Eventually, we we generally tend to get to some native code. So a PE file maybe some dot net Maybe some Java. That's the actual payload that the malware authors wanted to drop before we then move into this post You know post infection phase. So at each stage, there is generally some layers or multiple layers of Obfuscation and Depending on the type of code that we're looking at will also then greatly determine the type of obfuscation that we'll see Towards the outer end of that the beginnings of the attack there's a little less effort just in my experience in Making those, you know armored bulletproof documents and we're also dealing typically with with interpreted code And so the level of obfuscation techniques that are available to an author are maybe a little bit more limited Then when we move a little bit deeper get a little bit closer to that payload and now we're dealing with shell code We're dealing with PE files in which it's a little bit more difficult just in general to reverse engineer those And also to detect any sort of obfuscation or anti-analysis So there are many ways we could go about this. I'm going to focus on if we were going to analyze each stage I'm not saying that that's necessarily the step that you have to take in each stage If I wanted to observe the behavior of an office doc I might go to a sandbox before I decide to dump the macros and investigate those but for the purposes of this talk We're going to dig into those So our first document is this handset or mal doc with each sample that we're going to talk about today I'm going to have the MD5's there So if you want to grab a sample you'll be able to pull those down from virus total intelligence or maybe hybrid analysis Or your own internal pool So that you have that as a reference We're not going to go through all the analysis I'm just going to focus on a specific technique that I observed in that document or that that you know that piece of software that script That highlights or exemplifies some of the you know the obfuscation that I see With this one, so it's an office document So my go-to tool is OLE dump. That's a Python script made by Didier Stevens And what that allows us to do is you can see in the screenshot and hopefully everyone can see this one Okay, it might be a little bit hard the further back you get Is it essentially gives us the table of contents of that document? So we can see indexes those are the numbers off to the left Then you can see the contents the streams and some directories What is all stored in this document itself and then the most significant thing or at least the most important for this analysis is That we have the streams that are identified with macros So in this case, it's 8 and 10 and we know that because there's a capital M next to those streams So we can use the tool in order to extract those That allows us to decompress that macro code and begin investing the VBA the visual basic for applications Another thing that I've run across with office documents And this one took me a little bit of time to really piece together was the these streams right here 17 and 18 for this document, of course the document structure will change what streams you identify here So this is the structure for this particular doc But this one has F and O and what those actually represent are a user form So this means that within this document there's a user form and the user form generally will contain very basic objects labels buttons text boxes that you can then embed content into shellcode PE files obfuscated strings power shell scripts, whatever it happens to be so Seeing those referenced in the macro code isn't always the most direct or the most obvious And one of the tools that I use very often if I really need to actually look into any particular user form is To actually use the office ID the integrated development environment because then you can you can open up the project Kind of like you would in visual studio you can see the macros you can also see the forms You can get the the controls on the forms as well Now that's not always the case Oftentimes and a trick that you'll see really throughout all of the obfuscation efforts is to try to identify What obfuscation is being used when is it being de-obfuscated or decrypted catch it at that point let the malware do all the work for you and So it's very rare that I actually pull that raw content off of a form because I just try to figure out where in the code It's being de-obfuscated so I can grab it right there You start looking at VBA codes so let's say you have to dig a little bit deeper into this document and You're gonna find and you'll see this across a lot of interpreted languages JavaScript and PHP and that there's only a Limited number of ways in which you can really obfuscate this code you can create very You know random and seemingly strange looking variable names and function names. This just simply makes it harder to trace the logic So here's an example. We have function permanent and object parakeet We have strings and strings and API so strings and function calls are generally the most important thing that I'm looking for When I'm trying to analyze any form any sort of malicious content or any program at all even if it's not malicious What are the strings being used? What are the functions being called? So with this one again very common to see just enough string obfuscation to make it that you can't readily recognize What those strings are so that they can be dynamically reconstructed during runtime and use just at the point that the malware authors actually needed So this one has some string reversal and some substrings and that's how it's simply recreating those strings So using those string manipulation methods on either the string itself or a sub component of a string and then rebuilding that string as it Goes another technique very common across the board is also junk instructions And again my opinion is that it's a little bit easier to identify these when we're looking at an interpreted code I can see three variables here. They're doing some very basic math and each one of those variables I could highlight I could do a find in the document and I could quickly determine if they're being used or not if they're Not being used then I got a pretty good indication that it's just junk code So oftentimes the case there is you get in a native code and you start disassembling things with Ida or binary ninja or some other tool It at least for me It's a little bit more difficult to recognize those because you're looking at disassembly So you have to do more program analysis before you can determine if it's a junk instruction or not You might have some control structures and even those control structures might look like they're doing something with string manipulations So it might look like it's important, but again, it's not it's just there to slow you down if you're actually analyzing these And the last thing on this one the last that bladder pot, which is a great variable name That's actually a legitimate string and you can see that by looking at the content from win 32 It's just reverse from win 32 and then there's a substring select star So there it's gonna be from 1 32 space star. So that's the only legitimate string here So we could identify that variable and start tracing it through the macros if we needed to Another technique is to use the windows api so the windows api is important We're gonna any program that's gonna run in the operating system The windows operating system is gonna eventually interface through the windows api and some environments will allow you to do that directly So vba macros are actually no different you can in fact call directly into the windows api from your vba macros So normally you would use the functions that are defined in the language and those are documented on msdn as well the microsoft developer network But you can also directly call so here's an example All the green those are comments so the authors in this case decided to take and Interject all of these lyrics from songs in between these aliases that they're creating and these aliases are allowing them to call things like virtual alloc out of kernel 32, which is our memory allocation routine and RTL move memory, which is Coming out of NT DLL if we need to identify the usage of those apis Then you have to look off to the kind of to the left there and that virtual alloc is going to be aliased with betterment And RTL move memory is this variable antecedency So in order to identify their usage in the macros now You either need to just rename them and refactor that code if you've extracted it and you're working with this in a text editor Or just keep that mental mapping in mind So if I'm spending some time here I'm usually renaming things as I go because it doesn't take very long to just do a find replace Now this one and this document is actually using shellcode so Shellcode is embedded in a user form the macros begin to execute it used virtual alloc to allocate some memory It then use the RTL move memory API in order to copy that shellcode from that user form after it decrypted it or Deoffice skated it into the allocation that it just made so Logically we can think about if we're gonna have shellcode in memory it needs to be staged there So we need to allocate the memory we need to copy it into memory and then we need to execute it And so there's a final API in this particular example That if you go back here, this was I believe all of them one of these apis has to be responsible for executing the code Now it doesn't jump out immediately as an obvious API at least it didn't for me the first time I looked at it However, if I followed or traced those API calls I found the allocation I found the copy then the only other API that was being called was this cabriolet and this one You'll see here in just a moment is actually a function called enum dates format And so what I decided to you is to use a debugger so I oftentimes find myself using a you know a combination of static and dynamic analysis and in this case I felt it was easier to just set a break point on this function call and then Observe the behavior at the time that the code stopped this allowed me to not only see the memory that was allocated But because we're about to go execute code there that shellcode has to be in a de-op you skated form So I set a break point we can see that cabriolet is our enum dates formats enum date formats w And this actually as defined on MSDN takes the first argument Which is a pointer to an application to find callback So then it became clear obvious to me how exactly it was getting this code in memory to execute from within those macros So continuing with that dynamic analysis Was able to because it was running. I had runtime analysis I could look at the value of that first variable I could dump the content so it was base 10 convert it quick to base 16 and you can look at the process memory This is an office document. So when we're dot exe and we can see that at the base of this allocation We have our WX which of course we would need execute permissions in that region of memory in order to execute the shellcode So from there I Used process hacker. I like process hacker because it allows me to see memory I was able to look at this this really amounts to the entry point So so not only did this allow me to identify the shellcode pull it out of memory when it was de-op you skated But it also allowed me to identify the entry point, which is another important step If you don't have a specific point to start analyzing some code, you should probably start at start If I took all of this out of memory, you can see that we're at an offset the base of the allocation Seven zero D zero zero zero, but we're actually at an offset of E5D So if I dump that out of memory and sort of disassembling from the first byte You might get incorrect disassembly results So I'm going to take my disassembler Ida Pro or binary ninja and I can point it to the entry point Which is this first byte right here, and that's a push EBP the opcode 55 So seeing that in memory recognizing that opcode to me was a good thing There are I'm going to go kind of fast because there's a lot of stuff I want to have here So if it seems like I'm just chugging through I am that night. I drank a big thing of caffeine before I got up here What's that? Yeah So embedding content another a this is an example There's our OLE dump content. You can see f and zero this project view below That's actually from the office IDE and so not only can you see the macro streams this document and cowkeeper Another name that I use oftentimes when I develop But we can see the form as well this form has a name It's called discord you can look at the form and you'll see all the content on the form Not only will you see the content? but if you select any of those objects you can get the name of that object and What this helped me connect the dots on was that when I'm looking at macro code You may find at times these these objects being referenced But it's not clear exactly where they're coming from because a tool like OLE dump isn't going to give you the Structure of the form and the objects within it It's just going to simply say hey, there's a potentially there's a form here The IDE allows me to see that. Oh, this is in fact an object on that form So that at least helped me connect those dots So it was an important step in my analysis and looking at office documents, which I tend to see quite a few of Another document I ran across not too long ago was another office doc that has exhibited anti-analysis So there's a variety of techniques in which the authors will try to employ Detection of a virtual or analysis environment so that it can disrupt its behavior disrupt your tools disrupt the output This particular document again I did just did some runtime analysis because I didn't want to have to bother with trying to piece together all these strings and With this one it had this array of values KVM QEM you right hat virtual VM or Xen and it was looking for the Manufacturer in the model of the host system and so then it would take those values from the value It returned or obtained from the host and do some simple string comparison if it determined any of these matched Then it said I'm in it I'm in a sandbox environment, and it would really abort its behavior if it didn't detect it would do one more check and This one as you can see by the same string box up above Was using names of common analysis tools so using win 32 Or I'm sorry the win management WMI It gets a current listing of processes compares it to these hard-coded strings process names If anything matches again to checks in order to to deviate or modify its behavior Right and office documents are the only one that does that technique I see it across the board I see a lot in native code and one of the first things that native code will do is use create tool help 32 Snapshot a Windows API to get a process listing go through those processes and see if there's any Known processes that are running that would indicate that it's being analyzed or debugged so that it can abort or change its behavior It's not uncommon to run across password or documents that are actually password protected in this particular case I got a document, but I when I went to analyze it because it's password protected the macros are encrypted So you can't use a tool like Oli dump to extract those So I really needed to see for a variety of reasons what was going on here And I didn't have the original email that it was sent to so I didn't have the password now These passwords are getting sent to users that means that those passwords are typically pretty simple four-digit pins So a lot of documents at the time that just had four-digit pins And so in doing a little bit of digging Discovered that John the Ripper actually has a Python script Office to John that will extract that hash put it into a format that you can then feed into John and Begin doing some brute forcing so in this case I told John to just incrementally go through the digits until it found a password and after actually a few minutes in a one-core CPU VM I had the password to my document which was four five five so then I could open the dock I could extract the macros I could actually remove the password all together and continue my analysis So mentioned shellcode I actually like to talk about shellcode very early on because it's used and I see it Throughout really all phases of the different attack stages that I see we've saw it in VBA. I've seen it in PowerShell You'll see it in native code. It's really a very efficient or I should say effective way to just you know Contain some functionality into whatever vehicle you're using to attack or you're seeing that is being used for attack So oftentimes seen in malicious code Those things there I see it used for unpacking and we'll go through an example here in just a little bit and how The shell code is used in a very modular form in order to do some unpacking so that the original functionality of whatever that pack sample Was can then execute Showcode once you've identified the usage just like you saw with the VBA document Then we just need to extract it from memory and because it is likely native code We can use some tool like Ida Pro or binary ninja in order to disassemble that So this is an example that shellcode that you saw earlier This is actually disassembly from that and of course I chose a select part of that disassembly here to talk through There was lots of Differences or nuances with shellcode as far as it is how it differentiates between a normal executable file that you give to the operating system and loads it through the operating system loader into Memory and then prepares it for execution one of those main things is how it calls or imports functionality So if we're going to interact with the Windows OS we're going to use the Windows API and if we're going to do that We're going to import that functionality. So the operating system will take care of that for us in a normal situation Shellcode is not normal. It's put into memory And then we're just telling the CPU to go to some location in that shellcode and begin executing So the shellcode is responsible amongst other things for ensuring that it has built its own import table So you see artifacts of that or evidence of that when you look at the shellcode because you'll see calls instead of You know call create process or call virtual alloc You see call ebp plus var 1b 0 kind of a non-standard way of calling a function There's a function pointer inside of that local variable. It's a local variable because we're referencing ebp And we're also assuming or we have analyzed this to know that this function has a normal stack frame And it's so it's calling it through a local variable, which again you can do if you write code You can actually do that, but it's not the normal way For our analysis though, we have to figure out What is that call I said strings and apis are important and I don't know what that apis I don't what that call is. I'm kind of blinded to what the program is actually doing So in this example, there's two instances of it. This one uses a really well-known technique So even though it's well known It's still something that I really regularly encounter and that it has stack strings So it's just taking the variable for those ASCII characters of the data the numeric values for those ASCII characters And it's moving them into the stack So it's constructing that string on the stack at the time that it needs it so that then it can dynamically resolve our call to Whatever function it's after so in this example, that's going to call ZW unmapped view of section So there's our stack variable the BL is our null byte. It was x-word up above. So that's just terminating the string the other thing that this shows us if you looked at the sample in its entirety is this trend or this pattern of string function call Result results are going to be returned at EAX in this example That being moved into our local variable and of course because I've made these screenshots that local variable is right here So this also tells us that once we recognize this pattern that are called a sub CF one That is likely resolving these API's for us So if you have to figure out how that works, you can trace into it If not, you just maybe rename it and you're happy with the fact that you know that anywhere This is being called. It's likely resolving a function for you the sample does Process hollowing so really there's another layer that we have to trace into if we were to continue to analyze it So what you're seeing in that shell code is the fact that it's going to start a process in a suspended state It's going to empty out or replace the original code So it's going to use probably a binary a well-known binary on the system like explorer.exe or SVC host or anything that it can think of since it's loading that executable in a suspended state It looks like it's coming from that original location, you know, so see system 32 SVC host.exe But it's suspended so it can use some of the other API's like unmapped view of section in order to get a pointer to that Text section to then replace it with its own code So now another round of or stage of shell codes getting injected into that memory And once it's replaced it updates the entry point and resumes execution So if we wanted to continue to debug that we would just have to recognize that pattern Which is why it's important to find those API's and then continue to trace in You might also be able to recognize signatures arguments that are being pushed onto the stack for that call So even if you don't recognize because you can't because this is called to this location that we can't see You might be able to recognize some of the arguments and still Identify the API that's being used that doesn't really scale all that well But sometimes if you're just doing some quick analysis that it can't help This one I called a common dropper and it is a common dropper and that it contains very limited functionality It's just simply trying to go out to some C2 node that is now long dead and download the next stage What's interesting about this one is that it exhibits that same behavior that we're starting to discuss with the shell code But in a normal full PE executable file format So you do some analysis right typically I start by doing some basic things if it's a PE file I'll use something like PE studio look at the imports look at the libraries look at the strings to try to understand a little bit about the file Is it is it going to be employing obfuscation? Is it going to be employee? Is it going to be packed? We need to unpack it first and some of those Characteristics of the file will then just jump out this one has no libraries no imports And even though I've significantly snipped the strings. I'd really had no strings just strings from a normal PE file So that tells me that yeah, it's dynamically resolved resolving its imports It's probably dynamically resolving strings. They're hidden in there somewhere or it's not even using them Which is actually the case here with this sample You can disassemble right it's still a valid PE file So if I need to take to disassembly to start trying to get a sense of the code then in this case I did that and here's a call EAX right so what is what is EAX? You can trace above and see that there's a push and then a pop and then a call So we know that whatever this D word is here. That's actually what's being called But that value is populated at runtime so you navigate to that now in Ida or BN And you're going to see that it's a zero value right so it's runtime dynamically resolving those Again a lot of different approaches. Maybe I just jump to a debugger Ida Pro has an integrated debugger set a breakpoint once I hit that call that indirect call site The debugger will likely tell me exactly what's being called there, but again That's doesn't really scale well you can script it you could script every indirect call site so that Ida could Possibly populate those values for you get a lot of ways you could do that Or you could actually get in and analyze the code, which is what I did here This technique we could spend an hour on alone. So I just wanted to give you the high-level overview And that this is a basic block So if you've ever looked at Ida and a function graph in Ida you have all those blocks right those basic This is a basic block. This is the first basic block in the program and it exemplifies the problem and that we have an indirect call and We have two calls before that and so what we can determine from from looking at that is that those two calls have to be responsible for populating this Jumping into each one they each have a very specific purpose The first one will then locate in memory the DLL that we're going to get an API from so it passes this hash value Which it then calculates in the function based off of the DLL that is trying to find so it's going through all of the DLLs in memory character by Character creating that same check summer hash value and then comparing it to this so it's avoiding strings as it's trying to find The DLL that we're after once it identifies that It returns the image base for that library and then this next function takes an array of Basically the same hash values the exports that it's after it parses the PE file and builds an import table So once that import table is constructed then our program can go ahead and start making function calls Right. It could be a little bit more discreet It could do it an individual API at a time in this case it constructs them per DLL at a time So it's a little bit more noisy a little bit more obvious once you recognize the pattern For the sake of time I'll just really quick highlight kind of the overall flow here I wanted this in here more as a reference just in case you were curious. I wanted to look at the slides You can see the flow. This is the flow of the DLL So it's using the peb the process environment block and you can recognize that usage at the very top here FS 30 hex so it's using the FS register to get the peb the process environment block This allows the program to navigate these somewhat undocumented structures in the process to get a doubly linked list of all the DLLs That are in memory and once it determines the match It can get the base of that DLL and then we can parse the PE file from there That's what this next function is doing and that's the basic flow here So calculating those hashes after it's found the export table the PE file Comparing those to the hashes that it has hard-coded and then if it finds a match gets that function address and then builds an array of function pointers All right, so what do we do with this this technique in this example? I actually created an IDA plug-in and a binary ninja one for that matter and actually made it go through the database and The same essentially perform the same logic without having to do runtime analysis So it went through it populated all of those those call sites that we saw that well I won't back up now but at the very beginning and added a comment to rename them with the actual API so now I could just go through the database and I Could actually see the functions that were being called so Detecting packing I really bias my analysis at this point and that I just assume everything I'm gonna look at is gonna have some layer of packing and I'm gonna have to do some work to unpack it You have to unpack something because if you want to analyze the functionality You have to get it out of whatever it's packed into if you don't do that then you're analyzing the unpacking code so Probably not of interest to you unless you're just curious on how it actually is unpacking Lots of different ways you can do this looking at entropy in the sections look at an entropy in the file Looking at things like strings and imports as we've already discussed and that can give you some evidence typically there's no one Key piece of information that says 100% this is packed It's usually for me It's looking at a variety of different characteristics or maybe features of that file in order to detect that You may open it up an IDA and just get a feel for the functionality itself looking at how many functions are there looking at How complex the functions appear to be and that can also just you look at enough of it You just kind of get a sense of whether something's packed or not by looking at the disassembly I've got a variety of ways in which I've been able to unpack things One of the simpler and one that I prefer whenever I possibly can is just to maybe watch memory allocations So this sample here was a test the crypt and what it would do is it would allocate memory two or three or four times And as it was after those allocations If you just let it run for a while then you could look back in those allocations and you'd eventually find a PE file So the unpacking here was an entirely new PE file that it pulled out into memory and then began executing You can use tools like windabug or whatever debugger you prefer I use windabug so I'm prepared for jeers and and tomatoes to be thrown at me But I like it I think it's a good debugger at least for what I use it for and commands like this Simply allow me to search the process the address space the memory of that process to find strings like the DOS Stubb right and then I'm just limiting the range that I'm looking at so that I'm not looking at PE files up in the where the DLLs typically get loaded This is what it looked like before Limited functionality although it's kind of hard to see kind of strange entry point with the program and no real discernible strings And then once it was pulled out of memory. I had very discernible strings base 64 encoded data things like shadow copy and delete and More complex entry point DLL or when main was identified And things that just made me feel much more confident that the sample was in fact unpacked Okay, here's an example of dry dex this one that technique did not work on because essentially what this sample is doing is It's using several rounds of shell code in order to begin the unpacking process and ultimately it's it's doing a Forget the name of the term now, but it's going to replace the code in the main program when it starts with this unpack code So it's going to allocate some shell code jump to the shell code The shell code is going to replace the original code once that's replaced it's going to jump back So it's a little bit harder to trace through that you also don't have a blatantly obvious PE file in memory once it's all done The way that I attack that or begin determining how to trace that functionality And I've been able to do this technique with a lot of different pack samples is just look for Abnormal behavior and by abnormal behavior. I mean conditional jumps into Dynamic locations maybe an indirect jump into a register or a global variable That's going to get populated after the code is executing this one begins There's an lea and eax the sub routine it then pushes and then rats So pushing before you ret means that you're pushing on whatever your return instruction is going to return to Again kind of odd normal functions don't do that so in this case though, we have the function so we can trace into that and After analyzing that function again, I look at the context of it. I don't want to get lost in the weeds I don't want to have to go through every single disassembly instruction so what I what I Right generally consider is that if this is doing someone packing then it's probably going to begin by allocating some memory It's probably then going to copy stuff into memory Probably de-office skating it along the way and when it's done It's going to transfer control to whatever it just de-office skated or the shell code that it just created So I take the function graph I go to the bottom This one there really wasn't much there other than this call. So if you disassemble this, you'll see what I'm talking about This call right here is calling a d-word and again this value is being populated dynamically during runtime So statically you can't just double-click on that and see that value Set a breakpoint see the value trace into it. It happens to have gone to this location 40 a fe 0 This is an already disassembled function Right, it just was some for some reason being dynamically Populated in that global so you might be able to go back to Ida and find that function So now I can trace trace the program a little bit further Same thing here though looking at the function and its entirety don't want to get lost in the weeds or the details So I eventually see towards the end that there's another call to a local variable So something that we saw earlier with that that shell code set a break point here and this is calling Into this location Right and seeing this in memory now We can identify that this is an address that a dot at the normal image base of our program And so it must have been from a memory allocation. It must be shell code not only do we see this allocation? It's unpacked we can pull this out of memory and we know where the entry point is because we just followed the call to this location So taking that shell code out of memory again I didn't spend a lot of time looking at what all of the shell code was doing I started tracing down to the bottom of the shell code until I found this jump EAX So we're jumping to whatever EAX is in this case It took me to this location 401 a 40 so it took me back to the address space from where that original program began executing So that was interesting It helped me confirm that I was at the point where it was unpacked I went ahead and I compared the location and the instructions that were there in memory Versus what was originally there when I disassembled it and I saw that they were different instructions So now I know I'm at the entry point of the Sunpack codes and I can begin doing some analysis So I didn't have to get lost in the weeds. You could do this in this sample It just takes a couple minutes really and it gets you into the inner workings of whatever is packed inside here Smoke loader is another example. There's the MD5 Sometimes you're going to be able to detect packing with tools that will apply signatures and be able to identify well-known packing routines PE compact to Then there's tools that can help you Unpack that and then I can take you to the next stage That doesn't mean there isn't more layers of packing and in this case There is more layers of packing and there's also some anti analysis So some of that by doing the same process of analysis that we've been talking about Allows you to determine whether or not it's packed So this is just disassembling that unpacked sample and just recognizing that right We've got some again some strange code that we have to start chugging through Some of the techniques that gets the peb at FS 30 hex. So that's usually an instruction that stands out pretty You know it really stands out to me when I'm looking at any binary It moves that into EAX it then moves that into ESI probably to save it to use it later But the important part here is EAX plus 2 has moved into AL. It's then tested in a conditional jump follows That offset in the peb 2 hex right the peb is a structure and you can find it somewhat defined on Wikipedia somewhat defined on MSDN That that member right there is the is being debug flag So it's just simply detecting or determining based off of that structure in a non API way right there are APIs at Microsoft recommends for detecting this behavior looking for the is being debug flag. This isn't it It's just seeing if it's being debug Okay, a little bit later on in the code whole series of checks ESI if you recall, that's our peb It's moving an offset of 68 hex into EAX at then from there uses EAX plus 10 And what this ends up being is a pointer to the process heap And if the program is being debugged at an offset of 10 from that process heap You'll have a value of 70 hex which is why or where this value here for this bitwise end is coming from It then tests and again if it determines that it is in a debugged environment It can modify its behavior or just abort program behavior or the program itself There's one more that smoke loader exhibits at least in the amount of the code that I looked at St. ESI structure. This happens to be the process heap This gives us at an offset of 10 hex the force flags and the force flags is another flag That tells the kernel whether or not that process is being debug if it started with a debugger Right, so several different well-known techniques that are that are still being used and employed This one in addition uses RC4 encryption and so what you'll find is That in some of the functions functions are going to use strings You're going to find these sequences of what appears like random data It looks like a stack string except that if you convert that data to ASCII It's not going to convert because it's still encrypted So one pattern though is overlaps and that is the null byte So CL if we could see all the code up above that register was x-sword So we have a null byte to then null terminate this this buffer of data and so this process repeats So anytime that in this code it needs to de-off you skate or decrypt a string it's going to set them up on the stack and then You'll see this call a little bit later on and I remain renamed mine decrypt string This one took a little bit of analysis to figure out exactly what it was doing, but the gist of it is that it's Apologize is a little bit out of sight out of order That's the function and I said that there's a little bit of obfuscation first That's it injected just a ton of junk instructions at the beginning of this function And that's what the function graph looks like just one big solid line So you have to figure out exactly where those junk instructions are and focus on just the functionality and again Usually you can you can start to see the patterns so you know what's junk and what isn't So this one pushes the size of the string onto the stack so it knows what bytes to decrypt It then moves a pointer for that string into the stack as well. So into eax and then push eax We then push a or move a key into ecx So it's a hard-coded key and that same key is actually used for every single string that it's encrypted So it's a it's a constant key the function is called and After it's called there you can see the key but more importantly if you look at the pointer to the stack string It is now in its decrypted form. So With this because it's using well-known crypto you could recognize that pattern probably write a plug-in go through those stack strings to Crypt them and add a comment or an annotation in your Ida database to help with your analysis jump chains are another problem and this is another technique that smoke loader employs and Here is an example of this problem It starts our program start at start not at main and from here We have a call dollar five that just takes us to the next instruction and these two instructions here This is the jump chain you have two conditional jumps jump of zero jump of not zero They're complementary situations and they're both going to the same location, right? So in this disassembly you see four zero two nine nine d plus two Because Ida doesn't detect that that's not really two separate conditional jumps It's really just a single conditional jump then what will happen is if you put some junk instructions after that It will continue to disassemble and you'll get incorrect disassembly results and you can actually see This right here and that we're jumping to this location plus two, but Ida didn't create this location Right here's our label four zero two nine nine d, but it's going to plus two and that's because this disassembly was incorrect So you can manually fix that up you can convert that back to data and then go to the right location Which is this address plus two and then go ahead and tell it to disassemble correctly, but that's very tedious and time-consuming So there's some scripts. I have some examples and I'm going to link to a few here in just a moment that will go through and Essentially identify all of those situations you can look at the op codes So you can look at the actual byte values and say oh here's a here's a short jump Here's a long jump we see two of them together So we know that the address that you know the jump target is actually where we're going So let's just replace the first instance with an unconditional jump to that location and then not about the other one Right and then your disassembly can look a lot more accurate and it will clean up the code a little bit So that's one of the techniques and anti-disassembly the other thing that it's doing then is also making your function graphs a little bit harder to generate because you have a Jump and then an instruction to another jump and an instruction than another jump And so you've got these chains of jumps that are just really annoying to look at so all of this code If you were to trace through it is essentially just doing these commands here So with smoke loader it is a little bit of jump chains at the beginning and then you get back into kind of normal functionality We'll talk real briefly here because I'm running out of time with fin spy and fin spy does it just about through the whole darn Program so it's more prevalent and it's a lot more painful to deal with for your reference there's a difference between the two original disassembly and then Actually, it looks like the same thing so I had a screenshot apparently I failed to post the right one What that looks like after the plug-in ran and cleaned up all of those locations so the plug-in was able to go through read the actual op codes for all the instructions and then Clean up the entire database for me so that I didn't have to go through and do that one manually one One of those jump spots at a time All right, the last thing is just to discuss a little bit about fin fish or fin spy This one I encountered earlier this year which seemed to coincide with some notable researchers also publishing information about Analysis on fin spy and in particular the use of the virtual machine. So when I first encountered this I didn't recognize I'd never encountered a virtual machine at least used in malware before and I certainly have never taken the time to reverse engineer The Java virtual machine or anything like that So it really threw me off because I didn't understand what I was looking at it took me some time to recognize what it was and Because some of this research happened to come out at the same time became very instrumental for me to figure out a little bit better What was going on here? I won't get into fin fish or fin spy because I don't really know a whole lot about all the data breach and stuff It's out there. It's on wiki leaks. It's still being used. It was sold by a German UK company as a IT Monitoring solution to put it very politely And the resources that I found the most helpful in analyzing this e-set has a white paper with some code So it's an almost 100% solution There's some gaps that you'd have to fill if you were going to try to recreate this work based off of their paper Mobius strip has a site and there is an extensive number of articles there really great resource and then Microsoft has also published some technical analysis. So three really great sources of information came out earlier this year So why a virtual machine? It's another layer of obfuscation So if you take a dotnet program for example, it's bytecode it gets interpreted by the dotnet runtime the CLR and That bytecode is then interpreted into machine code So if you took a dotnet binary and to disassemble it with with Ida Pro You'd be looking at that bytecode and that process of however. It's being converted or some something that would look pretty awful Anyway, I does not the right tool, right? There are tools that will then be able to parse that bytecode and turn it back into decompiled code So DN spy as an example, it'll look like the original or more like the original C sharp This creates a nice layer of obfuscation and at least for me one that was pretty effective when I encountered it There's a virtual processor that is now built into the program versus having that virtual machine running within the host So there's a distinction there Full of bytecodes of virtual instructions that have to be translated through the program Into native code in order to get the actual functionality So in order to understand what the program is doing at least from that that static analysis perspective is you have to understand What those virtual instructions are how the virtual machine works so that you can understand how it's translating those into those native code calls So it's quite a bit of work Those the processor the bytecode that the intermediate code that can be defined by the developer So you can find that it'll be easy if they have of course the source to build this Something that they can easily tweak so that your your scripts or tools that are that are tackling these problems can change and you have to update those As well as of course there can be a variety of different VM solutions out there and there are there are some proprietary ones that That you could take a look at Okay, so this sample if you grab a copy the MD5 as I put at the original slide and you disassemble it You're gonna find that the beginning starts with a bunch of junk instructions And as you navigate down those junk instructions, you'll find this pattern, which is this push followed by a jump This jump to this location is actually our entry point so it's like our the beginning of our VM and This push value right here is identifying the virtual instruction So we're calling the entry point. We're pushing the idea of the instruction that we want to call and that starts the process One way you can recognize this and this is what I was referring to with all these junk instructions One way you can identify this is by looking at the cross references to that location And you can see in this sample here that there are 124 different cross references to that location So it's a very heavily used point in the program so My initial assessment was that it was the entry point as well as you can I was able to confirm that with some of that research that was also published From here, you're gonna run into some jump chains so the first thing that you had to do that I had to do was You know really adapt the script that I had made for smoke loader and get it to go through this database and try to identify all These sites and really clean up the database once I was able to do that Then I was able to create a cleaner call graph So I could then convert that location to a function and I could toggle from the linear view back to the function call graph view And I came up with something that looked like this We won't have time to go into all the details here and So we'll just focus on the essentials and what this is essentially doing is it's preparing what is called the dispatcher so we're taking a Virtual opcode a virtual instruction the virtual machine this entry point then it's going to do some things to prepare This dispatcher to know and process what that instruction is and the code that can handle its interpretation its execution So that's all that it's doing. So it's it's allocating some memory It's creating a virtual stack for the VM that's going to be running With this sample it did do some encryption. So the instructions had to be X or decrypted They were then packed. They had to be unpacked. They were then still encrypted. They had to be Decrypted again. So all of this is happening inside of this chunk of code and and Eventually once we get to the very end then it's ready to call the Appropriate dispatcher. So that is the the section of code that's responsible for now interpreting whatever that instruction actually is You said had some really good Tools available because they did a lot of in-depth work here So they identified some key structures that are available or that are used throughout this virtual machine one is the context so when an instruction is about to be executed there is a structure a context structure that's created and that structure Crap got ahead of myself That structure contains important elements like where does the stack begin? Where does the image begin? Where are the arguments? Where is the virtual instruction? And I have it listed here a little bit better later on At the end of that that start that entry point of the virtual machine You'll find this jump and this is the actual transition from start to that dispatcher So at this point you could set a break point and you could see where this is going and where this is going is Essentially a jump table right so it did a little bit of analysis there and preparing for the execution of that virtual instruction To load the right location for that handler. So it's just a jump table This is what the dispatcher look like and That last basic block is where that handler will then transfer that control the dispatcher will transfer control to the handler So what you can do is you can actually add cross references to those locations So we had that jump table the list of those those those called those jump targets And you can go in Ida and actually add cross references to those you can say okay at the end of my dispatcher function There's actually cross reference to this location and if you do that then it will make your function graph look like this Right, which at least to me made it look a little bit more obvious as to the fact that there was some sort of a Dispatcher routine here. So jump then this code here is the dispatchers this handles whatever that virtual instruction was as I said, there's still more to go and there's a context structure that contains The pointer to the bytecode the address the VM stack the image base the bytecode start address the virtual instruction parameters and Instead of linking to it here in the slides ESET has the entire structure documented So what you can do is grab that structure and then you can create it in Ida and then you can overlay that structure and those Offsets into where that's being used in your code and that'll grab add more clarity more visibility into what that program is actually doing This VM has 34 handlers those jump tables those handlers that we talked about there's 34 of them That means there's 34 op codes. So the next step is to signature what those are doing and then move into the process of actually creating a Decompiler, so this was by far for me the most difficult difficult level of obfuscation that I encountered because there was so many steps involved with it And the time that I had to devote to this as a project for some work. I was doing This far exceeded that time So I have a better understanding of how they work, but again, it's a lot of time involved here So I thought of a relatively effective way of slowing down the research and the analysis 50 minutes So that's all my time. I appreciate everybody Spending the last 50 minutes with me talking a little bit about malware and obfuscation again any questions comments Anything I said wrong you want to correct me on please feel free to email me jstroshine at vda labs.com and Hopefully everyone has a great torque on so thank you