 Hello Defcon. First of all, I would like to really thank Defcon for giving me the opportunity to come here and speak at this great conference. You guys really rock. So my presentation today is on Linux Thread Injection Kit. This is a kit that I have developed. I have named it Jougar, which I'll tell you why the name. So a little bit about me. I'm from India. I'm the founder of Null Security Community. If you're not aware, you can go to null.co.in and have a look. I'm also the organizer for NullCon Security Conference in India. It happens every year in February in Goa. And I'm the chief researcher at Pyro Technologies, which is a startup in information security services and trainings. All right. So a little bit about Null. It's a registered non-profit organization. And we have around six to seven chapters in India right now. And our prime focus is on knowledge sharing and security research. So we do that by means of having monthly meets in all of the chapters. And then we do security awareness camps in organizations and institutions. All right. So the agenda for today is I'm briefly going to touch upon what the toolkit is, what it is not, and basically kind of give you a very brief or just touch upon what code injection is, because I think most of you already know what different code injection techniques there are. And then I'm going to talk about how it is handled in Windows and how Linux lacks this capability. And a little bit about ptrace. And finally I'll talk about why library injection has a little bit of flaws. And then finally I'll talk about the toolkit that I have developed and how is it different from library injection and what exactly does it do. Okay. So Jhukar is a Hindi word, which is actually, which means a workaround or a hack, which is evident from the fact what we have been doing with this library. So it basically gives you a framework wherein you can inject your own customized payload as a thread inside a remote process. So I started looking at it from the point of view of Windows malware. So Windows already provides you an API where you can remotely inject code inside another process. But it's not there in Linux or other Unix platforms. Okay. So what it is not, it's not an exploit. I won't even call it a vulnerability because it is one of the features provided by Unix operating systems. Okay. So most of you are already aware of different code injection techniques. You can do it, you can do remote code execution via buffer overflows or you can do SQL injection. So I'm not going to talk about it because these are, these are kind of, I mean, everybody knows about it. So my interest area is the last, that is the APIs that are provided by the operating systems. So Windows, Windows already has an API where all you need to do is just call this function and it'll do the needful, whatever you want to do. So I'm not going to go into deep into what this API does, but we'll just look at some of the important parameters that this function has. So edge process will specify the target process or the victim process where you want to inject code. The stack size talks about the stack for the thread that you want to create inside the main process. And then the start address is the address of the function or code that you want to execute. Now according to this, the documentation of this function, it says that the function or the code must exist inside the process. Okay, so Linux, there's no equivalent API on Linux. So the question is how do we inject code into a remote process? So the first thing that obviously comes to mind is a debugger. How does a debugger inject code or do memory operations? How's the debugger able to access memory inside a remote process or a trace process? How is it able to change the values of variables? So the answer is simple. It uses the Ptrace API, which is obviously provided by most of the Unix platforms. So a little bit about Ptrace. So Ptrace is just a single function and it's a very powerful function in terms of what operations you can perform on a target process. So just one function will give you the ability to read memory, write memory, read registers, write registers, stop the process and do a lot of other things. So some of the common operations that you can perform, which we've also used in this library, attach obviously to attach or to start debugging a particular process, continue with if the trace process is stopped, you can start the execution of the trace process. So peak test allows you to read a word from a specified location inside a process. Poke text does the opposite. It allows you to write to that memory location. And getregs and setregs give you the option of setting registers for the process. Okay, so how does the debugger get the control back? I mean, if I'm tracing a process, obviously I need the control back after I execute some code. So how do I do that? So the breakpoints come to rescue. It's actually an int3 instruction or a software interrupt. When specified inside, when executed in a remote process, what it will do is the child process stops and you get the control back as the tracing process. All right, so a little bit about library injection. So when I started, the intention of developing this library was to create an exact replica of what is already there for Windows, so create remote thread. So after I was finished halfway through, I was still searching on the net for any tool available that does this thing. So I found an interesting tool called injectSO, which uses the same ptrace functionality to inject a whole shared object inside a process. Now the problem with this is you can see the library or the shared object that has been loaded into the process if you go and view the maps file. Okay, so I'll just give you a small demo of the tool. It's a pretty old tool. I think it was developed in 2005 or 2006, but it's nice in terms of what it does. So this is the library code, just the test code that comes with the injectSO implementation. So all it does is just says yo from init when the library is loaded. Okay, so this is how the libraries are structured. Now what we're going to do is, so all you need to do is just specify the PID and the library that you want to inject. And it uses the dl open function inside the process, executes that particular function. So there you go. Okay, so now coming back to the library that I've created. So what I've done is instead of injecting a shared object, I inject, I give the framework for, you know, to people who want to use it. To inject a shell code instead of, you know, injecting the whole library. So if you inject the shell code what happens is what you're doing is in effect all in memory injection. So there are no traces of any libraries ever being injected into the process. So I divided the problem into three parts. One was memory allocation and execution. How do you allocate memory inside the process? And how do you make it execute? Then is how do you, how do you threadifier? How do you create a thread inside that particular process? And the third is the customized payload that you want to execute inside that process. So allocation is very simple. What I've done is I've created a stub shell code which we'll see for MAP2 system call. So what I do is I backup a particular location inside the remote process and I backup the registers of the process. And then I overwrite it with my own MAP2 shell code and then make it execute that. So how do I do it? I use setregs to set the EIP to the memory that has been newly allocated by my shell code. And at the end I put the in three instructions so that I know once it has executed it gives control back to me. Yeah, so it's as simple as this. You specify the length of the memory that you want to create inside the remote process and MAP specific flags and the protection for the memory area. So yeah, this is the stub shell code. Now at runtime I just change the values, whatever values the user wants or the caller wants, I just change it to whatever is specified in the function. So what I do is I use the MAP code to first allocate memory inside the process. So I allocate memory for the thread and I allocate memory for the thread stack. And then what I do is I call the clone, so I inject the clone shell code which also contains my payload that we'll come to later. So what happens is I put the clone shell code and using the same process I make it execute the clone shell code. And if it's the child thread, it jumps on to the payload. If it's the parent thread, it gives me the control back because of the interrupt instruction. Yeah, so this is how the payload looks like. Once you pass the payload to the API, what it does is it creates a sandwich wherein it gives the clone head which is the stub shell code for the clone system call and a clone tail which is just the exit system call. So once it starts executing, in the child it will jump on to the payload from the clone head and then eventually to clone tail which is the exit system call. And if it is the parent thread, what it will do is it will execute the CC instruction and give control back to the tracing process. Okay, yeah, so implementation is very simple. I just play around with shell codes rather than executing the function inside the process directly. It makes it easier. So that's the API. I mean, this is used internally, but in case if you want to extend the shell codes, you can do it. I mean, it follows. If you look at the functions, the requirement is the same. You specify the length, you specify the memory protections and the flags for M-Map2, it will generate the shell code on the fly for you. Okay, so finally the API is as simple as this. All you need to do is specify the PID of the remote process. You need to specify the stack, the size of the stack, and you need to specify the payload that you want to inject inside that process. So this is all that is required from a generic point of view. But if you want to try it out with different options, you can actually get greater control using the extended function wherein you can specify your own M-Map flags. Now, why I've kept this extension is because I've been kind of finding a lot of problems with some of the distributions. So if you guys can try it out using different options for the M-Map flags and the thread flags or whatever. All right, so first we'll look at a simple demo wherein what I've done is my payload just creates a file called slash temp TMP slash temp slash TMP and it writes some data onto that file. Okay, so now I've backed up the registers and I've injected my M-Map2 shell code again twice. So this is one of the memories that has been returned by this process. Let's just have a look at it. FB000, yeah. So this memory area has been allocated because I've by default I specify read write and execute permissions for the memory area. That's like always supposed to happen with demos. So a real demo would be, I'll show you another demo, which I'll try to inject a TCP listener onto Firefox. So this particular shell code starts a listener. I've directly taken it from Mitter's point. This starts a listener at port 4444. Let's see if it works out. So I've just injected a thread inside this process. Let's see if, so it's probably this thread that is running. All right, so just one thing to understand is that since it's a thread injection, your payload should be at least thread aware since this payload is a standard Mitter's point payload that just spawns a shell basically execs the shell. So as soon as you try to connect to it, the Firefox will die obviously because it execs to a shell. So here's the Firefox. Now let's try and connect to it. Let's say NC. So now Firefox is dead and the process has changed to min slash sh. All right, so the conclusion is now you can actually do stealthy create remote thread in Linux. On top of what Windows provides, Windows does not give you the option of just passing in your payload and it'll do the rest. But in this case, you just need to pass the payload. So for Windows, you need to first create memory inside the remote process. I mean, you need to use two or three, a few lines of code before actually you're trying to execute something. Library injection, if you are looking at some kind of stealthy malware, library injection will not help you because it may be found out by forensics people and they're trying to just investigate which process might be the evil process. So yeah, if you want to... So Ubuntu, I think from 10 onwards, Ubuntu has disabled ptrace in their distribution. Fedora I think still has it open. So if you want to safeguard yourself from any future threat of this kind, I think the best way would be to just disable ptrace because on a normal system, if it's not a development box, there is no requirement of having ptrace on. It makes no sense actually. All right, so details of the project, you can get the project. It's hosted on Jithub and so this release contains is a 32-bit binary that works for 32-bit processes. So next version onwards, we'll be putting in support for 64-bit processes. And since we've already created this, so we might put a lot of other things like VM detection or anti-forensics into it. So if any of you is interested in helping out or just letting us know what all we can add into it other than just the threat injection part, it'll be helpful. All right, so contribution in the end. So if you guys are interested, we're actually having a small informal null meet here tomorrow, 4 o'clock outside the wireless village. So if any of you is interested in starting a null chapter or just want to know what null is or what we do, you can meet us at 4 o'clock, I think 4 o'clock or 6 o'clock. I'll be there at 4 o'clock and 6 o'clock. All right. Yeah, so that's about it. If you have any questions, I think we can take it in the Q&A room.