 All right. Well, thank you everyone for coming to the talk. This is a invoke dospiscation looking at fin-style DOS level command obfuscation and hopefully by the end of this talk the syntax of this title slide will make just a little bit more sense. I'm also obsessed with coffee which is why there's latte art on the front. A little bit about myself. I work with Mandiant FireEye out of the Washington DC area. I started out doing instant response for a few years and am now transitioned to the advanced practices team doing applied research basically writing detections and my kind of sickness or obsession is looking at obfuscation techniques to break my own detections so that I can make them better before an attacker breaks them. And so some of the obfuscation projects I've worked on include that invoke obfuscation cradle crafter invoke dospiscation which we'll talk about today and then the revoke obfuscation detection framework. Brief disclaimer nothing I talked about today points to any specific client of FireEye or Mandiant most of the stuff I'm talking about we've never seen in the wild before but standard disclaimer. So today we're going to look at a quick overview of kind of the state of obfuscation and kind of from different angles from red blue and then we're going to look at three case studies that really propelled me last year in so starting this area of research and then we're going to look at a couple of different layers of obfuscation starting with something as simple as like binary name obfuscation and then diving into character insertion obfuscation and then adding all those things together to do full payload encoding all using just native command.exe. And then we'll do a demo of invoke dospiscation and then we'll talk about detecting dospiscation. There's a lot of content here and so I posted the slides online and also there's a 36 page white paper with all this research in it as well so if you don't like the sound of my voice you can leave now and then just read the white paper and all the information is there with just a few less memes so there's options. So first the state of obfuscation what does it look like today? Well why obfuscate? From a red team perspective obfuscation is great because it takes relatively little effort to evade rigid detections and typically they're targeting static detections to evade but also some dynamic as well and it increases the work for defenders so we as defenders even if we detect this payload we still have to take extra time to decode it to de-obfuscate it and see what is actually happening here. And there's obfuscation frameworks from almost any language you can think of most of them open source and even though I may be biased I don't really see it slowing down anytime soon because it's just so effective. From a blue team perspective there's actually been some significant strides in visibility and capabilities over the past several years. Things like Microsoft's anti-malware skin interface or some things that have been around forever like event tracing for Windows that as the defensive community we've kind of started to embrace more and use for better visibility and then also some more signature-less kind of detection approaches using some different data science techniques. So there's been really cool strides in this industry for detection but attackers they just respond and sometimes they respond by choosing a softer target in general or they'll just straight up disable these defensive capabilities or they'll use languages that just don't provide this additional visibility. So this talk is kind of my response to all of this and looking at command XE obfuscation as a defender most of the detections that I see in conversations I have when it comes to command XE is typically looking for a process named command XE followed by certain arguments. Some additional detections could be looking for like parent child process relationships. So explore spawning command XE is a little less suspicious than when we're spawning command XE. There's tons of caveats to that statement. You could also look at command XE as like the source of action. So command XE modifying a registry key or doing something weird like that or make a DNS request or something of that nature. But really when it comes down to what's what's the purpose of building an entire framework for generating obfuscated payloads for command XE. So what got me into this was specifically three case studies of actual attackers that we investigated last year. And my manager Nick Carnite we co authored this blog post last the end of June about these three different techniques and these three different attackers. And so the groups we're going to talk about very briefly here are fin eight financial threat actor APT 32 also known as ocean lotus out of Vietnam and then fin seven also known as carbon act. So the first example was in February of last year on fin eight. They really like to obfuscate their macros. And so this is a de obfuscated version. And basically they are using a lot of process level environment variables to store their payloads in a lot of different places. And then they're setting a power shell command which is just power shell dash into one environment variable. Now when you run power shell dash it runs the power shell process and it executes standard input as the command. You they didn't have the very bottom here they have the rest of the power shell command which is pulling and reassembling the payload from additional process level environment variables set by the parent windward process. And so then the only child process you see out of windward.exe is the command at the very top command slash C echo var one pipe var two which is echoing the power shell command into power shell dash. That's really cool. The second one APT 32. They APT 32 really embraces the the the latest trendy thing on Twitter. And so like when Casey Smith tweeted the red serve 32 squibbley do downloader APT 32 as did the rest of the world it seems jumped on it very very quickly. So defenders also jumped on it very quickly and started to write detections a lot of them based on slash I colon HTTP. And so APT 32 did as they used the tried and true carrots. Now the carrot is the escape character for command XE but if you escape a character that doesn't have any escapeable meaning that nothing happens. But now this carrot is in the command line arguments or in the event logs. And so it can evade rigid detections that don't take this into account. Some people do take this into account. So APT 32 did was they use the double quote instead. Now I mentioned the double quote a couple of times over the past few years and I'm amazed that more attackers don't use it because it has it's a lot more resilient than the carrots and a lot of defenders aren't looking for it but it was cool to see them pull this out and you can actually see they didn't put it in the entire command. They only put it very strategically in certain pieces that they knew detections were based off of. So I kind of call this tasteful obfuscation as opposed to just throwing everything against the wall. Now this last example single handedly like blew my mind and started me down this entire area of research. Then seven then seven APT 32 they compete for first place in my heart for the coolest most tasteful obfuscation because they really obfuscate just certain pieces and they do it really well. So this is actually extracted from a malicious link file that they dropped. And it's actually has some JavaScript level obfuscation as you can see some string concatenation then for eval that should do a ASCII conversion and concatenate it. So that's kind of cool and they're echoing that onto disk but the two red boxes are what's really really interesting. Now when I saw this it didn't make any sense because as you can see there's this W script command but has this at sign in it. Now it makes sense if that was a carrot or if it was a double quote but the at sign I couldn't get this command to run when I copied and pasted that and ran it. So what's going on here. Well first they're running command and they're setting this W script command into an environment variable called X. They then write out the JavaScript file but then at the very end they echo X into command because just like PowerShell command can also receive from standard input. But then they put in these garbage delimiters the at sign they put it in W script and J script because perhaps some defenders were looking for these static strings and link files. But then when they echo the X variable they actually make space after the variable name and they insert this syntax right here which is really fascinating. So what this says the colon after a variable name but before the final percent it says any string on the left side of the equal sign find every instance of that string and then replace it with a string on the right side of the equal sign. In this case the string is just a single at sign and there's nothing on the right side which means in memory remove every at sign from the variable X. How freaking cool is that. This this is tasteful. This is delectable. This is very just has so much finesse to it. And it got me wondering this is native to command dot XC. Like is this a Winten thing or is it been around forever. So you start googling this stuff and realize this has been around for freaking forever. Like how cool is this. So this all happened very quickly. We found this payload on a Wednesday blew my mind on a Thursday wrote the blog post put it out on a Friday. I went home couldn't stop thinking about it. I spent that weekend writing this small P.O.C. which I called out fin coded command for like fin style encoding and I released it on GitHub that Sunday and as soon as I released it I kind of sat back and thought I wonder if there's more here. This was one really cool trick and I wrote the P.O.C. to come generate some payloads to test my detections. But what else does fin seven know that I don't about command dot XC what are hidden gems are there in this tool that that we may get blindsided by in a couple weeks or a couple months or maybe it's been used for years and we just never seen it. So implications of the kind of obfuscation we're about to talk about. I would argue that it affects both dynamic and static detections and I'll kind of revisit this throughout. But but basically as a defender a lot of times we'll think this is only going to affect static detections like if you're running yarrables against link files or extracting macros and looking at that but you know these characters will be removed when it actually runs on the command line. In that link file example when W script actually runs that's true there is not going to be an at sign there but there are things that we can do that remain. So we'll look at that. So basically with this research and with the tool that I released with it you'll be able to take any arbitrary input command for command dot XC and start to apply a layer upon layer of obfuscation. It's something that looks like that. Let's see how it works. So hang on tight. There's a lot of information. We're going to move really fast and we're going to visit all these building blocks. We're going to stack up to at the end be able to do some crazy payload encoding and obfuscation and then we're going to talk about how in the world you go about detecting this stuff. So let's start with obfuscation of binary names. Now a lot of attackers know that that defenders will write detections that look like process name is command dot XC and argument contains A, B or C or D and E or blah blah blah. So an attacker could just simply copy command dot XC to like benign dot XC. That's one way of evading based on binary name but that's not what I'm talking about. There's also a lot of kind of command dot XC substitutes. So to break parent child process relationships if you have a rule looking for when we're responding command one attacker could just use for files dot XC and launch their code or they could use PCA Lua or they could use run DLL or MSHTA or all these sorts of things some more obvious than others. There's actually there's kind of the term wall bins has been getting pretty popular recently and so a lot of different people are tracking a lot of these native binaries that you should start looking for in addition to command dot XC but that's also not what I'm talking about. I'm looking at just purely the syntactical obfuscation of the string CMD and the string powershell as two specific binary names that we'd like to obfuscate. So one way we can do this is through environment variable encoding. Now this is going to buy you good static detection like in batch files or like if you're looking at persistence and registry but in most cases this will resolve on the command line so if you're looking at like sysmon EID1 or security EID4688 for process execution events for the most part this will be de-obfuscated but what are we talking about? If we echo the environment variable program data it's C program data or whatever drive you have mapped so if I want to produce the string CMD to spawn command I can start to take substrings with this colon tilde first index comma look ahead and start to concatenate stuff this way. You can do the same thing with powershell as in the bottom and however I wanted something that didn't resolve on the command line because if you copy and paste this into the command prompt or run it to like W script shell when you actually see the command that runs it's de-obfuscated however there are ways you can produce the string command and powershell without it actually being resolved in that initial command so set ASOS and F type these are just three internal commands that I came across as being useful to basically reassemble these strings. If you run set it'll show you all the environment variable names plus the values ASOS and F type are actually related so ASOS is going to show the association between a file extension and the associated type and then F type will map that type to what binary should I run with what arguments to run this thing but the reason I chose these is because each of them if you run just the command you'll get a lot of standard output and they will contain the string CMD or powershell as it's aware in that output so let's take the set since it's the most kind of straightforward example so if I do set then find string powershell I get two hits that come back one is for the path variable the others for PS module path well if I'm an attacker then the path variable is likely going to be really different a lot of different environments so maybe I'll stick with PS module path maybe that's going to be more consistent for what I'm going for so instead of doing find string PS module path I can just do PSM and that would also give me the result and at the bottom you'll see it's a code snippet from invoked ossification that will basically random would choose one of these substrings that will produce just the result for PS module path so this is the exact text that we get this bottom box here so now we actually see there's two places that the string powershell shows up what we want to do is we want to basically lift both of those out of the text and the way we can do that is look at what are the characters the delimiters on either side of powershell and in this case it's the lowercase s and the the backslash for both examples so now if we delimit on the lowercase s in the backslash it actually breaks up this value into 13 pieces and we're interested in the fourth and the 11th piece both of those being powershell so now how can we actually do this on the command line using just command XE well the for loop and command XE actually has a delim's of argument so what we can do is we can run the for loop and at the very end we run our sub command which is our set find string PSM it then takes those results it applies the delimiters that you gave and then you can say I want the fourth token and then it returns a string powershell and we can either just echo that string or we can just say do the string that comes back and it actually executes the string that comes back so in this example the for loop runs it extracts a string powershell and then invokes it or executes it and in this case drops us into a powershell prompt so in real quick why this is important if you're looking at process executions you're going to see command the XE run and nowhere in that argument is it going to be the string powershell but you're obviously still going to see powershell runs a child process so this isn't removing the process execution but it's basically changing the dynamic indicator itself within the calling process so that was binary name obfuscation just kind of a quick look at that character insertion obfuscation where does this look like in most cases this is more useful for evading static signatures but there's plenty of dynamic use cases that I think aren't talked about quite a lot the characters the most common one the the double quotes as long as they're evenly balanced that's really important we'll look we'll see why in a later example this is what we saw apt 32 using amongst a lot of others but it has some really nice features compared to the character especially when you have a lot of child processes because the care escape character if you have 10 child processes you have to double up your escaping at every layer because it gets topped in half every single time with the double quote there's no escaping of it so it'll persist all the way down no matter how many child processes you have encapsulating parentheses we actually the first time I saw this being used I don't think it was being used for obfuscation purposes it wasn't investigating some newscaster activity but for any for any command and in some subcommands you can actually wrap with as many layers as you want of evenly balanced parentheses and this could be important it has a defender your writing detection is looking for like catnated commands using like the single or double ampersand or the double vertical pipes and then looking for white space followed by net stat or some other command well now you can actually put a lot of parentheses in between there so if you're writing those kinds of rules you need to take that into account as well leading and trailing special characters this may be a little hard to see on this slide but in after looking at the parentheses that got me wondering what additional characters exist that you can still put in a command that's that will function properly and so I wrote a little fuzzer script to go through and start to injecting characters and running the command and seeing if the expected output came out and so with that tool I basically came across the comma and the semicolon now you can put a comma or semicolon almost anywhere where white space exists and basically it's when white space is acting as a delimiter the comma and semicolon can also be used as delimiter characters now this will get really crazy really fast when we start to add all these pieces together um standard input argument hiding we looked at this in the previous example you can echo content into command um non-existent environment variables this is only good for static like for batch files it doesn't work on the command line but uh and this this was actually was from a blog post that someone wrote several years ago so I didn't I didn't discover this um but basically you can put non- existent environment variables all throughout the command and the batch file will essentially resolve it to nothing and then the command is de-opfuscated when it runs um but again it's only for static batch file stuff it doesn't work on the command line setting custom environment variables we've seen this used primarily in like link files um where you can basically chop up in this case they're they want to chop up the string power shell and so they set the character p into a variable and then they call that variable in the same session and we'll look at some of the components of this command that let you do that all within the single uh all within the same process which is pretty interesting and actually a core building block of what's of what we'll talk about over the next few slides um and then as we discussed earlier you can use existing environment variables and just start to concatenate substrings of existing values so when I released outfin coded command poc one of the options was do you want your final command to be run by command.exe or powershell.exe and so I also included a couple just kind of like pre-built obfuscated syntaxes for doing command or powershell um and these are the two tweets I put out just kind of showing you can run command or powershell with these concatenated substrings then someone replied on twitter with this an entire command of nothing but concatenated substrings funny enough some people actually ran this and then complained to me that I infected their system and it's like I didn't even write this what are you doing running code on the internet so that was interesting so once in the research process once I started to find some of these techniques as soon as I found another technique I documented it but then I built the detection for it and said have we ever seen this before I started to search our internal repositories as well as like doing like retrohunt some virus total and just scouring web forms and seeing what I can find and for like for the substring concatenation it's actually been around for a long time this is an example of a devourer malware back from 2012 and I'm sure it's a lot older the technique goes back a lot further than that but this one just happened to be reuploaded to vt not too long ago where they're basically using environment variable concatenation to do batch file obfuscation this next one is really cool this one actually is used a lot and even by a couple interesting Chinese APT groups using a variation of this tool JS batch obfuscator is written two two and a half years ago it's up on github it's like less than 50 lines of code but it's a really cool tool just for obfuscating batch files but this uses an approach of instead of using existing environment variables the batch file starts with setting a random name environment variable and setting it with a full alphabet or later custom versions just do only the characters needed in the command and then the rest of the command is just concatenating the characters one by one from that random environment variable and there's the decoded version there of this particular payload and this last one I won't go into too much detail but if you check out the white paper this was a really interesting fish and really interesting payload called a batch encryption just one piece of a larger kind of obfuscation component but this actually combines both known environment variables and unknown environment environment variables by setting them into a variable called a single quote that's just what they named it and then the rest of the command goes through there but again a lot more detail some of the white paper but all this to say that it's cool when something you didn't know existed all of a sudden your eyes crap this has been around for a while and I'm just now seeing this with my own eyes based on this research I think I'm on to something but I wonder if there's more things there that I've never seen before so let's keep going into advanced payload obfuscation now I use this example here and if you're a defender the first half of this command might look familiar comm spec bc start b min like this is used all over the place but like metasploit and several other tools and if you see this in the registry and like a run key if you see this in the security 7045 service creation then you have some issues percent comm set percent should send up huge red flags to any defender which is why I wanted to use this in this example and the rest of the command is just doing a net stat fine string something simple that we can use to obfuscate and you can see we run the command here it's looking for listening results when you run net stat here's a quick breakdown of the components of this command whenever you look at a command either as an attacker or defender it's interesting to to ask the question are all these things necessary are they necessary in this order can I change the syntax of any of this and still get it to run how I want it to so starting with comm spec there's two ways we can go about obfuscating this one is using environment variable substring syntax so if you echo comm spec it's 27 characters and it's the full path to command .exe so using substring syntax we could use we could say hey start from the zero with character and go out 27 characters unless you use that value and that's going to be the full value you don't have to specify how many characters to go out if you don't it will go out to the end you can also do reverse indexes so start from the end and go back 27 characters to start and then go forward the rest of the way and there's nothing saying you have to use the exact length instead of 27 we could use 1337 or anything that's greater than the value of the variable so these will all still successfully produce a string command .exe with a full path you can also use environment variable substitution so just like we saw fin7 substituting the at sign with nothing to remove it we could basically say substitute four slashes for backslashes or substitute something that will never exist with something else that we never want to see because it doesn't matter all we're doing is breaking detections that are looking for percent conspect percent so let's just choose two of these and keep going we can randomize the case of the variables if anyone's doing case sensitive detections on this looking for anomalies is actually a good way to detect some of this stuff but just in case as defenders we should know it's possible to do this you can also add white space before each of the two indexes and actually the bottom command technically this changes how it functions but it doesn't matter because we wanted the original value anyways and then we can also explicitly sign integers now I don't know about you but I've never really looked at a zero and thought it needed to be positive or negative because that doesn't make any sense but it's actually technically possible on the command line so maybe that's an interesting thing to look for do I ever expect to see that so let's go with the second option and put it in the command now a really important point here is that context is crucial and I do get a lot of complaints for this because people complain that my tool doesn't work if you dive into this payload or that payload and I remind them it's like you know I'm a defender right like I didn't write this to like pump out all these crazy things I wrote it for defenders to be able to look at all these options and to write detections for it and if you're an attacker and you're too lazy to go and fiddle with this then you probably shouldn't be using this so the context is important if you drop this into command.exe it will run if you are in a command like context like wscript shell this will also work but if you drop this command into like a service or registry run key or something like that it won't work because this substring syntax is a command.exe thing the reason percent concept percent works is it's literally like a find and replace the operating system does in the run key or service to say oh this is a known environment variable let me lift that and replace it with the value but it doesn't know how to interpret the substring syntax now this only matters for the first part of the command if the first part of our command is just cmd.exe and then later we use a substring syntax that's fine because the command engine is interpreting that but it's just something to be mindful of so for the rest of the command we can apply a lot of the techniques we talked about in the last section so we can randomize the case of all this we can actually remove a lot of white space so I don't know if you've seen many commands that don't have any white space between the arguments but bc start bmin all that stuff white space isn't needed and a fascinating thing here is that you'll see there's zero white space between that first argument slash b and the cmd.exe but when you look at the dynamic execution the operating system adds a white space in there so if you write a detection that works for this command if it's in registry it's actually gonna look different when you actually see it running on the command line or when you see it in process execution logs so now wow we can actually have to write slightly different detections or more robust detections whether we're applying it to dynamic data or static data it's getting tricky so we can remove that white space netstat a and o we can just move that around because it still runs just fine we can also add a lot of white space remember those commas and semicolons we talked about? anywhere where you have white space used as a delimiter you can use commas and semicolons but you can put as many as you want even if you don't need a delimiter there and it actually doesn't affect the command we can add tons of character characters and we can escape at multiple levels depending on the functionality we want to exist depending on how many child processes we have and if we run this look the process execution is like bottom up we'll see that we get this interesting intermediate command that's highlighted blue so as a defender and we'll talk more about this in the detection section if you see command.exe run as command.exe two spaces slash s space slash d space slash c no space double quote one space and then something this is actually an artifact of the operating system in a couple scenarios like sub command execution or when you're piping content into a new binary it'll actually spawn this intermediate process and there's really interesting and valuable detection opportunities when you see this in the hacks right here that we'll talk about towards the end of this talk but the important thing here is that the carrots in that intermediate process they're all chopped in half right because the escaping diminishes by half every single layer and once you get to the fine string and the net stat there's no obfuscation left these characters are all gone you're just left with the spacing and the casing so if the comma and semicolon and carrot don't persist is there a character that does persist into that final child process the answer is yes and the double quote is making a shining entry in here and what's awesome about this is that you don't have to worry about different layers of escaping you put it in the first command it persists all the way down into every child process so when in writing the tool this became insanely complicated to basically keep all these things in place and in doing power shell obfuscation it was great because you have access to the language tokenizer to parse the command you're looking at to know this is a string this is a command this is an argument you also could have access to the abstract syntax tree to do all this kind of stuff command actually doesn't have any of that crap so it gets really tough to basically piece all this stuff together and know kind of where you're at and how many layers of escaping you need at each part so this is what I call the world's tiniest violence slide defenders are giving me no sympathy right now but basically it was a really interesting challenge to go through without these tools that I have with power shell and it was just a much more rigid kind of framework to work with them for an obfuscation perspective so some defenders may look at me and say okay dude well I don't care about your dynamic stuff because I'm already looking for carrots I'm looking for commas and semicolons plus half those examples they were removed anyways and okay maybe I didn't know about the double quotes but I'll start looking for that like this doesn't really phase me like why should I worry about this obfuscation stuff as much as you're talking about well I would argue that obfuscation is a great way to give zero crap about an attacker's intent because if I can detect obfuscation I don't have to think I wonder if this net stack can manage malicious or not it's like whoa obfuscation someone doesn't want me to read this I'm super interested now so I would argue it's important to detect obfuscation in and of itself and as another reason why there's a lot of things an attacker can do that if they have a command.exe argument that's obfuscated that never spawns a child process a lot of recon an attacker could list all the files they could type and actually essentially cat the files maybe they would add an entry to your host file and sinkhole your cloud-based security product wouldn't you want to know about that if this command never showed up in plain text what was insanely obfuscated I would want to know about that so with this being said the last part of this research was is there a way that I can obfuscate any arbitrary command without using any of these characters that we just talked about without having to rely on these special characters that defenders could I don't want to say easily implement but could start looking for is there a way in a sneaky attacker could get around so the first of the four techniques we'll look at is concatenation so netstat tack ANO we'll use that example again and fun fact you can also use the forward slash instead of a dash for that argument right there this actually has really interesting implications so as a bonus think about as a defender or an attacker what are the detections that are based on arguments for commands okay if you're looking for w script slash no logo you can actually change that to a dash and it works for power shell not non-encoded instead of dashes you can use slashes or interchange them for red serve detections looking for slash I colon HTTP you could use a dash and get right around that and also if you look at the URL instead of forward slashes you could use backward slashes so how many people are looking at different slashes in url so maybe they just do HTTP colon and that's enough in some languages even let you interchange forward and backward slashes after urls so again when we're doing content regexes or things like that like are we taking these things into account so anytime now when I'm writing a detection if I see a slash or a dash you better believe I'm interchanging those and playing around and poking at it to see is it possible with this binary to do this thing so back to concatenation what we're going to do is we're going to set our net stack command into an environment variable and then let's just echo the variable in this case we're calling it calm and let's just make sure our payload was set successfully now if we just echo the variable it actually doesn't give us the value it just gives us the variable name that's because the variable isn't expanded in the current session so two ways we can do that the very bottom example is we can just spawn a child process and then at that point the variable that we set will be expanded but I don't really want to spawn an extra process that's a little too noisy so what you can actually do one example is using the internal call command which says expand the variable I want the value of it and as you can see in the middle command we get the value so if we replace that into our command then if we run it then it actually successfully expands and executes the value we just set okay perfect well instead of having one variable what if we chop up our entire command into three variables comm one through three and then we call the concatenation of comm one two and three now an interesting thing happens here it runs successfully but this is actually some screenshots from sysmon eid one and if you'll notice the parent command line is perfectly fine but the image process command line actually has two percents for every single percent and this is incorrect this is I released the blog post several weeks ago on this this is actually a parsing bug in sysmon where it doesn't properly escape the percent and there's really interesting bugs that come out if you're using event viewer to look at event logs or power shells get one event it actually improperly handles this improperly escaped percent there's a lot of implications there but essentially you can if you have detections that are relying on it being a single percent then sysmon is going to give you double percent so I don't mean to harp on that too long but basically it's important to test your data as well as the tools you use to analyze the data and try a couple different tools to make sure that it lines up actually I reported this bug twice to Microsoft over a year and a half and I hope to see it changed maybe after a year and a half that'd be nice so anyways what we can do is we can also reorder our substrings when we set the initial command as long as we reassemble them back in the right order and then finally we can just set all of them into a final command and then just have one command to play with for our final execution options so that's that chopped up into little pieces reassembled into a variable called final we can just call final and it runs our command now at this point there are kind of five options in the tools for how you can run the final payload one is what we have right here if at all possible we don't want to spawn a child process so let's just run the call command now there are fringe cases in which you have in which I've not found a good way to not use call like if you have vertical pipes or things like that when it expands it actually interprets it so it gets kind of weird in that case you want a child process which are options two and three you can basically just say command C run the final variable or you can echo the final variable into the command the second process and options four and five are the same except they have to do with PowerShell so I also built into the tool the ability to handle PowerShell layer escaping inside of DOS layer escaping to handle that and that was just madness but it's there and it works and this is kind of what that syntax will look like and so with this basic command we've obfuscated the netstat command and dynamically it looks you'll still see netstat run as a child process but our original command here is chopped up and we didn't use any carrots commas, semi-colons, anything like that but if we're evil and we want to we totally can and the tool will help you do that so you can randomize the case you can add a remove white space you can also add commas and semi-colons you can add carrots of different layers you can also add the nested parentheses and it runs just fine now when it runs in this case it still just runs the netstat command but what you can do is as input you can add your own obfuscation to netstat like carrots for double quotes and the tool will properly handle all of your special characters at input and it will handle all the layers of escaping necessary to still produce the proper command as output so if as input you have netstat that has double quote double quote inside of it the tool will properly handle that throughout all the layers but now there's a huge difference here between two double quotes side by side and double quotes that aren't adjacent now it's important that you have evenly paired double quotes but the reason this is a problem if we try to do this in the command it's actually not going to work because there's no way to escape double quotes in the command.exe's arguments and the fact that these double quotes remain is just kind of this weird concept of like almost the arguments are just kind of being like concatenated together but the quotes still stay so this is a problem for me how do I if I have evenly balanced double quotes that aren't adjacent how can I make this work because there are going to be situations in which someone wants to input a command that has double quotes that aren't adjacent so I kind of after a lot of headbanging came up with a four step solution for this that's all handled in the tool if you ever have something that has to be double quoted like this it handles all this for you so basically anywhere where I want a non-adjacent double quote I double it up I make two double quotes the next step is I set an environment variable in this case let's call it quotes and I set it with the value quote quote because I have to have an even number of quotes throughout my command next our final variable I'm going to use this substring syntax or this character substitution and I'm going to say hey find every instance of quote quote and I want to replace it with one quote but I can't just put one quote there because then I'm going to have unbalanced double quotes what to do but what I can do is inside of this I can call the quotes variable and say I just want one of you now in the command we still have even double quotes but in memory I want just one unfortunately this doesn't work this doesn't work because of those percent signs because we have our final variable that's percent percent and the stuff in between but then inside of that we're trying to put more percents so that's like all right well how can I get something in memory maybe is there another way that I can extract the value of an environment variable without using percents fun fact if you're on vista or later you can use a slash vista flag now here we are when you use a slash vista flag instead of percents for a variable you can actually use exclamation points so now our quotes variable is resolved in memory inside of the percents there's no conflict there and this command freaking works double quotes evenly paired not adjacent awesome now I have to admit this is a little bit of a troll this does work but there is no such thing as the vista flag if you look at commands help menu you will see though slash v colon on which is enabling delayed environment variable expansion but when I see that I can't just look for v colon on I have to poke at it a little bit what I found is that you can use any substring of v colon on as long as it's not v colon off and a couple other interesting fringe cases but then you can do slash v almost anything else and it still works yikes all right well that just got interesting I'll come back to that in a second we'll have some more fun with that but also environment variable names yeah calm final quotes this is dumb it's just to make the example easier an attacker or a tool could just make all those special characters for environment variable names you could also start with a non-white space character then have differing lengths of white space to be your variable names and it can just get crazier and crazier from there so dude what the crap you call yourself a defender why are you doing this stuff well I started with concatenation because we've actually already seen little baby steps of this in the wild and most of them coming from malicious link files but attackers never seem to move past obfuscating just a small piece of the command and in almost every single case we saw before this research it was just obfuscating the string powershell as in this scenario this one's similar the yellow spots are just like random crap in random variables that aren't even called they're just trying to break it up there's some carrots in that one and then this one as well and as you can see this one uses that slash v at the beginning as well so now we're starting to notice this slash v thing okay that means they don't have to spawn a child process and oh yeah they're using exclamation points instead of percents for the variables cool that's neat so that was technique one of four concatenation and again the part of that we've seen in the wild is just these like little link files the next three we're going to talk about we've not seen in the wild as of the time that this research was finished and when I say that what I mean is that for the past nine months or this point I guess 10 months my life has been looking at these techniques and then searching for them across all of our internal information at FireEye virus total in all these different places and then running all these detections across millions and millions of endpoints and on the network to look for these techniques and I've come up completely empty so I feel like it's going to be really interesting when we see this stuff in the wild but it's all things that we've not seen before before this research so the for loop for loop is freaking cool it has some fun stuff for us from command.exe so I dub this for coding for loop encoding and again if you go back to the commands help menu I love this this verbage here it says you use the variable expansion you can use exclamation points instead of percents which is quite a different thing when inside of a for loop that is an understatement it gets crazy different in a for loop so what do I mean let's start with our netstat command again let's make sure we have that v in there for variable expansion and again it could be any of these options but we'll just stick with v another fun thing remember I said you want to look at your look at your arguments to see do I have to have this or what does this thing mean how many people think the slash c is necessary for command to run non-interactive commands there actually are other options like k stuff like that but c is again just saying hey everything else after this is an argument well if you scroll down on the help menu you'll find that for compatibility reasons slash r is the same as slash c all right well that got weird because I know attackers like to rename binary so I don't want to write my detections based off of command dot xc so slash c seemed like a good place to kind of anchor off of but now instead of slash c we could just replace that with a slash r and it still works okay well I'm going to make sure to look for both of those now that's kind of weird the way I remember this is crv c and r for the command and v for variable expansion another amazing thing is this is what I like to call a huge troll opportunity because all that space before the slash c or slash r you can put anything you want this command works it doesn't serve that gift but you can put almost anything you want and it's not interpreted so an attacker you know could be nice and send you funny messages and stuff in the command some do you could also do this so if an analyst is looking at this what do you think's going to happen when you run this command you'll see the path variable right anything look weird about this what about all this white space before that netstat command down there back slash c has no meaning it's forward slash c that we're looking for or forward slash r so when you run this netstat's going to run so if you're an analyst and you see that horizontal scroll bar be really tiny you might want to slide over and see what's over there or just enable wrapping lines or something I don't know gosh man this is getting rough all right anyways four coding four looping coding how do we do this well we take our command we take all the unique characters for that command and we set it in a variable let's call it unique we then have a for loop and inside of that we're going to put the indexes of each character of our command so for netstat zero one two etc that's our command and then we're going to end with one more value that in this case it's just not going to be one of the normal values and this is kind of our book in delimiter then for each one of those loops we are going to set and append onto this new variable called final the index from the for loop of the unique variable and so loop by loop we're going to reassemble our command in memory and then each time we're going to check and say hey are you the book in delimiter and then if you are all right let's actually execute whatever's in the final valuable or variable and this is what it looks like here and so in standard output you have every iteration of the for loop but none of it actually hits the command line logging which is pretty nice and then the final command runs from memory pretty sweet if you want to increase the obfuscation you can add a bunch of garbage characters into this unique variable or reorder and all that stuff and just update your indexes and it works just fine there and then invoke obfuscation we'll wrap all the building blocks we talked about so randomized casing remove white space add it commas and semicolons carrots parenthesis and then also explicit signing if we want to crap all right so that just happened well there's also another troll opportunity here that I built into the tool for that unique variable you can put any message you want and then any character still missing in your input payload it'll just add those to the end so again attackers can have fun like they can be nice sometimes so you can put whatever you want to in there and uh give some D for people like me some laughs all right concatenation was number one we just talked about for loop and coding or for coding reversal is almost the same except it uses this slash l so instead of having to specify every single index we just say start end and the increment decrement in between and then we just set our command in reverse and iterate through and that becomes our payload we can add additional characters in there and adjust the incrementer decrementer and start and end payload et cetera I'm going to skip that it's in the paper for the final variables and we're using this substring syntax the reason is because in the for loop we don't have any value set for the final variable so we have to basically remove the name of the final variable which we can do with a negative index we can also do with a positive index with the length of the variable these are all random options on the tool it'll take care of this for you or you can do a string replace on the name of the index and the exclamation point and the that asterisk when you have a string replace starting with an asterisk it says find the first match of this and replace that and all the characters leading up to it with whatever is on the right side of the equal sign the very last one is fin coding in this case we're going to start swapping out characters so it take every t in your command we're going to stop it with a z and then in memory we're going to do a string substitution for z back to t it does that swap in memory we'll add another layer and then we'll call the sub one that we just did we'll add another layer and replace a's with sevens later replace it back to a's and memory and then call sub two add another layer etc and at the very bottom this is an example of the crappy poc or at least a year ago I didn't know about the variable expansion stuff so for every single substitution I spawned a new child process so that tree was like one two three four five six seven oh it's horrible and also because of that I had to spawn multiple processes I had to do different layers of escaping for the ands for the ampersand so one layer two layer three layer it got really ugly really fast so that was a lot to go through just got a quick demo if you know me I like to do ASCII art that's the extent of my artistic capabilities I think so anyways this is just some invoked osmosification ASCII art adding some layers of obfuscation some fun color coded stuff the look and feel is it's the same kind of wrapper user interface as the other obfuscation frameworks that I've worked on you can look at tutorials help menus all that stuff I'll kind of show you what to do yellow takes you to a new menu green actually applies a thing so in this case we have three options here binary encoding and payload binary is simply going to produce syntax that is the string cmd or powershell that's it so you can go here and play around with it and just copy and paste that into some other commander payload that you have and then in this case let's copy to the clipboard paste it into command to show that it still works still works sweet let's go back let's say we actually want to input a command and then apply that environment variable substring cat nation we can do that with the encoding options so in this case we're going to set a command let's do ping 8888 we can go show it any time and say here's our command here's all the options we've applied we'll go through level one and you can see it just chooses maybe one or two characters and applies substring or you can do the whole thing copy the clipboard throw it in and we can see that it actually runs it just fine but the real meat of the project is in the third section which is payload which again any arbitrary commander powershell input command you can add all these crazy things so in this case I actually want to run a powershell command from command so I'm going to set my command to be this right host powershell command and then I'm going to say set final binary to be powershell so I'm handling powershell escaping inside of command.exe escaping let's then go to payload we'll do cat nation and there's kind of three profiles one two or three and one is not going to have any of the crazy special characters it's just going to do kind of the least common work or the least amount of work to get the job done but three is more fun let's be real because you're going to get something that looks like that and it's random every single time and you can copy and paste that and see the command still works and kind of as a fast-force a little bit kind of as a finale what I decided to do was I created a powershell command at a bit.ly link I ran it through all my other tools I created a download cradle through invoke cradle crafter I then took the output ran it through invoke office token layer obfuscation I then ran that through invoke obfuscation for this for loop stuff and then when you paste that in I'm actually going to fast forward because this my VM was hating life when I did this like like really not happy but when you do this done interactively it happens just like that so don't be fooled but there you go the command works so red teamers like cool defenders like I'm going to see you afterwards so yet the disclaimer is always please don't use this tool for evil and if you're fin seven eight or apt 32 and define evil differently than I do just don't use it at all I know you will but whatever it's up on github so detecting obfuscation again tons of information I put in the white paper because the whole reason I do this research is to detect stuff I've never seen before to find out it's possible and then to share with the community so you don't have to waste as many hours and nights and weekends as I did on this so again a lot of details on the white paper basically start to look for really long argument lengths we can look for high frequency of these special characters none of this is easy by the way like these bullet points are freaking hard there's a reason it took me months and months and months of doing this to try to get to a point where I felt okay with releasing it and sharing it but one really valuable one is looking for obfuscation of known internal commands because we start to break all this down there's several building blocks necessary to make all this stuff happen and so when you identify those building blocks looking for the obfuscation of those is really important SDC there's more information on the paper about that again artifacts of sub commands and standard input I suffer from FOMO but for me it's fear of missing obfuscation it's very real it's very real so when I'm doing this research I can't keep all this stuff in my head so I write a tool that does it for me and then I generate thousands of examples with that tool and let it test my detections that are right and see hey out of these thousand examples you miss these three and I look at those three and say okay what about these evaded my detections and then I go and add that in so for this project I release the full test harness the exact code that I use to write every detection for from this research and I released it with the project I also released 4,000 obfuscated examples as text files as well as security EID 4688 events as well as system on EID1 events so if you don't want to run my code you don't have to but I have tons of sample data that you can use to test it and the last thing I'll say about this is that when you run the tool like in the demo you only get three profiles of like low, medium, or high and there's a lot of randomization in there but you don't get the full gamut of obfuscation with the test harness you get the full gamut every single time you run it there's over 20 different switches that flips the test to basically change the percentages of all these special characters and stuff like that and basically you start to add in your regexes and your searches for this obfuscation and it'll go through and say hey here's how many you missed here's the ones that match here's the ones you want to look at again so key takeaways attackers love to obfuscate because it's still effective command has crazy obfuscation capabilities when you stack all these building blocks together and as defenders we kind of have to match the attacker's level of creativity and again I know it's not easy but like we have to start thinking differently about some of these things even if we've never seen them before and I really hope that this research will help people do that I just want to give a huge thanks to the advanced practices team mainly Nick Carr Matt Dunwoody been with I get to work with some awesome people who really make hunting threat actors like insanely fun and really support this kind of research which is awesome and definitely my wife because she supports like insane hours of doing this stuff this is about nine months of research over a thousand hours when it's all said and done and just a lot of coffee also in that process so with that here's my Twitter handle my blog the code is on my get hub the white papers there I'll be around the rest of tonight I'm really excited to talk I'm very sure I'm at my time so please come and say hello and ask questions afterwards and just thank you so much for your time it's really honored to be here thanks