DLL hijack on operating system ten. My name is path Wardle. It's the only U.S. government agency that listens. The rest don't pay attention. I work as the director of R and D at Synack they do crowd sourced vulnerability. Anyone can sign up to find vulnerabilities on websites, mobile devices, IOT devices. And not a secret secret, their security is really bad. It's a blood bath. We pay a ton of money to researchers. If you want to make money and get paid to hack legally. Synack. Since we're in Vegas it's good to define terms. Implants are persist tent malicious code. Intercepting function code. A Trojan is a malicious program. Injection is about getting code into remote process. And back door is code that provides undetected remote control. Today's talk is three parts. A brief overview of DLL hijacking on Windows. We're going to look at the features and loader and linker that allow us to realize this attack and talk about how to find vulnerable applications to hijack. And finally walk through some hijack examples because there are nuances to this. We're going to end with some attacks and defenses. First, let's talk about DLL hijacking on Windows. The reason we talk about this first is because it's similar to -- hijacking on operating system S. There are real life examples of DLL hijacking that illustrate the gravity of this kind of attack. Some of you are probably familiar with DLL hijacking on Windows. Starts with an application that starts into a DLL instead of a qualified path. This makes it vulnerable. When only a name is provided the Windows loader look in various application directories before the system directory. We have an application that says I have a dependency on (audio blipped) the loader says, okay, you didn't give me a full path. I'm going to look in several directories. I'm going to start with the current one or the applications directory before looking in the system directory. What malware can do is plant malicious DLL in the primary search directory and the loader can be tricked to using the malicious one. -- very useful for malicious adversaries in malware. You can persist without touching the registry. All you have to do is (audio blipped) and it loads. Load time process injection. If a browser is vulnerable to DLL hijacking you plant a malicious DLL and your DLL gets loaded into the context. Used to bypass UAC. There are applications on Windows that are autoUAC, automatically elevated without putting in the password. If these applications are vulnerable to DLL hijack, you can plant a DLL and execute the applications and the DLL is (audio blipped) in the process. Aspects where this can be used for remote infection. If an attacker can -- off web dab share, they can get the DLL loaded from that remote share as well. Here are examples. Persistence. There is a blog written and they talk about unrelated samples of malware they were all named the same in Windows. If you look deeper, explore dot EXE was subject to attack. If you plant that in Windows, every time when explorer starts the malicious DLL gets loaded. (audio blipped) vulnerable to DLL hijacking. Here is malware that was abusing this. It would plant a malicious DLL and start CYS prep [indiscernible] processing. What does DLL hijacking stand today. Microsoft responded and they patched the applications. They set some registry keys that help control the loader so maybe it wouldn't be tricked as much. When I was working on these slides two weeks ago, there was a security advisory released by Microsoft they had to repatch an application because it was vulnerable to this DLL hijack. This bodes well for an attacker if they can find a similar attack. 6 months ago I was reading stack overflow. I do programming at work and this is how I code at work. I see what other people are doing. And I found this quote by Mark B. I owe him a beer. Any DLS is vulnerable to DLL hijacking. I'm going to [indiscernible] on operating system X. Why are attacks on Mac a big deal? This is kind of an obvious statement but Macs are ever where. You look around a security conference, college campuses, R and D centers, everyone uses Mac. When a technology becomes more prevalent, attacks become more valuable and destructive. So the previous terms I defined were funny. These are more serious but equally important. When I say mock -- this is the executable format that apple uses. Windows has PE files, and Linux L files and Macs have (inaudible). Windows has DLLs. Linux is dot SOs and Mac ... Load commands. They are embedded in these binaries (audio blipped) commands to the loader. They do things like specify the memory lay out, the initial execution thread of the main execution state. (audio blipped) loader should load. Since these load commands play such a pivotal role I wanted to talk more in depth. Embedded in the binary and read by the loader. And you can view them with tools like mock OV or O tool. One of the most important load commands for this presentation is the LC load command. This is one for each -- application as a dependency. This is like an entry in the IAT on Windows. I have a dependency, load it into memory. Let's take a closer look at the load command. Starts with a load command header, the command number and size. Then a DILib structure. A name, a full path and versioning information. There is another important load command called the LCID DILib load command. This shares the same format as the LC load command. The reason is it's complimentary. Applications have the LV load DILib command which says there is a dependency. The loader goes and finds the DILib and looks for the (audio blipped) command and make sure they have the same format and they're complementary. So back to DILib hijacking. Let's specify exactly what we're trying to do. We want to be able to plant or drop a malicious DILib and have it matched to an application. Obviously you can achieve this by patching a binary and putting in a new dependency. This breaks the digital signature and it's easy to detect. We're going to say no other modifications to the operating system. No autorun key less files or anything. Just plant the file on the file system. Again we want it independent of the users environment. We're not going to modify any path variables. If we can find an attack on operating system X, dropping a DILib and getting it loaded, it would be powerful and we would be able to abuse it similar to DLL hijacking on Windows (audio blipped) load time process, bypass security and open avenues to facilitate infection. Windows and DLL injection was about all [indiscernible]. When an application starts the loader does a few things. These are similar to what loaders on other operating systems do. They parse the application they're loading. Look for dependencies. Find the dependencies on disk. Load them into memory and link so the application can use this. This is standard loader, linker stuff. Take a closer look you can see what DILib is doing. The first code (audio blipped) in that newly-borne process is DILib under score start. This calls start and then main. This isn't the applications name, it's the loaders name. Name gets -- link. Link calls recursive libraries and step four calls the DILibs and starts the loading process. Step five prerequisite parsing and other analysis and step 6, load phase 6 that loads the DILib into memory and does the linking. That is DILib. Let's find some logic that we can abuse to hijack. We want to look for two scenarios, the first is there code within the loader that doesn't error out if the DILib is not found. Is there code within the loader that looks for DILibs in multiple applications. If in either case the answer is yes, we may be able to hijack. The first scenario, there is instance where the dependent is not found, we can plant a malicious DILib and fulfill the dependency. In the second scenario, if the loader is looking in multiple places for the DILibs to load and the legitimate DILib is not in a primary location it's loading, we may be able to plant or save a malicious DILib and trick the loader into loading it. Let's look for the first case which is there a scenario where it's okay if a DILib is not found. In the recursive load libraries function we see an exception is thrown if is DILib is not found. If an application has a dependency and the dependency is unable to be fulfilled the loader is going to crash. In the catch statement the exception is ignored if some variable named is required and not set. There is an apple comment that says weak libraries are okay (audio blipped) required variable. We see code iterating over the load bands and the LC load DILib and a new load command. If the load command is this weak DILib the variable is set to false. The exception is avoided. If the DILib is not there, no harm done. By using these weak dependencies this is the first scenario. A weak dependency, the loader is going to try to find the DILib, the application is like I would have used it if it was there but if it's not, no problem. A hacker can plant a malicious DILib in that location and the loader will find the malicious DILib and be tricked into using it. That was the first method. Auditing the code was a loop. Loading DILibs from multiple R path locations. An inner loop, a vector of path and trying each path and seeing if it can find the DILib in each path. I have no idea what this was functionally doing but apple explains. There are two parts to these. The first is the DILib. A run path dependent DILib which is a library that doesn't know where it's going to end up on a target system when installed. The second piece is applications that link to these independent DILibs. The application has to have some knowledge to tell the loader where to look. (audio blipped) from an attacker's point of view we can say DILib is going to look for DILib in multiple areas. We're going to build a run path library and create an example application that links against the libraries that we'll use to hijack. It's a normal DILib except you put a special keyboard. You compile the DILib and dump the load commands. A load command that tells or identifies the DILib to the loader. You can see the name which is a path starts with a special keyword. For an application to link or make use of run path dependent DILibs they have to do two things. You drag the local copy and read the create the dependency and then you have to tell the loader where this DILib may end up on the target system when the software is deployed. You specify search paths. When you run the application it's going to generate load commands. First is the dependency. And now there are new load commands, the RC load commands. These contain the list of places that tell the loader where to look for the DILib. Let's dump each load command and show you what I'm talking about. This is the LC DILib load command. This specifies a dependency. I'm dependent on a DILib, go load it. This is standard. The name field starts with @R path. This says as an application I have this dependency. When I was built I didn't know where this DILib was going to end up on the file system by have embedded search paths for you to look for to try to find it. In order to find this DILib, the loader looks for LCR path load commands. One for each directory. So we go back to the loader source code and we can see where these load commands are processed and how the loader interacts with them. (audio blipped) get R path. What this does is extract the run path and puts them all into the vector. Each of those search directories and put them into an array into a vector. Now a list of where to look. In load phase 3 which is a prerequisite loader functions it looks for all dependencies that start with that P path keyword. And now it's going to put in a search directory and see if it's happy, if not it goes to the next directory to look there. There are several pre-recs. We have an application with a dependency on a run path dependent DILib. The loader is going to look in the applications library directory. That's the first LCR path. Then after it doesn't find the DILib there it consults the second RC path manned and look for the DILib there. What an evil adversary can do is plant or place a malicious DILib in that primary search directory and every time the search is started, it will find that DILib first and load the malicious DILib. It will be tricked into using ours. I described two ways to perform DILib hijacking on operating system S. First a weak dependency, the dependency is not there we can plant a malicious DILib. Or if an application contains multiple search directories, the legitimate one is not in the primary directory. We can plant a malicious DILib and it will get loaded automatically. Now it's time to perform hijack. We use the example application. It has a dependency on the run path dependent DILibs. We confirm it's vulnerable. The loader has variables that you can set that tell it to do more logging. We set the DILib print R pass environment. This prints all the information that the loader is going to do. On (audio blipped) search directly and didn't find the DILib there. Went and looked in the second directory and found the DILib there so it's happy. What we're going to try to do is build a DILib and drop it in the primary search directory. Hopefully the loader picks it up. We put an export constructor in the DILib. The reason is when DILibs are loaded they're not executed right away. The application has to trigger the excuse. If you create a custom exporter as soon as the DILib is loaded, it's automatically executed. We plant the malicious DILib in the primary run path search directory and start the directory. Good news, the loader seems to have found it and tried to load. The bad news is it crashes. There is a verbose error message that says what is going on. We look at the source code to see where the error message is from. Within the recursive load libraries method it checks that the version of the DILib that it's about to load matches the version that the application has a dependency on. Makes sense. If an application has a dependency on a DILib and says I need version X. If the DILib that the loader loads is less thanking X, it's going to crash and say I couldn't fulfill the dependency for you. We didn't specify a version, it's going to be set to 0. We can fix this easily. We go back to X codes and set the version information. Recompile and dump the load commands and now the version is 1.0. We have a compatible version number. We take this malicious DILib and copy back to the search directory, and execute the application and it crashes again. Different error message. You don't have the symbols I require. This makes sense. Applications have dependencies on DILibs because they want to use some functionality with the DILib. The way this is linked and glued together is symbols. The loader is like you don't have the symbols the application need. How do we address this issue. We can manually create the symbols nah the application needs but this is problematic. One it's a lot of work. And I'm lazy. The other is it's brittle. Say we're trying to hijack application A, we have to export all the symbols for application A. Then we want to hijack application B, we have to create a whole new set of symbols. It's better if we can point to the (audio blipped) that we're hijacking and say I don't have the symbols that you need but I know someone else that does. We can update the hijacker to point to the correct legitimate doctor. In operating system S you can do this. There are linker flags that you patch and this creates a new load command. Again, this tells the linker I don't have the symbols but this other DILib has the correct symbols. Go get them. Two issues. Both are LD, the compile time linger. When you specify this export dependency the compile time linker goes and gets the names of the legitimate DILib you're exporting to. This name is going to start with the [indiscernible] keyword. When the run time linkers sees this load command it doesn't resolve that at R path keyword. It tries to go to the file system and look for a DILib that starts with at R path which is not going to exist. LD, the compile time linker will not allow you to link against or reexport to another DILib is that DILib is a system DILib under an umbrella framework. We can get around this by linking to a fake DILib. This allows us to compile and we can patch or fix up this reload command so it points to the correct DILib. There is an apple tool to do this. The install name tool. You give it parameters. The existing name or value in the load command. You give it the new value. The full path through the legitimate DILib that we're hijacking and then the path to our own DILib. When you run this it's going to fully update the run LC DILib. That points to the correct DILib that we're hijacking. We take this hijacker DILib and copy back to the primary search directly and execute the application and it finally works. The malicious DILib is loaded and executed. All symbols are reexported to the legitimate DILib so the user doesn't see anything fishy going on. This allows us to achieve cool hacks by planting a malicious DILib. It's unlikely to be patched out. We're using the functionality of the operating system function loader. And unlikely to be detected. The loader is doing the one that is loading the malicious library. We're abusing legitimate techniques. I want to talk about automation. In order to do this DILib hijack you have to have a vulnerable application. You can't just target any application. I wrote a script that scans the running processes or all files on the file system and looks for applications vulnerable to either of the two hijack scenarios described. It found 150 binaries on the box. We can see apple has a whole list. Third party applications like Microsoft have a bunch. All the office products are vulnerable to DLL and hijacking on operating system S. And third party like Google, Dropbox. Hijack any of these applications. Talking more about automation. To successfully hijack an application we draft a DILib with the correct version number and reexported the symbols to the correct DILib. I wrote a script that takes a generic hijacker DILib and configures for the target. For any application you're trying to hijack, it will be fully compatible and the hijack will work. Persistence. This is probably one of the best uses of attack. The goal is to maintain automatic code execution by dropping a DILib. The benefits is no breaking of digital signatures or autorun locations. No new processes. The malicious DILib is loaded into the existing process. The user doesn't see any new malicious processes running. Also it's going to be hosted within a trusted process. This is good because trusted processes are allowed to do more things than untrusted processes and abuses legitimate functionality. That mean it's going to be harder to patch and detect. In my box there is an I cloud photostream agent. Apple daemon that is automatically run when the operating system starts. And it turns out it's vulnerable to a hijack attack. We configure the malicious DILib, copy to the primary run path and any time the box is restarted our malicious DILib will get loaded automatically by the loader. We can use DILib hijacking to obtain persistent -- within the process. There is a number of ways to do process injection. An external monitoring component. And then as soon as the browser comes up and you want to inject code you allocate memory and copy in shell code. This works but it's noisy and complicated and easy to detect. DILib achieves the same thing. Code execution within a target process without any of these downsides. So X code is an attractive code for malware. Malware can use it to infect all employed binaries. Ex-code is the apple IDE, what developers use to develop applications. I thought it would be cool if there was malware watching for a release build and as soon as the developer builds it, the malware can - at the source code inject malicious code so the release binary is infected and it will go out and propagate malware. X code is vulnerable to a [indiscernible]. We can configure a malicious DILib and save to the file system and ever time the X code is started, our malware is automatically loaded. Another use is to bypass security products. The goal is we want to do something that normally would be blocked or not allowed. There are a lot of ways to individually attack personal security but DILib hijacking provides a generic way to bypass all of them. Let's talk specifically about little snitch. It's the de-facto firewall for operating system. I run it on my box. When there is a new outgoing connection, it pops up and asks if I want to trust it. The approach that little snitch takes is it's binary. Trusts known processes and allows users to create blanket rules. On my box it's allowed to create any outgoing connection. It is trusted. This rule makes sense. The problem is DPT chain is vulnerable to a DILib hijack attack. We can plant -- and every time DPT chain is started, [indiscernible] by the user, the malicious DILib gets loaded and executed and now be in the trusted process context of the DPT chain. And the malicious DILib can create an outgoing connection to any network at once. Little snitch will see this and say this is [indiscernible] and I trust it. I'm going to let the connection out. This is how to use DILib hijacking bypass security. We talked about local attacks and these are great per persistent malware. I want to infect remote users. There is this built in security component called gate keeper that gets in the way. We want to bypass this. How does it work? When you download content from the internet it's tagged with a quarantine. And when you run the application, doubleclick on the desktop, gate keeper intercepts the request the first time and makes sure what you're about to do conform PSFTP you can set it to various settings. If you download code from anywhere else gate keeper will pop up and block. It does a decent job of blocking malicious downloads. Users are faked into downloading a flash update or something. If there are man in the middle attacks performed against software gate keeper can detect this because it will have been modified. Gate keeper verifies the downloaded application but only verifies that. External content was not verified. That's okay except if the application loads the external content. This is what we do in three steps, two. First find an apple sign or Mac approved application with an (audio blipped). Create the necessary zip package and inject into a legitimate DILib and build the folder structure necessary to execute. Let's talk about these steps. First find a gate keeper approved application with external relative presence to a hijack able DILib. It has to be external because we can't modify the bundle. Gate keeper will not allow it to execute. It has to be externally relative. We want it within the same zip file. So instruments dot app, we can see that it is verifiable, accepted by gate keeper. Apple signed. You download from the internet and only from the Mac app store, I will allow you to run this application. If we dump it, it has an LCR path that is relative externally to the application bundle. [indiscernible] installed under X code application. At run time it goes into X code shared framework directory and looks for directories there. DMG image or a zip file or inject into a legitimate download. At the top there is instruments dot app. Under the applications directory. There's the external folders that instruments will look for for DILibs to load. If we provide the user with this image, they're like what is this? I'm not going to run this. We can take steps to clean it up. We can hide the files and folders. Set a top level alias. Change the icon or background. We're not modifying the digital signature itself. If you're downloading a flash installer over HTTP and this is what you get, you're probably going to run it. This is how this happens. We have Mac's gate keeper setting. Only allow code from the Mac store and the malicious DILib that should not be able to execute because it's not from the Mac app store and instruments dot app. When the user clicks they get a pop up. The gate keeper pop up for any content. Even if it's signed and validated. The user is going to click okay because they downloaded software they want to run. Even though gate keeper is set to only allow code from the Mac store it will load our malicious DILib. Apple patched this so we're save now. This was problematic until they patched it. This allowed hackers to go back to their tricks and get users to download malicious software. The way most hackers target Mac users is getting people to download malicious software. A website that says there is HD codex you have to install, flash installer or something, or a free copy of Photoshop. Hackers put malicious code in there. Gate keeper would block this. Using this attack, hackers can go back to their same techniques and infect Mac users. Hopefully we're all security conscious professionals here so we're unlikely to download shady content. We do all download software. Since the Mac app store is so constrictive. A lot of us get the software from the company's website. Photoshop, you go to Adobe.COM. It's problematic if it's distributed over HTTP. An adversary with network level access can inject malicious code and gate keeper can no longer detect if they're tampered with. 2015, how much software is distributed over HTTP. About two-thirds of the software that I installed on my computer was distributed over HTTP. All right, you are a malware analysis security guy and you're downloading a lot of stuff. Let me look at security tools. These guys are supposed to be the shining example of how to do it right. When I did this research earlier this year, every single third party thing I downloaded was downloaded over HTTP. Any adversary could have injected malicious content. And gate keeper would not have caught it. I wanted to put everything together to test the third party products. I put in a piece of code that was distributed as a malicious download. When executed it persists as a DILib hijack and Ex-fill trait data on I drive and download and execute commands. Not the most sophisticated. It persists, downloads and executes. I wanted to test this against these third party securities. The test I thought was simple. Download the security product, update it so it had the latest signatures and run the image to see if the antivirus product or firewall detected the attack. I skewed it. If they detected any component of the attack that would win for the antivirus product and loss for the malware. If they detected the gate keeper, the persistence, the downloaded commands, any of those detections is a win for the antivirus company. Not too surprising, none of them detected any of this. This reexposed the ineptitude of an entire industry that charges us for their products. I wanted to talk about suggested fixes. Since DILib hijacking is legitimate, it's unlikely to be patched. I don't know how to protect against this. Gate keeper I reported this to apple (audio blipped) the way apple patches things is narrow minded. A vulnerable piece of code, they patch the code path to the code. I'm giving a talk tomorrow about apples patch (audio blipped) with this gate keeper patch, there are other avenues to coerce gate keeper to run code. Hopefully I talked to apple about this and they fix it. So it's improving slowly. If software is downloaded over HTTP, let the company know. Why are you distributing software to me over HTTP. I briefly want to talk about El captain. I was hoping DILib would be addressed. There are new security mitigations according to apple markets, DILib hijacking is alive and well. I was able to plant a malicious unsigned DILib and every time the operating system was started the DILib was loaded. Apple says that code injection into system binaries is no longer permitted. But using DILib we can still do it. So I don't know. I don't know if they'll fix it. It is what it is. It looks like this attack will be around for a while. (audio blipped) DHS, DILib hijack scanner is running processes over the entire file system and it will tell you if there are vulnerable applications. There is probably going to be a lot of vulnerable applications. That doesn't mean your hacked just means if malware were to get into your system, it can load the DILib by the operating system. It will show you hijacked application. They appear to be hijacked there. Are some false positives. I have yet to see any malware abusing this technique. This will detect all the attacks I said earlier. If someone (audio blipped) DILib to hijack a legitimate one this tool will detect that. This tool is available for free at objective C.com. There is a nice collection of malware if you want to download and play with recent samples that I find. It's hard to get the AD companies to share malware with me. I spent some time getting this collection together. There are free tools that I run on my personal computer. I love my Mac but it's easy to hack. I wanted to write some tools to protect it and make them available for free. The first tool is knock knock. This is autoruns for operating system X. Task explorer, this is internal tools for Windows. Shows you all the running tasks, if they're signed, virus total integration and loaded DILibs. It shows any of these injected DILibs. Network connections and open files and block block. It will monitor the file system and if malware tries to install itself, it will detect it. We talked about really new class of attack that affects operating system S. Affects everyone, apple, third party, and abuses legitimate functionally and it's stealthy. We can do all sort of cool things. Persist, we can gain low time process injection. Bypass security products and facilitate remote infections. Until apple fixes this which they - I would recommend scanning your system, make sure you're not hijacks. I doubt you are but it can't hurt. Only download software over (inaudible) and if it's over HTTP, send them a nasty email. I don't think the antivirus programs are worth the money. They don't detect anything. That's a wrap. We have two minutes for Q and A. Slides are available for download. I wrote a white paper about this. If you want to read about the details. And here is a website for free security tools. That is it. Any questions? Some of the UI ones not. There are open source versions of knock knock and the DILib scanner. Those are on sin knacks GitHub. You can download them and play with them as well. Thank you. Gentleman in blue. The question is how does this impact I operating system. I believe the code is kind of vulnerable because they share a lot of the same loader code. Because I operating system does not allow you to run unsaved code, that blocks this attack. Even if an application is vulnerable and you planted a malicious DILib the loader would ignore it because it's not signed by apple. Any other questions? Yes. I think one thing, the question is can you require the DILibs to be signed or something? Apple, if I'm an apple signed process I should only load apple signed processes. A problem that you can prevent this is don't allow unsigned DILibs to be loaded in. It's not that hard to get a developer ID and get apple to sign it but it makes the bar higher. I'm about to get kicked off the stage. Thank you again. If you have questions, I would love to chat.