 Alright, so let's talk about DLL hijacking on OS 10. My name is Patrick Wardle. I've worked at a bunch of acronym places including the NSA which I always have to joke is the only U.S. government agency that I actually think listens. You know, the rest don't really pay that much attention. So I work as the director of R&D at SINAC. SINAC does crowd sourced vulnerability discovery with vetted security researchers. Basically anyone can sign up to find vulnerabilities in our customers. Websites, mobile apps, network devices, IOT devices. And I'll let you in on a little not-so-secret secret because I don't see any of our customers here. Their security is really bad. So it's a bloodbath. We always pay out a ton of bugs, a ton of money to our researcher. So if you guys want to make some extra money, get paid to hack legally, check out SINAC.com. Alright, so before diving in, since we are in Vegas I think it's good to concisely define any possibly ambiguous terms. So in the context of this presentation I'm talking about implants, I'm talking about persistent malicious code. I'm talking about hooking, I'm talking about intercepting function calls, installing a hook or a detour. Atrogen is a malicious program, something that pretends to be legitimate. Injection is all about getting code into a remote process. And then finally a back door is code that provides undetected remote control of a computer. Alright, so today's talk can be divided into pretty much three parts. We're going to start with a brief overview of DLL hijacking on Windows. The core of the talk is then going to be talking about dilib hijacking on OSX. We're going to look at the features in the loader and linker that allow us to realize this attack. We're then going to talk about how to find vulnerable applications that we can hijack. And then finally we're going to actually walk through some hijack examples because there's some nuances to getting this all work. And then finally we're going to end with some attacks and defenses. So first let's briefly talk about DLL hijacking on Windows. The reason we talk about this first is because it's conceptually very similar to dilib hijacking on OSX. It's also well understood. And finally there's real life examples we can look at of DLL hijacking that illustrate the gravity of this kind of attack. So most of you are probably familiar with DLL hijacking on Windows. Basically starts with an application that specifies just a name to a DLL instead of a fully qualified path. This makes the application vulnerable. Why? Well it turns out when only a name is provided, the Windows loader will look in various application directories before looking in the system directory. So this is conceptually how it all works. We have an application that says, hey, I have a dependency on blah dot DLL. The loader says, okay, you didn't give me a full path, so I'm going to look in several directories for this DLL. I'm going to start with the current working directory or the applications directory. Before then going and looking in the system directory. So what a malicious adversary or malware can do is plant a malicious DLL in that primary search directory and then whenever that application is started the loader will be tricked or coerced into using the malicious DLL. Now there was a lot of hype around DLL hijacking, a lot of media when it was first publicly discovered in 2010. And this is because it was very useful for malicious adversaries in malware. So using DLL hijacking you can do a variety of things. You could persist without touching the registry. All you would have to do is plant a malicious DLL and it would get loaded. You could also do load time process injection. So if an application say a browser was vulnerable to DLL hijacking, you could just plant a malicious DLL and every time the browser would be started your DLL will get loaded into the context of the browser. It was also used to bypass UAC. There's some applications on windows that are auto UAC which means when they're executed they are automatically elevated without having to put in a username and password. If these applications are vulnerable to a DLL hijack, again an attacker can plant a malicious DLL and then execute these applications and their DLL will also be auto elevated into the context of that process. And then finally there were some aspects where this could be used for remote infection where if an attacker could get a user to load something off a remote webdab share they could also get their malicious DLL loaded from that remote share as well. So here's some brief real life examples of DLL hijacking. The first is persistence. It was a blog written by Mandiant. They talked about all these unrelated samples of malware they found that were all called FXSST.DLL. They were all in C slash windows. They looked a little deeper into this and they found out that explore.exe was vulnerable to a DLL hijack tack. Basically if you plant a DLL with that name in C windows every time explorer starts which is automatically when a computer reboots your malicious DLL will get loaded. So this is a really great way to persist without having to modify the registry. The second example is ProVesq. sysprep.exe is one of those auto UAC applications and it was vulnerable to a DLL hijacking. So here's some source code from some malware that actually was abusing this to bypass UAC. It would plant a malicious DLL and then programmatically start sysprep.exe which would load the attacker's DLL into its auto UAC process. So where does DLL hijacking stand today? Well, Microsoft fairly rapidly responded. They patched a lot of their vulnerable applications by specifying the fully qualified path instead of the name. And they also set some registry keys that would help control the loader so it maybe wouldn't be coerced or tricked as much. I thought it was pretty much done and gone but when I was working on these slides about two weeks ago there was a security advisory released by Microsoft that they had to repatch one of their applications because it was still vulnerable to this DLL hijacking attack. So this shows the longevity and bodes well for an attacker if we can find a similar attack on OS X. So about six months ago I was reading Stack Overflow because I do some programming at work and this is how I code. I just go to Stack Overflow and see what other people do. And I found this quote by this guy named Mark B. So wherever Mark B is, whoever he is, I totally owe him a beer because he kind of piqued my interest and said that any OS that does dynamic library loading is theoretically vulnerable to DLL hijacking. So today I want to talk about dilip hijacking on OS X. Now first you might be thinking why are attacks on Mac, you know, a big deal? Well, this is kind of an obvious statement but Macs are pretty much everywhere. You look around a security conference, college campuses, R and D centers, board meetings, you know, everyone uses Macs. And of course we all know anytime a technology becomes more prevalent attacks become more valuable and more destructive. All right, so the previous terms I defined were kind of funny. These ones are a little more serious but equally important. So when I'm talking about Mock-O, this is the executable format that Apple uses. So Windows has PE files, Linux has L files, Macs have Mock-O. Dilibs are simply dynamic shared libraries. Again, Windows has DLLs, Linux has .sos, Macs have Dilibs. And then finally load commands. Load commands are embedded in these Mock-O binaries and as their name suggests they are commands to the loader. So they do things like specify the memory layout, the initial execution state of the main thread and then for the context of this presentation it's very important because they specify dependencies on Dilibs that the loader should load. Now since these load commands play such a pivotal role I wanted to talk about them a little more in depth. So as I mentioned they're embedded within the binary and they're read by the loader when the loader is loading the binary into memory. And you can view them with tools such as Mock-O view or O tool. One of the most important load commands for this presentation is the LC load Dilib load command. Basically there's one for each Dilib that an application has a dependency for. So this is kind of like an entry in the IAT on Windows. Basically it tells the loader, hey I have a dependency, please go find that Dilib and load it into memory. So let's take a closer look at this Dilib, this load command. So it starts with the standard load command header which just has the command number and the command size because it can be variable length and then has a Dilib structure. This Dilib structure has a name which is usually a full path and then some versioning information. Now there's another important load command called the LC ID Dilib load command. And this actually shares the exact same format as the LC load Dilib load command. And the reason why is it's complimentary. So applications have the LC load Dilib load command which tells the loader they have a dependency and what the loader does is it goes and finds that Dilib and then in the Dilib it looks for the Dilib's LC ID load command and makes sure they just match. So that's why they have the same format. They're basically complimentary. All right 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 then have it be automatically loaded by a vulnerable application. Now let's put some constraints on this. So obviously you could achieve this by patching a binary, putting in a new dependency, but this is going to break the digital signature, makes it pretty easy to detect. We also are going to say no other modifications to the operating system. So no modification of auto run P list files, anything like this. Again just plant a file on the file system. That's all we're allowed to do. Again we also want it to be independent or global of the user's environment. So we're not going to modify any path variables or environment variables. If we could find such an attack on OSX that is simply dropping a Dilib and getting it loaded by vulnerable applications it would be quite powerful. And we'd be able to abuse it for attacks that were similar to DLL hijacking on Windows. So we could gain persistence, load time process injection, bypass security products and maybe even open some avenues to facilitate remote infection. So on Windows DLL hijacking was all about abusing logic in the loader. So let's start by looking at OSX's dynamic loader and linker which is called DYLD. Basically when an application starts the loader does a few things and these are similar to what loaders on other operating systems do. They're going to parse the application they're loading, look for the dependencies, go and find those dependencies on disk, load them into memory and then link so that the application can use us. Again this is pretty standard loader linker stuff. We take a little bit of a closer look we can see exactly what DYLD is doing. So when a new process has started the first code that executes in user mode in that newly born process is DYLD underscore start. This is just a little assembly stub routine that then calls start and then main. Now this isn't the applications main this is the loader's main. Main simply gets a path to the executable and calls link. Step three link calls recursive load libraries. Step four actually starts to parse the dependent dilibs and begins to call load library on each to start the loading process. Step five there's these various prerequisite functions that are called that do some parsing and some other analysis. And then finally in step six it calls load phase six which actually loads the dilib into memory and does all the linking. So that's a brief overview of DYLD. So let's talk about finding some logic that we can abuse to perform a dilib hijack attack. So basically we want to look for two scenarios. The first scenario we want to look for is their code within the loader that doesn't error out if a dilib is not found. And then the second scenario we want to look for is their code again within the loader that looks for dilibs in multiple locations. In either case if the answer is yes we may be able to hijack via a dilib hijack. Why? Well think about the first scenario. There's an instance where an application has a dependency and that dependency is not found. We may be able to plant a malicious dilib in that location and fulfill the dependency. Similarly in the second scenario if the loader is looking in multiple places for the dilibs to load and the legitimate dilib is not in one of the primary locations it's loading. Again we may be able to plant or save a malicious dilib in that primary search location and then trick the loader into loading that. So let's start by looking for the first case which is is there a scenario which it's okay if a dilib is not found. So in the recursive load libraries function we can see an exception is thrown if a dilib is not found. This is what you expect. If an application has a dependency and that dependency is unable to be fulfilled the loader is kind of throw up its hands and crash. However we can see in the catch statement that the exception is ignored if some variable that's named required is not set. And there's an apple comment that says weak libraries are okay. So we have to go to the do get dependent libraries method to see what sets this required variable. We can see some code that's iterating over various load commands and we can see logic for the LC load dilib which we talked about. And there's a new dilib, a new load command called LC load weak dilib. If the load command is this new LC load weak dilib that required variable is set to false which is good. That means the exception is going to be avoided. Pretty much it says if that dilib is not there no harm done. So by abusing these weak dependencies this is our first dilib hijack scenario. So here's the normal scenario you have an application that has a weak dependency. The loader is going to go and try to find that dilib but if that dilib is not there the application is like okay I would have used it if it was there but if it's not no problem. So what a hacker can do is obviously plant a malicious dilib in that location and now whenever that application is started the loader will find the malicious dilib and be tricked into using it. Now that's the first method I wanted to keep looking to see if I could find the second method because the first one wasn't as common as I would have thought. So auditing the code again uncovered a loop. Basically it was trying to load dilibs for multiple R path locations. We can basically see there's an inner loop which is a vector of paths and it's trying each of these paths and seeing if it can find the dilib in each of these paths. So I had no idea what functionally this was doing but luckily Apple explains. So there's two parts to these R path, run path dependent dilibs. The first is the actual dilib which is called a run path dependent dilib. A run path dependent dilib is simply a library that doesn't know where it's going to end up on a target system when it's installed. The second piece are applications that link against these run path dependent dilibs. Since the dilibs don't know where they're going to end up the application has to have some knowledge so that it can tell the loader where to look. So this is exactly what happens. Now I guess this makes it easier to deploy software but from an attacker's point of view we can see this and say oh, DYLD is basically going to look for dilibs in multiple locations. This is promising. So I briefly want to walk through an example where we're going to build a run path dependent library and then we're going to create an example application that links against these libraries that then we'll use to hijack. So it's pretty easy to make a run path dependent library. It's a normal dilib except in the install directory you put this special keyword that's at our path. If you then compile this dilib and dump its load commands you can see the LCID dilib which again is the load command that tells or identifies the dilib to the loader. You can see that its name which is a path actually starts with this special keyword at our path. Now for an application to link or make use of such run path dependent dilibs they've got to do two things. So first in Xcode you just drag the local copy of your run path dependent library to create the dependency and then you have to specify, you have to tell the loader where this dilib may end up on the target system when the software is deployed. So you do this by specifying some search paths in the run path search paths in Xcode. Again when we compile the application this is going to generate some load commands. First there's going to be the standard LC load dilib load command because we have a dependency but now there's these new load commands which are the LC R path load commands and these contain the list of places that tell the loader where to look for the dilibs. So let's dump each of these load commands to show you exactly what I'm talking about. So this is first the LC load dilib load command. Again this is in the application and it simply specifies a dependency. It tells the loader hey I'm dependent on some dilib please go load that. Now this is standard except if you look at the name field you can see that it starts with R path. Again this tells DYLD hey as an application I have this dependency when I was built I didn't know exactly where this dilib was going to end up on the file system but I have some embedded search paths that I'd like you to go look for to find this dilib. So in order to find this dilib the loader will then look for these LC R path load commands. There's going to be one for each directory where the dilib may end up. So we go back to the loader source code we can actually see where these load commands are processed and how the loader interacts with them. So in the recursive load libraries method we can see it calls this function called get R paths. What this does is extract the run path search paths and puts them all into a vector. So it's going to get each of those search directories and just put them into an array into a vector. Now it has a list of where to look. So back in load phase three which is one of those prerequisite loader functions what it's going to do is it's going to look for all dependencies that start with that at R path keyword. Then what it's going to do is it's going to swap out that at R path keyword and put in one of the search directories, check if the dilib is there, if it is it's happy, if not it's going to iterate to the next search directory to look for the dilib there. So here's hijacked number two. Now there's several prereqs but it turns out they're pretty common. So we have an application that has a dependency on a run path dependent dilib. We can see the loader is first going to look in the applications library directory because that's first LCR path. Then after it doesn't find the dilib there it's going to consult the second LCR path load command and go there and look for the dilib there which it then finds the legitimate dilib. So what an evil adversary, a malware, a local attacker can do is plant or place a malicious dilib in that primary run path search directory and then every time the application is started the loader will find that malicious dilib first and because it's a first match wins it will load that malicious dilib. It will be tricked into using our malicious one instead. Alright so briefly summarize I've described two ways to perform dilib hijacking on OSX. First if an application has a weak dependency that that dependency is not there we can plant a malicious dilib or if an application contains multiple run path search directories and the run path dependent library the legitimate one is not in one of the primary directories again we can plant a malicious dilib in the initial directory and it will get loaded automatically. Alright so now it's time to actually perform hijack we're going to use the example application we just built that has this dependency on these run path dependent dilibs. So the first thing we should do is confirm that it's actually vulnerable. So the loader has various environment variables that you can set that basically tell it to do more logging tell you what exactly it's doing. So we set the DYLD print our pass environment variable this will print all the information that the loader is trying to do as it tries to find these dilibs. So we can see in on the slide at first try to look in the initial search directory and didn't find the dilib there. So then it went and looked in the second directory and it found the dilib there so it's all happy. Alright so what we're going to try to do is simply build a dilib and drop it in that primary search directory. We'll cross our fingers and hopefully the loader picks it up. Now one thing we are going to do is we're going to put an export constructor in our dilib. Now the reason we do this is normally when dilibs are loaded they're not executed right away the application has to call into some way to trigger execution. But if you create a custom exporter as soon as your dilib is loaded it will be automatically executed in a deterministic manner. So we plant our malicious dilib in the primary run path search directory we start the application and good news bad news. Good news the loader seems to have found it and try to load it. Bad news the app horribly crashes. Luckily though there's a pretty verbose error message that kind of says exactly what's going on. So we go look at the source code to see where this error message is thrown. Basically we can see that within the recursive load libraries method it's going to check that the version of the dilib that it's about to load matches the version that the application has a dependency on. This makes sense. If an application say has a dependency on a dilib and says hey I need at least version X if the dilib that the loader loads is less than version X the loader is going to crash and basically say hey I couldn't fulfill the dependency for you. Now since we didn't specify a version of the dilib we're going to be set to zero and if we dump with the application once we can see it once version 1.0. So we can fix this pretty easily. We just go back to X code and there's actually fields where you set the version information. We recompile our dilib and again dump its load commands. We can now see the version is 1.0. So now we have a compatible version number. We take this newly compiled malicious dilib again copy it back to the primary run path search directory execute the application again. Crash is again. Different error messages though it says hey you don't have the symbols I require. Again this makes total sense. Applications have dependencies on dilibs because they want to use some functionality within the dilib and the way this is all linked in and glued together is via symbols. In our hijacker dilib that we just copied in we didn't export any symbols. So again the loader is going to be like GTFO you don't have the symbols the application needs. So we got to figure out how to address the symbol issue. So we could manually create the symbols that the application needs but this is problematic for two ways. One is a lot of work and I'm kind of lazy. The other is that it's kind of brittle. We would have to say we're trying to hijack application A. We would have to export all the symbols for application A. Then we wanted to hijack application B. We would have to create a whole new set of symbols. So ideally it would be way better if in our malicious hijacker dilib we could just point to the correct legitimate dilib that we're hijacking. Turns out that in OSX you can actually do this. There's some linker flags you basically patch. Pass and this creates a new load command. The LC re-export dilib load command. Again this tells the linker I don't have the symbols but this guy or girl this other dilib has the correct symbol so go get them from there. There's two issues though. That both have the same symbols. One of them has the same symbols. There's two issues though. That both deal with LD which is the compile time linker. The first is when you specify this export dependency. The compile time linker goes and gets the name of legitimate dilib that you're re-exporting to. Since this is a run path dependent dilib its name is going to start with this at our path keyword. Now this is only a problem because when the run time linker sees this LC re-export dilib load command it doesn't actually resolve that at our path keyword. It doesn't treat it as special. So it just tries to go to the file system and look for a dilib that starts with at our path which obviously is not going to exist. The other problem is LD again the compile time linker will not allow you to link against or re-export to another dilib if that dilib is a system dilib under an umbrella framework which a lot of the one dilibs that we want to hijack are. So we can get around against a fake dilib. This will allow us to compile and then we can patch or fix up this LC re-export dilib load command so that it points to the correct dilib. Turns out there's an Apple tool to do this. It's the install name tool and basically you give it a few parameters. You give it the existing name or value in the LC re-export dilib load command. You give it the new value which again this is the full path to the legitimate dilib that we're looking for. And then when we run this we can see in the slide it's going to fully update the LC re-export dilib so that it'll point to the correct dilib that we are hijacking which contains all the symbols that the application needs. So we take this built hijacker dilib copy it again back into the primary search directory, execute the application and it finally works. Basically our malicious dilib is automatically loaded and executed. All symbols are re-exported to the correct dilib so that the application runs and the user doesn't see anything fishy going on. So now let's talk about some attacks and some defense. The attacks we're going to highlight in my opinion are pretty damaging and allow us to achieve all these cool hacks and malicious activities by simply planting a malicious dilib to the file system. It's all we're doing. We're not modifying anything else. Also it's unlikely to be patched out because we're abusing legitimate techniques so that's hard for security products to detect and block. So first I want to talk about automation. So in order to do this dilib hijack attack you have to have a vulnerable application. You can't indiscriminately just target any application. So I wrote a little script that basically scans the either your running processes or all files on the file system and looks for applications that you can use to detect and block. So I'm going to talk about automation and all the other files on the file system and looks for applications that are vulnerable to either of the two hijack scenarios we described. And we can see that it found about 150 binaries on my box. So that's good. There's a lot of targets we can go after. Now I can't list them all but these are some of the ones, maybe some of the more well known ones. We can see Apple has a whole list. Third party applications like Microsoft have a whole bunch. This is a little funny because all of them have a whole bunch of different types of applications. So I'm going to go ahead and talk a little bit more about automation and then a lot of third party ones like Google, Adobe, PGB tools, Dropbox. We can hijack any of these applications. Also recall talking a little bit more about automation that in order to successfully hijack an application we had to craft a dilib that had the correct version number and also re-exported the symbols to hijacker dilib and configures it for the target you're about to hit. So for any application you're trying to hijack you just run the script and it'll configure the hijacker dilib so it's fully compatible so that your hijack will work. Alright, so I want to talk about persistence first. This is probably one of the best uses of attack. Again our goal is to gain automatic and persistent code execution by simply dropping a dilib to disk. All we're going to do. The benefits of this, again, there's no binary or OS modifications. We're not modifying any P lists or auto run locations that might be monitor. There's also going to be no new processes. Our dilib, our malicious dilib is going to get loaded into existing process. So the user's not going to see any new malicious processes running if they do a PS or check out activity monitor. Also it's going to be hosted within a trusted process. This is good because a lot of times trusted processes are allowed to do more things than untrusted processes. Again it abuses legitimate functionality. Any time you have an attack that abuses a legitimate functionality, it means it's probably going to be harder to patch and detect. Alright, so in my box there is an application called the iCloud photo stream agent. It's Apple daemon that gets automatically run whenever the operating system starts. So anytime I reboot my computer and it turns out it's vulnerable to a dilib hijack attack. So what we can do is configure our malicious dilib so it's compatible with iCloud photo stream agents dilibs. Copy it to the primary run path search directory and now anytime the box is restarted our malicious dilib will get loaded and executed automatically by the loader. So this is really stealthy persistence. We can also use dilib hijacking to gain persistent code execution within a process anytime it's starting. Now there's a number of ways to do process injection. Normally you have an external monitoring component that's waiting for your target process. For example the user's browser and then that browser comes up and you want to inject code into it. You allocate some memory, you copy in some shell code, you spawn a new thread. This works but it's kind of noisy and a little bit complicated and easy to detect. Dilib hijacking can achieve the same kind of thing, code execution within a target process without any of these downsides. So Xcode is an attractive target for malware because I think malware could use it to infect all deployed binaries. Kind of as a propagation vector. So Xcode is the Apple IDE. It's what developers use to build applications. I thought it'd be really cool if there is malware that's running within the context of Xcode's process that's basically watching for a release build and as soon as the developer builds that release build the malware could either subvert the source code or actually at the compiler level inject some malicious code so now the release binary is infected and as it goes out it'll propagate malware. So it turns out that Xcode is vulnerable to a Dilib hijack attack. So again we can customize, configure a malicious Dilib, simply save it to the file system. That's all we have to do. Now every time Xcode is started our malicious Dilib will get automatically loaded by the loader into Xcode's process space. If you can't trust the compiler you should pretty much just go home. Another use of Dilib hijacking is to bypass security products. Again the goal here is we want to do something that normally would be blocked by this allowed. There are a lot of ways to maybe individually attack personal security products but Dilib hijacking provides kind of a nice generic way to bypass pretty much all of them. So let's talk specifically about Little Snitch. Little Snitch is the de facto firewall for OSX. I run it on my box and what it does is anytime there's a new outgoing untrusted connection it pops up and says hey do you want to trust this connection from process XYZ. It's kind of binary. It trusts known processes and also allows users to create blanket rules. So on my box GPG Keychain is allowed to create any outgoing connection. This makes sense. GPG Keychain is trusted, it's signed, it needs to talk to various key servers, update itself so this rule makes sense. The problem is GPG Keychain is vulnerable to a Dilib hijack attack. So what this means is we can plant a malicious Dilib and then every time GPG Keychain is started either in the background by an attacker or by the user the malicious Dilib will get automatically loaded and execute and now be in the trusted process context of GPG Keychain. And then the malicious Dilib can create an outgoing connection to any network endpoint at once. It's command and control server you know anywhere else. Little Snitch will see this but it says hey this is GPG Keychain, I trust GPG Keychain I'm going to let the connection out. So this is again how we can use security products. Now so far we've talked about local attacks and these are great for persistent malware but I wanted to take this a little bit farther I want to be able to infect remote users but there is this built-in security component of OSX called Gatekeeper that keeps getting in the way this is something we want to bypass. So how does Gatekeeper work? Basically every time you download content from the internet this content gets tagged with a quarantine attribute and then when you go to run that application you know double-click it on your desktop Gatekeeper will first intercept this request the first time and make sure that the application you're about to run conforms to the system settings. So you can see on the slide you can set Gatekeeper to various settings the highest being only allow code from the Mac App Store. This means if you download code from anywhere else and try to run it Gatekeeper will pop up and block. Gatekeeper actually does a decent job blocking malicious downloads it's really not a flash update so Gatekeeper will block this if it's unsigned also if there are men in the middle attacks that are being performed against software Gatekeeper can detect and block this because the digital signature will obviously have been modified so Gatekeeper does a great job verifying the downloaded application but it only verifies that external content was not verified which is okay except if the application loads that external content so this is what we're going to do in three steps. I guess we only need two. First we're going to find an Apple signed or Mac App Store approved application that contains an external relative reference to a hijackable dial up. We're then going to create the necessary zip package DMG package installer or inject into a legitimate dial up and build the folder structure necessary to execute this. So let's talk about these steps one by one. So first we need to find a Gatekeeper approved application and external relative reference to a hijackable dial up. It's got to be external because we can't modify the application bundle. Gatekeeper is verifying that. If you touch that at all it's going to break it and Gatekeeper will not allow it to execute. However the content has to be externally relative because we want to be able to put it within the same zip file within the same DMG image. So instruments.app fits the bill. We can see that it is verifiable accepted by Gatekeeper. It's an Apple signed binary gatekeeper like even if you downloaded from the internet and I have only allowed from the Mac App Store I will allow you to run this application. And if we dump it's load commands we can see it has an LCR path that's relative externally to the application bundle. This is because instrument expects to be installed under Xcode.app application. So at run time it kind of goes up into Xcode's shared framework directory and looks for shared dial ups there. But we can abuse this. So now let's create a DMG image. We can use this file or inject this into a legitimate download if it's over HTTP. So at the top you can see there's instruments.app. It's under the application's directory. And then there's the external folders that instruments.app will look for for dial ups to load. Now if we provide the user with this DMG image they're going to be like what is this? Where do I click? I mean I'm not going to run this. So we can take some steps to clean this all up. We can hide these files and folders. We can change the icon. We can change the background. Again we can modify all of this because we're not modifying the digital signature of instruments.app itself. So if you're downloading a flash installer, a legit flash installer over HTTP and this is what you get, you're probably going to run it. So this is how this all happens. So again we have max gatekeeper settings. We say only allow code from the Mac App Store. And then we have this malicious DMG that has dialip which should not be able to execute because it's not from the Mac App Store. And then instrument.app. So when the user clicks it they'll get a standard pop up. This is the standard gatekeeper pop up you get for any content you download from the internet. Even if it's signed, validated, you're just going to be like this is from the internet. The user is probably going to click okay because they've just downloaded some software that they want to run. And if they do, Apple actually patched this so we're safe now. Gave me my first CVE which I'm kind of stoked about. But this was problematic until they patched it because this allowed hackers to kind of go back to their old tricks and get users to download malicious software and infect themselves. So the way most hackers, you know non-nation state people target Mac users is by getting people to download malicious software. So you go to a website. It tells you there's some HD code installed. You have to download some flash installer stuff like that. Or you go to Pirate Bay and you want a free copy of Photoshop. Hackers would put malicious code in there and infect the users in that way. Gatekeeper would block this because those were unsigned malicious binaries. But now using this attack hackers could go back to their same techniques and infect Mac users. Now hopefully we're all security conscious professionals here. So we're unlikely to be downloading this software. Hopefully. However, we do all download software. And since the Mac apps were so constrictive, a lot of us go get the software from the company's website. So if you want to download Photoshop, you probably go to adobe.com. Microsoft Word, you go to microsoft.com. And this is problematic if this software is distributed over HTTP because what this means is now a nation state adversary or an adversary that has network level access can inject malicious code into your computer. So this is a problem that the gatekeeper will no longer detect that they have been tampered with. Now you might be thinking, 2015, how much software is really distributed over HTTP? So when I was doing this research earlier this year, I looked at my doc and about two thirds of the software that I installed on my computer had been distributed to me over HTTP. Now you might be thinking, all right Patrick, you are a malware developer. So I said, all right fair enough, let me look at security tools, firewalls, antivirus products. These guys are supposed to be the shiny example of how to do things right. Well, it turns out, again when I did this research earlier this year, every single third party security product that I downloaded was downloaded over HTTP. So again this means any network level adversary could have easily intercepted this download, injected malicious content and now put everything together to kind of test these third party security products. So I built a proof of concept piece of malicious code that was distributed as a malicious DMGers at file or it could be injected to a legitimate download if it was over HTTP. When executed it would persist via a dialy of hijack. It would then exfiltrate some data to a command and control server on iDrive and then download and execute some commands. Again this isn't the most sophisticated piece of malware what most malware today tries to do. Persist, exfilt, download and execute. Also you don't need a root to install this. So now I wanted to test this against these third party security tools and the test I thought was simple but realistic would download the security product over HTTP, update it so it had the latest signatures and then I would run my downloaded .dmg image to see if the antivirus product or the firewall detected the attack. And I skewed the test towards the third party security products by saying that any component of the attack that was a win for the antivirus product or the firewall a loss for the malware. So if they detected the gatekeeper bypass they detected the persistence, they detected the exfiltration of data the download the execute of commands any of those detections would be a win for the antivirus company. Now probably not too surprising to you guys none of them detected any of this. So again this really just kind of re-exposes the in my opinion the ineptitude of an entire industry that unfortunately doesn't have those for their products. All right so pretty much things are kind of broken so I wanted to briefly talk about some suggested fixes. First since dilib hijacking is legitimate it's unlikely to be patched so I don't really know how to protect against this. Gatekeeper I reported this to Apple they patched this which was great but the way Apple patches things is very narrow minded so if there's a vulnerable piece of code they'll generally just patch like to that vulnerable code. So you know I'm giving a talk actually tomorrow about a priv escalation and Apple's patch and how I was able to bypass the patch. Again with this gatekeeper patch there's other avenues to still coerce gatekeeper to run unsigned code. Demonstrated this at Black Hat a few days ago even on El Capitan. So hopefully I've talked to Apple about this hopefully they fix this as well so it's improving slowly. And then also if software is downloaded over HTTP let the company know like write them be like are you distributing software to me over HTTP it's 2015 right get your act together. So I briefly want to talk about OSX El Capitan I was hoping that dilib hijacking would be addressed. Unfortunately though even though there's all these new security mitigations well at least according to Apple marketing dilib hijacking is alive and well. So what I did was I scanned the system I found some vulnerable applications and I was able to plant a malicious unsigned dilib and now every time the marketing system was started the malicious dilib was still loaded. Apple specifically says that code injection into system binaries is no longer permitted. But using dilib hijacking we can still get malicious unsigned code into vulnerable system applications. So I don't know I don't know if I'll fix this but I guess that is what it is. So it looks like this attack unfortunately will be around for a while. So I decided to release a tool that can at least help us locally. So DHS dilib hijack scanner basically will scan your running processes or your entire file system and it will tell you two things. It will tell you if there's any vulnerable applications. Now there's probably going to be a lot of vulnerable applications. This doesn't mean you're hacked or hijacked this means if malware were to infect your system it could plant a malicious dilib and only have to do that and then it could get code execution or get that dilib loaded automatically by the operating system. It will also show you hijacked applications. These are some false positives so if you find this don't freak out too much I've yet to see any malware abusing this technique. But this will detect all the attacks I talked earlier where if someone does plant a malicious dilib to hijack a legitimate one this tool will detect that and show you. This tool is available for free at ObjectiveC.com. That's my free personal OSX security website. There's a nice collection of Mac malware if you guys want to download and play with some recent samples. I find it kind of hard to get the AD companies to share malware with me. So I spent a lot of time getting this collection together so you can download. There's also some free tools that I run on my personal computer. I love my Mac but in my opinion it's really easy to hack. So I kind of basically just wanted to write some tools to protect it and then make them available for free. So the first tool is Knock Knock. This is simply auto runs for OSX. It'll show you all software that's automatically persisting. Task process explorer, the assist internal tools for Windows, shows you all the running tasks. If they're signed, it has virus total integration, allows you to see loaded dilibs so it would show any of these injected or hijacked dilibs. Network connections, open files. And then finally Block Block. Block Block is simply a firewall for persistent auto run locations. So it'll monitor the file system and if malware tries to persist or install itself it'll detect this. So wrapping this all up, so we've talked about a relatively new class of attack that affects OSX. Pretty much affects every button. It affects Apple applications. It affects third party utilities. And it abuses legitimate functionality and is fairly stealthy. And using this attack we can do all sorts of cool things. We can persist really stealthily. We can gain low time process injection even on El Capitan. We can bypass security products and we can also facilitate this. So until Apple fixes this, which they may or may not, I would recommend scanning your system. Make sure you're not hijacked. Really doubt that you are but can't hurt. Also only download software over HTTPS and if you see a company distributing software over HTTPS send them a little nasty email or something. And then this is my personal opinion. I don't think the antivirus products are worth paying any money for. They cost money and they don't really detect it. You can find me on Twitter, email. Slides available for download. I wrote a white paper about this technique for virus bulletin. Check out ObjectiveSeas.com for free security tools. And also check out Cinec.com. We're an awesome company. So that's it. Are there any questions? Yes. Some of the UI ones not but there are open source versions of knock knock and the dilip hijack scanner. Those are the next GitHub repository so you can download and play with those as well. Yes. Any other questions? Thank you. Gentleman blue. Okay. The question is how does this impact iOS? So I believe the code is kind of vulnerable because they share a lot of the same loader code but because iOS does not allow you to run any unsigned code, that right there kind of blocks all this attack. It only runs Apple sign code. So even if an application was vulnerable and you wanted a malicious dilip, the loader would just ignore it because it's not signed by Apple. Any other questions? Yes. That's a great question. So I think one thing, the question was could you require the dilips to be signed or something? So Apple I think should say if I'm an Apple sign process I should only be loading Apple sign binaries. Or if I'm a sign process I should be only loading signed dilips. So yeah, one problem that you could generically prevent this is say don't allow unsigned libraries, unsigned libraries to be loaded in that. Now it's not that hard to get a developer ID and then get Apple to sign it but it would make the bar a little higher and generically I think would prevent a lot of the attacks. So great question. All right. I think I'm about to get kicked off the stage. Thank you again. I will be hanging out here. So if you have any questions I would love to chat.