← All talks

Save the Env (Variable): Hijacking Legit Apps w/ Minimal Footprint

BSides NYC · 202346:34150 viewsPublished 2023-06Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
TeamRed
StyleTalk
About this talk
DLL Hijacking, a well-known technique for executing malicious payloads via trusted executables, has been scrutinised extensively, to the point where defenses are in a much better position to detect malicious use. In this presentation, we take a closer look at how process-level Environment Variables can be abused for taking over legitimate applications.Taking a systemic approach, we demonstrate that 80+ Windows-native executables are vulnerable to this special type of DLL Hijacking. As this raises opportunities for UAC bypass and Privilege Escalation, we discuss the value and further implications of this technique. We also look at preventative/defensive measures, especially for this type of DLL Hijacking, but also for DLL Hijacking more broadly.
Show transcript [en]

cool let's make a start um hey everyone welcome to this talk in the next 45 minutes or so we will be talking about dll hijacking and how we can make that even more fun by throwing environment variables into the mix I will briefly introduce myself my name is Vita that's a Dutch name I'm originally from Amsterdam but I now live in London in the UK where I work for crowdstrike I've presented before at other conferences for example the sister conference in London as well as the one in Rome more recently and at Defcon last year but enough about me let's talk about interesting stuff dll hijacking so just the structure of this talk will first start by talking about what dll hijacking is because not all of you may be aware and just to make sure we're all on the same page as to what it means a quick recap of what that is then we're going to move on to environment variables and again sort of a reminder what are they and why do we have them and then I'm going to bring the two together in a more attacker scenario so so bear with me dll hijacking um like I said some people use different definitions so that's why I thought it's good I give you mine so we we know what we're talking about to meet the yellow hijacking is the tricking of a legitimate or trusted executable into doing or into loading an arbitrary dll now you may be thinking if you're new to this you haven't heard of this why why would you want that well libraries or dlls on windows are these shared pieces of executable code that programs May load into memory in order to use shared functionality now rather than compiling your own malware executable which which is one option you could also compile this dll and if you trick a legitimate dll into loading your malicious code you can leverage or piggyback on The Trusted or reputable reputation of this program and that means that very naive AV or even EDR software might not see it if you use allow listing software like Microsoft app Locker for example this could be a way to bypass it right so you have a legitimate executable that's trusted somehow zero detections on virus total you trick it into executing your evil stuff now this is a more generic term for specific subtypes some of these you might recognize if you know dll hijacking you no doubt will have heard of dll side loading um I think that's by far the most common type of dll hijacking basically what you do is you need a vulnerable executable you move that to a folder that you control like a temp folder or you know the download folder and you move that alongside a malicious dll the vulnerable executable will just simply load the dll from the same folder it is in and again you have this trusted application executing your malicious code another one I think these are often confused it's dll search order hijacking now um I won't really be talking about search order hijacking today but just as a reminder in Windows if you specify a dll you want to load as a program but you don't specify the full path you just say name.dll then windows will try and help you by searching in a number of set locations if we'll first try the same folder as the executable and if it's not there it will try the system32 folder system folder the windows folder and so on um social order hijacking as the name suggests makes advantage of that by putting a dll anywhere in this order of locations before the legitimate dll so rather clever but in practice I don't see this very often there's a number of documented cases so it certainly exists but compared to dll side loading it's like dll side loading is way more popular another common one that you would almost forget is substitution you literally just take a legitimate program that loads a legitimate dll you replace or somehow proxy the militia the legitimate one with a malicious version and you will all remember stocksnap a very crucial part of that attack was replacing a dll in the system 32 folder with modified code that partially relied on the legitimate version but also loaded malicious code which ended up changing the nuclear reactors actions now three more honorable mentions before I move on to sort of the problem statement Phantom dll hijacking um sometimes programs try to load dlls that don't even exist this sometimes is the result of a dependency that was changed typos are even common so um that's even better because if the dll doesn't exist you can place the dll anywhere in that search order including the path environment variable and uh it will load your code so um sometimes this is even cve worthy if it's really you know trusted application or it runs with higher privileges but um yeah that's that's not a good one Windows side by side hijacking or win sxs this is really rare but I do want to mention it because the miter attack page for Windows side loading for a very long time mentioned this as like the prime use case I think the confusion comes in because it also contains the word side right Windows side by side which is a very specific technique in Windows it's a compatibility mechanism for loading all the dlls I I personally have only seen one or two documented cases I think it's really rare but I do want to mention it just to make sure you don't confuse the two and then finally um it's just sort of like a catch-all bucket input based hijacking this is anything that involves changing like the registry or the command line and by changing that you somehow trick the vulnerable application into loading your malicious dll um some people call it dll redirection um right so we've talked about six types there's a few more but I think these are the the main ones and you might have experience with some of them now from an offensive perspective right um the problem is that these are very well documented and very well researched if you want to learn more about any of these just Google it and you will find plenty of blog posts code templates and whatnot and so you can really get started if you want to abuse this that means from a detection point of view as well because of all this information we have generally speaking this is pretty well detected um all of these types so the question is can we come up with something new that relies on the same principle right malicious code trusted software somehow gets executed that bypasses the limitations of the existing types and you've guessed it this is where environment variables come into the mix I'll just briefly give a background on what they are and why we have them in the first place because it's actually quite an old mechanism and then we're going to move on on how we how we can use it for dll hijacking so um it's a bit I've always found it very strangely named environment variables um but it's basically a global variable right if you've done any coding you'll you know the concept it is a um a variable that you define somewhere in your operating system typically that can be accessed by any part of the OS or programs running under it um if you've used windows or Linux you will you will know from bash scripts in particular right if you use the terminal or the command prompt you will know the pattern dollar sign variable name dollar sign on Windows or sorry percentage sign whatever and then on Unix systems you've got dollar sign and then the variable name so they're quite useful you can set these in scripts or again on operating system level and then use them further down the script but you would almost would forget is that you can use them in programs as well so any program can access these variables and use them in the code to change the flow of the program so in C you can use get n name of the variable and you will get the value of that variable typically these are stored as strings and most often ASCII strings so you can store of course booleans or numbers but you would have to cast them yourselves they're not typed everything is a string and this is cross cross platform now I don't want to change this into a proper history lesson even though we you know this feels like a lecture with this Auditorium anyway um but I do want to quickly remind ourselves why we have environment variables specifically in Windows because it's a bit weird um as I mentioned environment variables are old um as early as version 7 Unix it's the first time in an operating system we had a mainstream operating system we have environment variables the problem they're trying to solve is that there's lots of repetitive information that programs use and you don't want to bug your user every time asking the same questions for example what is your username or where is your home path so they came up with this system where you just Define them once and then every program will know hey if I use dollar sign user I will know the username or dollar sign home will give me the Home Path so it's a pretty clever mechanism and for these early day programs it was it was a godsend it made stuff a lot easier and because you could Define them yourself it made for a lot of computer users life a lot easier in fact it was so popular that only four years later PC dos 2.0 which would later found um it will form the foundation for Windows would also include it there's a little excerpt from the um the release notes the documentation and it's remarkable how it's pretty much still the same in 2023 so it says environment variable is a special case of a replaceable parameter in the command prompt use set and then name of the variable equals value so that is pretty much still how you do it um percentage signs for using it in scripts unchanged ever since so this is 82 and then exactly 10 years later we get proper Windows right where it starts looking like the windows we have today Windows 3.1 that comes with the Windows registry now if you've ever used Windows you will have you will know the registry which is this Central store of all sorts of operating system settings program settings and when you think about it it is basically trying to solve the same problem as environment variables right it's a central place we have all these things like usernames and paths but much better because registry unlike environment variables is typed right you have different types you have hierarchy you have permission schemes so it's much much better than the old-school environment variables and the registry has evolved over time of course but when you think about it in Windows at least you wouldn't really need environment variables if you had the registry right but there was edge cases but for the problem it's trying to solve the the registry is actually pretty good for that and what we see ever since um is that the environment variables somehow always end up in cves and causing vulnerabilities you might have heard of this path environment variable I'm not really going to talk about it today but in the past it has caused lots of trouble um this is something I found on a message board it's the oldest I could find 1997 someone complaining about how this this works and how Microsoft is unwilling to change something about it and he writes infrastration why would any other application developer bother to support secure configurations if this is what they see coming out of Redmond well we'll see later what the people in repmond did and then close to the start of the Millennium the first ever cves were issued and as part of the first batch there was actually a privileged escalation issue um that involved environment variables so long story short it solved a very legitimate problem environment variables I would argue in Windows it's been replaced by something that's more robust and more flexible but what we see is that over time it has caused lots of issues unforeseen things so how are they implemented in Windows then because before I was just talking generically right across platform how did they work in Windows so all environment variables in Windows in out of the box you get quite a few they're all concatenated into one massive string which has an upper limit it can contain 30 well 33-ish thousand characters in total so the names of your variables and the values they hold should not exceed that now you might wonder right so how does Windows where did you store environment variable data because they're still there they're still used but well they're stored so ironically they're stored in the registry so um this is a table that shows in order where it gets the values for the environment variables from and so when it boots your computer the first thing it does it goes to the all user Hive hqlm it will try and find all the defined variables there and it will set them for your entire operating system like even prior to logging in it will set the data there once you log in it adds or even overwrites these variables based on your user specific variables for example your username right that's a good example that's something of user level so once you log in it's set to use it to your username there's also something called current session um again not really going to talk about that today but I do want to mention it it is something where you can set an environment variable and it will live for the duration of your login session and after you log out um it's gone now the most interesting thing and this is where the dll hijacking will come in it's the process level so interestingly enough environment variables are a global variable but every process has their own table with environment variables so every process knows what they are but in theory they could differ process to process so if you know a bit about Windows internals every process has a process environment block the PEB this contains all sorts of metadata about the process that's running and if you look in the process parameters block lo and behold we see a number of interesting things there like the command line whether it's the standard in standard out goes but also the environment block and on the right hand side you see what it is set to in my lab so you see my username there a few times you see a couple of interesting paths like my home path you can see that my C drive is where I installed Windows on so the interesting thing is that every process has its own list with variables and values and that means that if you start a process typically it just passes down the via the environment variables that were set by the parent process if you compute the boots you get an Explorer process if you start any new processes from that most of the time it will just take whatever the the variables of explorer.exewhere so it's just one big chain of processes that keeps passing on these variables you can overwrite it so if we look at the windows API this is one way in which you can start a process and it has an optional parameter called environment and you can actually pass your own variables there which means that if you start the process it will have different values and variables and values then it's parent right so I hope we all have a cyber security mindset right I hope your gear starts spinning how can we use this to our advantage how can you how you how can you break something with this um so when I started looking into this I thought let's look at these variables they are interesting because these are parts we normally don't control right imagine you have initial foothold you don't have any additional privileges yet um you can't really write to C windows or any subfolders like system32 or any interesting ones anyway um so could we start a process maybe change some of these variables and then have fun so that's what I did um I chose one of these environment variables I then changed them to a different location I would then start a process with these updated variables um look in procmon see what this new manipulated run if I could see any different behavior and hopefully if it loads dlls using an environment variable I might trick it into running my variable so it's visualized on the right there normally distrust the program might use a variable to load some dll I hope you can see it it's not too dark but basically it normally goes to C legitimate path then in a manipulated run I start the same process but I overwrite that special variable with my evil path and then if I'm lucky it now loads my version of some lib in my manipulated user writable path I found such an example this is hostname.exe you might know it it's a very boring process because literally all it does is tell you what your hostname is that's all it does and in doing so it loads a number of dlls from the system32 folder strangely enough it relies on the system root environment variable so if I now start hostname.exe but change that system root value so normally it's C slash Windows if I now change it to C time slash Evo I might be able to trick it into loading my variable so this is how you do it in Powershell uh just a few lines just to quickly walk you through it and the first one says this is a new process block second line is where I specify hostname.exe this is important because I don't change the path right this is where hostname is normally located I don't move it I don't change it it's still signed and trusted is there I then remove the system root variable from the stack I then re-add it change it to my path and then the remainder is just making sure Powershell knows how to run it right demo time I'm not going to paste in that code and then hopefully if I press enter it's going to give us some visual confirmation of sorts that a malicious dll was loaded we also got procmon running so hopefully we get the proof there as well so I am going to press enter we've got a nice little pop-up box message box we've got calc because how else would you know we we broke something right and then at the very top you can see the hostname.exe in its normal location we can see there that it loaded C slash template evil and it loaded my version as is also represented by calc and the message box cool so we broke something uh but why would we care right so just take a step back what what is new about this so we got a legitimate process that is present on every Windows installation to run malicious code not really malicious in this case but as you can imagine uh you can you can let it execute anything the cool thing is is that we didn't do anything really special right we changed a variable on process level right I didn't change the registry I changed it on process level um there's nothing really observable in terms of command line or you know you don't have to suspend the process or whatever so from an EDR perspective um this is quite hard to spot um yeah and just to reiterate that right I didn't change the registry I just started the process overwrote the process level values and uh made it made it do something bad and yeah to my knowledge most EDR software they don't look into this sort of thing right they might detect the module out from a weird location but they don't check if the variables are changed because we'll do that and as we've seen a few lines of Powershell can do this but you can also do it with other built-in script engines like VB script or jscript so if you have a macro that you can somehow run um from uh from a not updated office version you might be able to run it from there and you know if you see word spawning some legitimate process sock analyst or an EDR or AV might think it's fine so yeah this is an example in Feb script it's just a screenshot but as you can see it's just three lines of code um you create the the shell engine you tell it to update the system route and then you say execute and then simply run cscript and then at the bottom once again we have evidence that it loaded my malicious version from the evil path sweet um so comparison right to the other ones we we called out a few issues with the other ones like dll side loading you you need to usually move the executable or bring your own it just means extra footprint good thing with this technique is that you