Process Injection Techniques Gotta Catch Them All
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Kotler, Itzik
Klein, Amit
When it comes to process injection in Windows, there are only 6-7 fundamental techniques, right? Wrong. In this talk, we provide the most comprehensive to-date “Windows process injection” collection of techniques. We focus on Windows 10 x64, and on injections from running 64-bit medium integrity process to another running 64-bit medium integrity process, without privilege elevation. We pay special attention to the new Windows protection technologies, e.g. CFG and CIG. We differentiate between memory write primitives and execution techniques, and discuss memory allocation strategies. Our collection is curated, analyzed, tabulated, with straight-forward, research-grade PoCs. We tested each technique against Windows 10 x64 with and without protections, and we report on the requirements, limitations, and quirks of each technique. And of course – no decent DEF CON presentation is complete without new attacks. We describe a new memory writing primitive which is CFG-agnostic. We describe a new “stack bombing” execution method (based on the memory write primitive above) that is inherently safe (even though overwriting the stack is a-priori a dangerous and destabilizing action). Finally, we release a library of all write primitives and execution methods, so users can generate “tailor-made” process injections. Itzik Kotler Itzik Kotler is CTO and Co-Founder of SafeBreach. Itzik has more than a decade of experience researching and working in the computer security space. He is a recognized industry speaker, having spoken at DEF CON, Black Hat USA, Hack In The Box, RSA, CCC and H2HC. Prior to founding SafeBreach, Itzik served as CTO at Security-Art, an information security consulting firm, and before that he was SOC Team Leader at Radware. (NASDQ: RDWR). Amit Klein Amit Klein is a world renowned information security expert, with 28 years in information security and over 30 published technical and academic papers on this topic. Amit is the VP Security Research at SafeBreach, responsible for researching various infiltration, exfiltration and lateral movement attacks. Before SafeBreach, Amit was the CTO for Trusteer (acquired by IBM) for 8.5 years. Prior to Trusteer, Amit was chief scientist for Cyota (acquired by RSA) for 2 years, and prior to that, director of Security and Research for Sanctum (acquired by Watchfire, now part of IBM security division) for 7 years. Amit has a B.Sc. from the Hebrew University in Mathematics and Physics (magna cum laude, Talpiot program), recognized by InfoWorld as a CTO of the year 2010 , and has presented at BlackHat USA, DEF CON, NDSS, OWASP Global (keynote), InfoCom, DSN, HITB, RSA, OWASP EU, CertConf, BlueHat, CyberTech, APWG and AusCERT (keynote).
 Welcome to track one, noon talk. This is uh Isaac Kotler and Amit Klein. So please give him a welcome to DEF CON. Thank you ladies and gentlemen and uh welcome to the uh presentation about uh process injection techniques. Uh some words about uh Isaac. You can see on the screen there. And also a few words about myself. And let's begin. So why do we do, why do we even care about uh process injections? Uh so they don't see the slides. They don't see the slides. You'll have to believe me on that. So when we started researching process injection back in uh late 2018 uh we obviously wanted to first understand what other people already did in this area. And to our surprise we couldn't find any comprehensive collection or catalog of process injection techniques. We found them scattered all over the internet in write ups, in proof of concept codes and in blogs. Uh also we didn't, we didn't find any, we didn't find, okay. We didn't, we couldn't find uh text that described the, the solely true process injections as we like to call them. And the text uh often uh took a bit of a liberal approach to what process injection is. Uh and uh lumped into process injection as some related but not true process injection techniques like process hollowing and spawning. Uh also we couldn't find uh uh categorization around the sub sub techniques of process injection namely process uh memory allocation, uh memory writing and uh code execution. And also we, we there was a lack of analysis and comparison between process injection techniques. Um finally uh we couldn't find any update for the old uh uh techniques that sometimes were developed for in the Windows XP days to Windows 10 uh with its latest security uh mechanisms and the 64 bit architecture. Before we begin uh I want to uh extend kudos to Adam of Hexacorn, Ojan and the Encilo team and Xaba Fitzel of the uh also known as the Evil Bit and uh many others that uh have no uh no space here to mention uh for their research uh in their invention, in inventions in process uh in process injection techniques uh development, documentation and proof of concepts uh of many, of many techniques. And of course head tip to end game for providing the first compilation of injection techniques although that compilation uh did lump together some non-true process injection techniques. So let us first define what true process injection is. Uh we're talking about injection from live user space process uh typically malware to another live user space process which is the target for injection which is typically benign or legitimate process. It can be a system process like Explorer.exe or a Microsoft office process, your browser, your messaging software, your email software, whatever you. Uh this is in contrast to which is out of scope for this uh project uh process spawning and hollowing uh and also some pre-execution techniques that require uh the uh malware to install or to configure things before the target process starts running like the LL hijacking, Upset, Appinit, LSP providers and image file execution options. Um so what's, what's important and interesting about Windows 10 and about 64 bit architecture. First Windows 10 introduced several security mechanisms such as a CFG, the control flow guard uh which prevents uh indirect calls to non-approved addresses and the CIG the code integrity guard which only allows modules all uh as we call them DLLs to be loaded if they are signed by Microsoft uh Microsoft Store or WHQL. Uh what's interesting about the 64 bit architecture as opposed to 32 bit architecture is that with 64 bit architecture the calling convention is different. Uh the first four arguments of a function are passed through the uh four uh volatile registers uh that would be uh uh RCX, RDX, R8 and R9. So that if uh so that in order to invoke uh successful invoke a function in the target process you need to control at least one or in depending on the number of arguments in the function up to four registers as opposed to on as opposed to only uh cooking up the stack which was the uh the uh uh which was the way to invoke functions in the 32 bit world. Also in the 64 bit world there's no uh pop all registers uh in opcode and that prevents us from uh uh elegantly populating all registers with uh desired values. There were there were a lot of good proof uh excellent proof of concepts out there for uh injection techniques. Uh but the problem is that that is that exact definition there are excellent proof of concepts uh in in that what I mean is that they uh they handle they they have proper error handling and exception handling uh they are uh tailored for both 32 bit applications and 64 bit applications and they also lump together uh in this case uh the uh uh uh uh the novel memor writing technique with an execution technique in order to demonstrate a full end to end uh process injection. Uh that makes the uh source code uh uh blow into 1500 line of code I don't know if you can see that. Uh and I and as a researcher I was I found it very difficult to focus on exactly what the novelty of the technique is. Whereas what I wanted to find or wanted what I searched for uh is the those those three lines that that are wrapped into five lines at the right hand side of the screen where you can see the exact uh technique that is uh the exact technique that is used in this case it's atom bombing. So what I what uh uh what we could not find uh in many cases uh uh is uh concise 3, 4, 10 lines of code that that describe exactly the technique and nothing more. So we set up to fix this uh situation and to fill this gap uh and to document all those process injection techniques. And the scope of our project was uh true process injection running a sequence of logic or commands in the target process so we're not talking about just uh forcing a system uh function call and and spawning another process. Uh the focus was on Windows 10 version 18.03 on the above. So we're talking about uh pretty recent versions of Windows 10. Uh X64 injection injecting process and X64 target process both medium integrity. We only look at techniques that do not require admin rights and we evaluate all the techniques against uh recent Windows 10 protections specifically CFG and CIG. Few words about CFG strategy. The attacker that wants to uh inject into a CFG protected target process has several options uh to choose from. The first one obviously is to disable CFG and this is possible for a standard Windows API set process valid call targets. Um however if you think about it this is a pretty suspicious action in itself and can be flagged by security products. Also I uh speculate that it may be disabled or restricted in the future by Microsoft. Another approach would be to allocate or set executable memory uh which uh as a side effect makes all the allocated memory CFG valid. Uh this can be done with virtual alloc EX or virtual protect EX. But then again if you think about it this is extremely suspicious we all know what happens next. We just allocated a bunch of executable pages in the target process. Obviously we know what's going to happen. So this is extremely suspicious. The third option and I think this is the future of process injection techniques is to play by the rules that is writing a non executable data which is of can be a ROP chain and then using a CFG agnostic execution method to run a stack pivot gadget and start running start executing the ROP chain. Uh unfortunately or fortunately depending on your point of view only very few execution techniques are CFG agnostic and I will touch on this subject later in this presentation. With respect to CIG and other defenses they used to be they used to be a technique to eliminate those defenses using set process mitigation policy in the target process invoking that with NTQ APC thread because that function has only three arguments uh that NTQ APC thread could cover them all. We'll see that in uh later slide. However this technique no longer works as of 1809 uh and I want to mention that CIG is most painful because it prevents us from loading a arbitrary non Microsoft signed DLLs. So what are the typical process injection building blocks? We have memory allocation and when we are when we are looking at uh such techniques we need to consider uh whether the allocation is implicit like a cave or stack or explicit where we actually allocate the memory ourselves. What page permissions are there? What control do we have over the allocation address and whether the target addresses will be CFG valid or not? Then we have memory writing, populating that uh memory area with our desired values. And the questions are whether the that whether a memory writing technique allows us to write arbitrary data or are there restrictions on size or character set and whether the writes are atomic or not. Finally there's uh there are the execution techniques uh and they need to be evaluated against whether the target has to be CFG valid or not, what controls do we have over the registers and what limitations and prerequisites are there for the execution methods and there are a lot of restrictions and limitations for some techniques out there. Without much ado let's go over some process injection techniques. I'm going to go over very quickly the uh uh uh very known ones and focus a bit more on the lesser known ones so I'm going to uh go quickly now. Uh there's the virtual aloki x uh memory allocation technique that we're all familiar with. It can allocate executable pages so those pages become CFG valid automatically by windows and of course we can only we can allocate to just read write and later uh add the uh page execute uh privileges with virtual protect ex. Um then we have the classic memory uh writing technique of using no write process memory. Again no prerequisites or limitations the address is fully controlled uh with regard to CFG if the allocation is set executable privileges then there are no problems. Uh CIG is of course not uh relevant because we are not handling DLLs here. And finally there's the create remote thread execution technique uh in which CIG has no impact because we're just we're not talking about DLLs here and with respect to CFG the target execution has to be CFG val- uh valid target and this is very val- uh this is enforced by uh the operating system. Uh we only have controls over RCX so we can only safely invoke functions with a single argument in this way. Then we have a classic DLL injection execution technique using again create remote thread but this time assuming we will use the writing technique to write the DLL path into the uh target process already we invoke create remote thread uh we invoke load library A with create remote thread and the argument of load library A would be the the path to the DLL already written to the target process. Uh in this case uh the prerequisite is that this DLL on disk and uh please note that DLL main this is the what uh the loader executes in such case is restricted to the load with the loader lock. CIG however blocks this technique so it no longer works if CIG is turned on in the target process and I just mentioned that uh variant of this technique can use Q user APC or NT Q APC thread instead of create remote thread. Uh another well known classic DLL injection technique is using setwindows hook acts in which case uh the DLL is loaded to the target process when the target process receives an event of a certain kind and after we we uh invoke setwindow hook acts uh we uh artificially send such event to the target thread and execution ensues. Again the prerequisite is that the DLL is on disk and again CIG blocks this technique. Uh one other classic execution technique is APC you can use a Q user APC the standard windows API or NT Q APC thread which is the internal function and more uh uh flexible function and more useful one. Now the prerequisite here starts be- starts getting interesting because the thread must be in an alertable state I'll take about I'll talk about that in the next slide. CIG has no impact we're not talking DLLs here and their CFG uh is uh is uh is uh relevant because the target execution should be valid CFG target again and forced by window uh windows at the uh uh uh uh uh uh uh uh uh in the execution time. Um Q user APC grants us control over RCX NT Q APC thread grants us control over two and a half registers RCX RDX and the lower half of R8. This can be quite useful for functions that uh accept up to three arguments. Now what is an alertable state? It means that uh uh that the thread is executing or is hanging in one of five functions, sleepy X, wait for single object X, etc, etc. And uh in in all five cases it means that the actual internal function executed uh executed when the thread is hung is NT delay execution, NT wait for single object and so forth. They all follow the same pattern they all follow the same template of code in which case the RIP is in uh at the entry point like NT delay execution plus hex 14 so therefore very easy to uh discover whether a thread is in an alertable state if you know it's RIP. So this is one handy uh uh handy byproduct of our research. Moving on to another pretty known technique, the suspend inject resume thread execution uh as the name hints we suspend the thread and then we set the RIP using set thread context to our desired execution location and then we resume the thread, the thread starts running in the new location. Now with respect to CFG amazingly there is no impact uh there's no check in Windows anywhere that this is a CFG valid uh address because there's it it it does not represent a callable function in the first place. And there is a bit of a restriction on our RIP it should be within the stack allocated region. Uh as for control over registers there is no guaranteed control over the volatile registers. Uh this is a bit of a puzzle. Uh in some processes uh we can control those volatile registers in others we cannot so we assume the worst we assume we cannot control the volatile registers. What if we can only write uh read write memory, no execution in the target process? Well we can use the write primitive uh to write uh rope chain to the target process and then set uh RIP to a stack pivot and start executing drop chain for this mechanism. Now here is an exotic uh technique that's uh not too well known it's called ghost writing I believe it dates back to 2007 and it's a monolithic technique in the sense that it carries out both uh memory writing and execution uh together. So it's quite similar to thread hijacking but without the need for memory writing uh uh primitive. The idea here is that memory writing is achieved in steps using set thread context to set the regi- to set registers and at the each at at the end of each step the thread is running an infinite loop which will be our success marker. Once the uh the malware sees that the thread is in the in the in its infinite loop marker it knows that it's safe to move to the next step. So we need three rope gadgets for this uh a sync gadget is simple simply an infinite loop the JMP minus two which will be the marker of a successful end of execution. I believe it's just two uh uh of uh of codes. And then we have a write gadget something like uh move into the uh uh set by RDI the value of RBX followed by uh return and then a stack pivot or something equivalent. So the first step is to write on stack the uh address of the infinite loop and the br- and using the write gadget and then finally the return from the write gadget will branch into the infinite loop and uh this will mark the uh successful end of this step. Moving to step two we write our arbitrary keywords uh so we repeatedly execute step two until we have all the memory that we need uh written to the target process. And the idea here is to use the write to to start the registers uh and to point at the write gadget so that the write gadget will write this keyword and then its return will branch right into the uh uh infinite loop. So marking the successful end of writing a single keyword and repeating this process as of as many times as needed to write all the arbitrary memory we need. Finally we just set RIP and RSP uh to desired value to start uh uh uh stack pivot or something similar and to start running over the ROP chain. One uh one lovely location for uh for the new stack is the unused part of the existing stack and here are some tips of how to do this right. Uh first you need to maintain some distance from the official top of stack the RSP value in order to to provide some space for stack for natural stack growing as as if the stack is used by Windows API calls. But on the other hand you can't go too far because the stack is limited by one megabyte so something like 64 kilobytes is probably in the in the in the right neighborhood. Now you need to grow the stack uh uh one page at a time, one guard page at a time in order to get from the TOS to where you really want to start writing your own stack and you do that by touching the memory page size intervals so that the uh the guard page will keep uh uh so the kernel will keep committing new pages uh as as we follow this algorithm. Finally you need to mind the stack alignment which is set to 16 bytes and it's uh really uh observed by some functions. So the uh the prerequisites from ghost writing is simply just a place where you can we can write some some data. There's no impact from CFG except uh what we already know about RSP. No of course no impact uh by from CIG because there's there are no DLLs involved and we have control over some registers which is nice. Now moving to um shared memory writing technique uh in this case uh the prerequisite is that we know that the uh target process uh has a shared memory section we know its name and we know its size and now it's pretty uh predictable if we know the exact software that we are targeting and it's built we know whether there are uh whether it uses shared memory and and or fort size. So this is uh we assume that this knowledge is available to the attacker. So the attacker first maps this shared memory to its own process writes the payload at the end of this shared memory. Hopefully it's an area not used by the legitimate software. And then uh opens the target process uh and starts looking for uh scanning its memory uh region by region trying to find a region that matches the attributes of the shared memory uh uh section. And this and so we are comparing we're looking for a map memory uh map and committed uh with page read write attributes and the exact uh size that we expect the shared memory to have. Once we find we also do a read memory to make sure that the payload is at the at the end of the shared memory. And once we know that we can start using this as memory written to the pro to the target process. Uh so the prerequisites obviously is that the target process has a read write shared memory and the attacker knows the name and the size uh with respect to CFG uh it's probably irrelevant because this memory is typically uh read and write only not executable. And CIG of course is irrelevant. Now we move to the atom bombing writing technique. So Navy speaking uh assuming the payload is small and it has contains no null bytes and except for terminating null byte uh what we have here is the uh the uh essence of this writing technique. We define a global uh an atom object in Windows that uh contains this payload for in this in the malware process and injecting process. And then we use anti QAPC thread uh to invoke the function get global get atom name A in the target uh process asking it to copy the value of the atom that we just created uh into the designated address. Now uh this is uh pretty uh pretty neat. The original paper uh doesn't try doesn't uh provide uh uh doesn't support writing null bytes. It simply assumes that the target memory is zeroed out which is the case because they chose to use a code cave. Uh we devise the technique to write null bytes and it's it's in our paper. The prerequisites are again that the third must be in an alertable state and that the target payload is allocated and writable. As for CFG and CIG there's no impact of course um and then we have another uh interesting uh allocation and writing technique combined uh using nt map view of section. Uh in this case the uh malware process forces uh a section to be mapped in the target process. It does so by first uh defining a section, populating it with the desired values and then uh opening the target process and uh doing running nt map view of section of the target process of the section into the target process. It's uh uh and we can also control the uh uh page attributes. You can ask for executable and and read execute and read write. So this cannot be used for already allocated memory. So for example we cannot write values on the stack using this technique. Uh and uh the the nice thing is the CFG wise is that Windows once because we requested uh page executable Windows will will mark the whole region as uh CFG valid. Um this is a uh a quite fascinating execution technique. The unmapped plus rewrite and it works like this. We we look at a DLL used heavily in the target process. Nt DLL is of course a prime choice. And then we first copy all the region of this DLL into our own process. Uh we suspend the target. So first we suspend the process then we copy the existing Nt DLL and entire module space into our process. We make a copy of it. We patch it, this copy locally. For example we can uh patch Nt and Nt close which is heavily used function. And then we un-map the original Nt DLL section from the target process and use any uh writing allocation and writing technique to map and and write the uh the patch the patch Nt DLL copy uh to where the original Nt DLL uh used to reside in the target process memory. And finally we flash the instructions from the CPU so that it will not it will forget everything it know it thought it knew about those uh addresses. Um and we resume the process. Now this is uh quite elegant. And of course with with respect to CFG it's a bit tricky because there are many all the entry and all the entry uh uh uh uh uh addresses in Nt DLL must be also uh uh be CFG valid uh now after this uh switch. Uh however fortunately when using Nt map view of section and virtual alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- and uh there are some uh tips regarding how not to destabilize the process. Uh first we need of course to do a process wise suspend because we can't know which thread will use the Nt DLL and when. And then the whole thing about copying the complete Nt DLL memory and then uh copying it back instead of just say uh uh copying parts of Nt DLL is because we need to make sure that some uh variables inside the Nt DLL space are consistent and if we just copy code and not the uh uh some uh uh uh variables that are part of the static variables and set that part of Nt DLL will bound to get in into inconsistency which will immediately crush the process. So if you do that copy the whole region. Uh there's a bunch of uh call back override execution techniques uh uh that uh operate under the same uh concept uh we have uh set things from set window long PTR to uh shuttle like uh uh uh techniques through ALPC, controlling checks, etc. The idea is that uh we write we write some code into the target using any writing technique then we find or obtain a memory object with a virtual table of call back uh table. Uh this may be tricky because uh uh it's not uh not all processes uh have all objects like uh ALPC or some sometimes some objects only exist in console application, some objects only exist if the uh application has uh private clipboard and this finding or obtaining uh can be done via a standard API like get window long PTR or via memory search like as is the case with ALPC then we replace this object or call back uh to point at our desired execution point which must be CFG valid target because windows will check each and every of those uh uh execution techniques in each of every one of them CFG is is checked and it may also require some adjustments to the object on to the code. We trigger execution which may be tricky because some uh techniques are not uh uh deterministic and we cannot really force uh the execution uh uh upon them and finally we restore the original object and call back so the process can resume normally. This is an example uh control inject uh in which uh we uh encode a pointer to our desired address and then we copy this pointer uh to where to the control C uh handler in the target process which is uh the address of kernel base single handler and finally we trigger execution by uh first uh simulating uh pressing the control key using send input and then uh sending the C character to the target process. Now we move to a nice technique that we developed uh we uh the uh nice writing technique we developed based on memset on memmove in which uh the idea is that we write uh arbitrary data to the process uh uh byte at a time and we use NTQ APC thread uh with uh the target function invoked being memset. This is a classic uh NTDLL function so it's it's not there's there are no CFG problems here and since memset takes three arguments the destination address the byte to write and how many copies we simply use it with the address we desire the byte we desire and the uh constant one and we can loop through our buffer and copy it to the destination address uh by the way along Weinberg uh we will be presenting here at today at 4 p.m. I believe they develop a similar uh technique. The prerequisites are that the thread must be in an alertable state we already discussed that and CFG is not affected because as I mentioned NTDLL memset is CFG valid. Finally there's this the execution technique we developed we call uh stack bombing uh in this case uh the idea here is that we overwrite uh a thing uh the return address on stack to point at our desired uh destination address. Now if the thread happens to be in an alertable state it becomes pretty simple. The code for an alertable a classic alertable state internal function is this as I said uh the the code the the thread is hanging right after a syscall at uh at entry point plus hex 14 and as you can see what will happen next is an immediate return without touching the stack or the registers so that if we modified the the value pointed to the value on stack pointed to by RSP we are bound to get execution. Of course the implementation is much more uh sophisticated and complex. There is a uh nice proof of concept uh in our paper and in our uh uh get uh the repository. Uh and the beauty of this uh technique is that uh there's no impact on CFG uh so we can use RopChain and start executing even if CFG is enabled in the uh in the target process. There are two techniques that we could not uh make um we could not implement successfully for Windows 10 the set win event hook and the desktop heap technique. If you manage to run them on Windows 10 X64 version 19.03 please please contact us we will be delighted to know. To summarize we looked at sick uh sorry five writing techniques and you can see the compesion here and in our paper. We also looked at over 20 execution techniques and uh you will see that uh techniques that are CFG agnostics marked in the yellow uh at the right hand side column are pretty rare. There are uh one two three and ours is the fourth and I we believe this is the future of process injection. Uh a quick bonus if you need to load a DLL and a system DLL into an arbitrary process maybe and you don't have a writing technique to write its path uh into the process first maybe your whole RopGuy maybe your favorite RopGuy is there. Uh we have good news for you. KernelBase.dll contains uh the names of uh more than a thousand system DLLs including some things like MSHTML.dll shell32.dll and wininet.dll and you can use that uh to load the uh the DLL using load library. And with that I hand it over to you Itzik. Thank you Amit. So as Amit mentioned our research was not only theory there's also the practical implementation side of it and as we went through and scraping different proof of concept trying to compile together we decided to take it to the next level and create Pinjectra. So in a nutshell Pinjectra is a framework that allow you to combine mix and match different elements as Amit presented writing and execution and obviously the payload in a mix and match style. And we're gonna sit in the next few slides. Feel free to go to the GitHub right now and download your copy. Okay so once you'll go to the GitHub you will see that the Pinjectra solution is basically made from four major projects. As Amit mentioned some of the injection techniques requires an artifact, a DLL. We already provided it for you. So the first two projects here are DLLs that are implementing certain interfaces so they can be easily used for the purpose of the injection. The other two is the Pinjectra itself which contains the library of the knowledge as well as the implementation and also for your convenience we also released a test process. This is a dummy program that puts itself into an alertable state as Amit mentioned it's a prerequisite for certain attacks techniques and so this will do the job for you. Now let's step a little bit outside and understand what's the philosophy. As I mentioned Pinjectra is a mix and match it's using object oriented so we leverage the CC++ static type system to create different classes from different types and so it's very easily kind of mixing together into a full attack. And how does it look like? Pretty much like that. So what you can see right now is the implementation of our new technique the stack bombing in Pinjectra. It's very easy, it's very clean, it's very elegant. We're looking on three major classes here. The first one code via which provides the actual execution so that's a class of an execution technique. Then we can see the net QAPC thread that's the writing technique and then at the end we can see the rope chain that's class representing of the payload. The mix and match philosophy means that you can now play and try different techniques, different primitives and see how they can combine together. You can obviously create the new ones and then explore different avenues. And now all this wrapped up in a very nice model. At the end of it there's a method for this class called inject that expects the process ID and thread ID and there you have it. And now let's go into a demo. No. Some technical difficulties. Okay. So this is the first class of the application. Okay. So what you can see here is two CMD consoles. There's a red one which will be the attacker and the green one which will be the attack key or the victim. So right now we're just going to run the test process. Again as I mentioned the purpose of that was to be the victim of the process injection. As you can see running it will conveniently print the process ID and thread ID as well as we'll put it into unrotable state. Going into the pinjector we will run it once without any parameters that will give us the usage of all the different attacks that are possible within the demo. Now finding the right combination with the process ID and thread ID will invoke the actual injection. In our payload by default we're using a very nifty low box word. So that's the process that you will have if you have a successful injection using pinjector right now. Okay. And as a bonus which we've seen for the last second there the process itself continues to run as interoperably. So again the process doesn't crash it keeps running. Moving on to a few other techniques that the meters mentioned and how they can be implemented within pinjector. Here's the ghost writing technique. So as you can see we're using conceptually the suspend inject resume design pattern not to be confused with the set thread context technique that the meters presented for the classical sear. Then we have the ghost writing as the actual writing primitive and then that accepts the payload. So again a pretty fairly simple way to combine different techniques into a one fusion process. So let's check this demo as well. Okay. So the same idea applies. We're creating a green process to be injected to. And then we're going into pinjector. Again running it without any parameters we will see the different usage that contains the different options. Giving it the process ID and thread ID. And we pop the box. Thank you. Thank you. Thank you. And now we're going to the next step. We're going to the next step. Okay. Again continuing with the series of demos that we have planned for you today. As Amit mentioned the very exotic and interesting technique of the unmap and map which includes many different steps in the way. Again with pinject probably broken down into these three different classes. For the people here that were keeping notes on the actual class names you can see the code via suspend inject and resume underscore complex was already actually used in our own implementation of the stack bombing. This is just one of the features of using these libraries the ability to reuse existing code and logic. And so we do not have to reimplement the conceptually execution technique. We can then just focus on the create file mapping map view file and PN map and map of the section. This is the combination that essentially identifies these technique. And of course the payload that has been accepted as the payload comes on top of it. Okay. Oh yeah. Okay. So the idea again is we're creating a green process and a red process. In this case as Amit mentioned our test process was not complicated enough to include all the different results and APIs. And so basically we also provided this very small batch file to simply return the P of the explorer. So in this case we're going to actually attack the explorer itself. So that gave us back the PID of the explorer process. And now going to pin check how we're going to use that as the destination of the process injection. Takes a little bit of a time. And here it is. Okay. The set window long pointer is quite an interesting implementation. As Amit mentioned we need to retrieve the actual structure and then change the callback within it. So for here it's actually a mixture of an execution technique which stands on its own. That's the code via set window long PTR. And then what we actually did is within the framework we refactor one of the most primitive techniques which is a combination of virtual allocation and write memory in conjunction with the payload. And the connector that actually brings them together is a metadata that calls complex immutable advanced memory writer. As you will dive into the framework you will see there's different types of classes to accommodate different types of attacks. That is actually a converter that we created for the purpose of this attack. So let's jump into the demo. It's important to mention that since this attack requires retrieval of a specific structure it's much easier to find to implement the discovery of finding of explorer within the attack itself and that's what you're going to see right now. So there's not going to be any green screen right now. It's only be contained within pin check tra. So we'll pass zero zero as an indication that again pin check tra method will come out with the PAD and TAD of explorer while using the set long window PTR API. And here it is. Okay. And that's but not least let's talk about the atom bombing technique and how it's implemented again within pin check tra. As you can see the Q user APC is used as the code execution technique and then the sequence of open thread, open process, virtual allocate and global add atom A are the actual writing sequence. And again you can see you can control the different parameters and you can control the function that retains the payload and having said that let's see how it looks on our platform. Okay. So here again we will be using the P of the actual explorer to perform the actual uh testing. Again we need a much complex process providing the PAD and TAD of explorer. Takes a second there and boom. Excellent. Thank you. And with that back to Amit. Thank you Itzik. So what have we seen today? Uh we have we have actually three deliverables you know through our project. One is a mapping of the vast territory of true process injection and together with that we provide an analysis and comparison. It's all in a single collection repository companion however way you like to call it. Uh it's part of the DEF CON uh deliverables uh from our side which so it's a PDF document uh for your uh enjoyment and pleasure. It's also uh on our website. We also provide this uh library that Itzik demonstrated called the PINJECTRA for a mix and match generation of process injection attacks. Now this is extremely important because a lot of the POCs out there will couple a single uh new say memory writing technique like in atom bombing with a single execution technique just to demonstrate that. And this becomes the atom bombing process injection uh technique. So if you're if you want to test your environment against or your system against uh atom bombing you may as well test that with not just a single execution technique but uh uh the all the array of possible execution techniques that that can be coupled to to atom bombing. And that's exactly what we provide with PINJECTRA. The ability to couple or to match any almost any writing technique with almost any execution technique and thereby we allow uh red teamers, blue teamers, uh security researchers to cover almost all the possible all possible uh combinations in this uh in this universe. Finally we also describe a new CFG agnostic execution technique and I remind you that this I believe that this is the future of process injections. The ones that are based on uh uh CFG agnostic execution techniques which we call stack bombing. And with that and coupled with that we also uh this we also uh uh described a new memory technique using a memset and mem move over APC. So that's our three deliverables. Thank you very much ladies and gentlemen.
 Welcome to track one, noon talk. This is uh Isaac Kotler and Amit Klein. So please give  him a welcome to DEF CON.  Thank you ladies and gentlemen and uh welcome to the uh presentation about uh process injection  techniques. Uh some words about uh Isaac. You can see on the screen there. And also a few  words about myself. And let's begin. So why do we do, why do we even care about uh process  injections? Uh so they don't see the slides. They don't see the slides. You'll have to  believe me on that. So when we started researching process injection back in uh late 2018 uh  we obviously wanted to first understand what other people already did in this area. And  to our surprise we couldn't find any comprehensive collection or catalog of process injection  techniques. We found them scattered all over the internet in write ups, in proof of concept  codes and in blogs. Uh also we didn't, we didn't find any, we didn't find, okay. We didn't, we  couldn't find uh text that described the, the solely true process injections as we like  to call them. And the text uh often uh took a bit of a liberal approach to what process  injection is. Uh and uh lumped into process injection as some related but not true process  injection techniques like process hollowing and spawning. Uh also we couldn't find uh uh  categorization around the sub sub techniques of process injection namely process uh memory  allocation, uh memory writing and uh code execution. And also we, we there was a lack of  analysis and comparison between process injection techniques. Um finally uh we couldn't find any  update for the old uh uh techniques that sometimes were developed for in the Windows XP  days to Windows 10 uh with its latest security uh mechanisms and the 64 bit architecture.  Before we begin uh I want to uh extend kudos to Adam of Hexacorn, Ojan and the Encilo team and  Xaba Fitzel of the uh also known as the Evil Bit and uh many others that uh have no uh no  space here to mention uh for their research uh in their invention, in inventions in process  uh in process injection techniques uh development, documentation and proof of concepts uh of  many, of many techniques. And of course head tip to end game for providing the first  compilation of injection techniques although that compilation uh did lump together some  non-true process injection techniques. So let us first define what true process injection  is. Uh we're talking about injection from live user space process uh typically malware to  another live user space process which is the target for injection which is typically benign  or legitimate process. It can be a system process like Explorer.exe or a Microsoft office  process, your browser, your messaging software, your email software, whatever you. Uh this  is in contrast to which is out of scope for this uh project uh process spawning and hollowing  uh and also some pre-execution techniques that require uh the uh malware to install or to  configure things before the target process starts running like the LL hijacking, Upset,  Appinit, LSP providers and image file execution options.  Um so what's, what's important and interesting about Windows 10 and about 64 bit architecture.  First Windows 10 introduced several security mechanisms such as a CFG, the control flow  guard uh which prevents uh indirect calls to non-approved addresses and the CIG the code  integrity guard which only allows modules all uh as we call them DLLs to be loaded if they are  signed by Microsoft uh Microsoft Store or WHQL. Uh what's interesting about the 64 bit  architecture as opposed to 32 bit architecture is that with 64 bit architecture the calling  convention is different. Uh the first four arguments of a function are passed through the  uh four uh volatile registers uh that would be uh uh RCX, RDX, R8 and R9. So that if uh so that in  order to invoke uh successful invoke a function in the target process you need to control at  least one or in depending on the number of arguments in the function up to four registers as  opposed to on as opposed to only uh cooking up the stack which was the uh the uh uh which was  the way to invoke functions in the 32 bit world. Also in the 64 bit world there's no uh  pop all registers uh in opcode and that prevents us from uh uh elegantly populating all  registers with uh desired values. There were there were a lot of good proof uh excellent proof  of concepts out there for uh injection techniques. Uh but the problem is that that is that exact  definition there are excellent proof of concepts uh in in that what I mean is that they uh  they handle they they have proper error handling and exception handling uh they are uh  tailored for both 32 bit applications and 64 bit applications and they also lump together  uh in this case uh the uh uh uh uh the novel memor writing technique with an execution  technique in order to demonstrate a full end to end uh process injection. Uh that makes the  uh source code uh uh blow into 1500 line of code I don't know if you can see that. Uh  and I and as a researcher I was I found it very difficult to focus on exactly what the  novelty of the technique is. Whereas what I wanted to find or wanted what I searched for uh  is the those those three lines that that are wrapped into five lines at the right hand side of  the screen where you can see the exact uh technique that is uh the exact technique that is used in  this case it's atom bombing. So what I what uh uh what we could not find uh in many cases uh  uh is uh concise 3, 4, 10 lines of code that that describe exactly the technique and nothing  more. So we set up to fix this uh situation and to fill this gap uh and to document all those  process injection techniques. And the scope of our project was uh true process injection  running a sequence of logic or commands in the target process so we're not talking about  just uh forcing a system uh function call and and spawning another process. Uh the focus  was on Windows 10 version 18.03 on the above. So we're talking about uh pretty recent  versions of Windows 10. Uh X64 injection injecting process and X64 target process both  medium integrity. We only look at techniques that do not require admin rights and we evaluate  all the techniques against uh recent Windows 10 protections specifically CFG and CIG. Few  words about CFG strategy. The attacker that wants to uh inject into a CFG protected target  process has several options uh to choose from. The first one obviously is to disable CFG and  this is possible for a standard Windows API set process valid call targets. Um however if  you think about it this is a pretty suspicious action in itself and can be flagged by security  products. Also I uh speculate that it may be disabled or restricted in the future by Microsoft.  Another approach would be to allocate or set executable memory uh which uh as a side effect  makes all the allocated memory CFG valid. Uh this can be done with virtual alloc EX or  virtual protect EX. But then again if you think about it this is extremely suspicious we all  know what happens next. We just allocated a bunch of executable pages in the target process.  Obviously we know what's going to happen. So this is extremely suspicious. The third option  and I think this is the future of process injection techniques is to play by the rules that  is writing a non executable data which is of can be a ROP chain and then using a CFG agnostic  execution method to run a stack pivot gadget and start running start executing the ROP chain.  Uh unfortunately or fortunately depending on your point of view only very few execution  techniques are CFG agnostic and I will touch on this subject later in this presentation.  With respect to CIG and other defenses they used to be they used to be a technique to  eliminate those defenses using set process mitigation policy in the target process invoking  that with NTQ APC thread because that function has only three arguments uh that NTQ APC thread  could cover them all. We'll see that in uh later slide. However this technique no longer  works as of 1809 uh and I want to mention that CIG is most painful because it prevents us  from loading a arbitrary non Microsoft signed DLLs. So what are the typical process injection  building blocks? We have memory allocation and when we are when we are looking at uh such  techniques we need to consider uh whether the allocation is implicit like a cave or stack or  explicit where we actually allocate the memory ourselves. What page permissions are there? What  control do we have over the allocation address and whether the target addresses will be CFG  valid or not? Then we have memory writing, populating that uh memory area with our desired values. And  the questions are whether the that whether a memory writing technique allows us to write  arbitrary data or are there restrictions on size or character set and whether the writes are  atomic or not. Finally there's uh there are the execution techniques uh and they need to be  evaluated against whether the target has to be CFG valid or not, what controls do we have over  the registers and what limitations and prerequisites are there for the execution methods and  there are a lot of restrictions and limitations for some techniques out there. Without much ado  let's go over some process injection techniques. I'm going to go over very quickly the uh uh  uh very known ones and focus a bit more on the lesser known ones so I'm going to uh go quickly  now. Uh there's the virtual aloki x uh memory allocation technique that we're all familiar  with. It can allocate executable pages so those pages become CFG valid automatically by  windows and of course we can only we can allocate to just read write and later uh add the uh page  execute uh privileges with virtual protect ex. Um then we have the classic memory uh writing  technique of using no write process memory. Again no prerequisites or limitations the address is  fully controlled uh with regard to CFG if the allocation is set executable privileges then  there are no problems. Uh CIG is of course not uh relevant because we are not handling DLLs here.  And finally there's the create remote thread execution technique uh in which CIG has no  impact because we're just we're not talking about DLLs here and with respect to CFG the target  execution has to be CFG val- uh valid target and this is very val- uh this is enforced by uh  the operating system. Uh we only have controls over RCX so we can only safely invoke functions  with a single argument in this way. Then we have a classic DLL injection execution technique  using again create remote thread but this time assuming we will use the writing technique  to write the DLL path into the uh target process already we invoke create remote thread uh we  invoke load library A with create remote thread and the argument of load library A would be the  the path to the DLL already written to the target process. Uh in this case uh the prerequisite  is that this DLL on disk and uh please note that DLL main this is the what uh the loader executes  in such case is restricted to the load with the loader lock. CIG however blocks this technique  so it no longer works if CIG is turned on in the target process and I just mentioned that uh  variant of this technique can use Q user APC or NT Q APC thread instead of create remote  thread. Uh another well known classic DLL injection technique is using setwindows hook  acts in which case uh the DLL is loaded to the target process when the target process receives  an event of a certain kind and after we we uh invoke setwindow hook acts uh we uh artificially  send such event to the target thread and execution ensues. Again the prerequisite is that the  DLL is on disk and again CIG blocks this technique. Uh one other classic execution technique is  APC you can use a Q user APC the standard windows API or NT Q APC thread which is the  internal function and more uh uh flexible function and more useful one. Now the prerequisite  here starts be- starts getting interesting because the thread must be in an alertable state  I'll take about I'll talk about that in the next slide. CIG has no impact we're not talking  DLLs here and their CFG uh is uh is uh is uh relevant because the target execution should  be valid CFG target again and forced by window uh windows at the uh uh uh uh uh uh uh uh uh  in the execution time. Um Q user APC grants us control over RCX NT Q APC thread grants us  control over two and a half registers RCX RDX and the lower half of R8. This can be quite  useful for functions that uh accept up to three arguments. Now what is an alertable  state? It means that uh uh that the thread is executing or is hanging in one of five  functions, sleepy X, wait for single object X, etc, etc. And uh in in all five cases it means  that the actual internal function executed uh executed when the thread is hung is NT  delay execution, NT wait for single object and so forth. They all follow the same pattern  they all follow the same template of code in which case the RIP is in uh at the entry point  like NT delay execution plus hex 14 so therefore very easy to uh discover whether a  thread is in an alertable state if you know it's RIP. So this is one handy uh uh handy  byproduct of our research. Moving on to another pretty known technique, the suspend  inject resume thread execution uh as the name hints we suspend the thread and then we set  the RIP using set thread context to our desired execution location and then we resume the  thread, the thread starts running in the new location. Now with respect to CFG amazingly  there is no impact uh there's no check in Windows anywhere that this is a CFG valid uh  address because there's it it it does not represent a callable function in the first  place. And there is a bit of a restriction on our RIP it should be within the stack  allocated region. Uh as for control over registers there is no guaranteed control over  the volatile registers. Uh this is a bit of a puzzle. Uh in some processes uh we can  control those volatile registers in others we cannot so we assume the worst we assume we  cannot control the volatile registers. What if we can only write uh read write memory, no  execution in the target process? Well we can use the write primitive uh to write uh  rope chain to the target process and then set uh RIP to a stack pivot and start executing  drop chain for this mechanism. Now here is an exotic uh technique that's uh not too well  known it's called ghost writing I believe it dates back to 2007 and it's a monolithic  technique in the sense that it carries out both uh memory writing and execution uh together.  So it's quite similar to thread hijacking but without the need for memory writing uh  uh primitive. The idea here is that memory writing is achieved in steps using set thread  context to set the regi- to set registers and at the each at at the end of each step the  thread is running an infinite loop which will be our success marker. Once the uh the  malware sees that the thread is in the in the in its infinite loop marker it knows that  it's safe to move to the next step. So we need three rope gadgets for this uh a sync  gadget is simple simply an infinite loop the JMP minus two which will be the marker of a  successful end of execution. I believe it's just two uh uh of uh of codes. And then we have  a write gadget something like uh move into the uh uh set by RDI the value of RBX followed  by uh return and then a stack pivot or something equivalent. So the first step is to write on  stack the uh address of the infinite loop and the br- and using the write gadget and then  finally the return from the write gadget will branch into the infinite loop and uh this  will mark the uh successful end of this step. Moving to step two we write our arbitrary  keywords uh so we repeatedly execute step two until we have all the memory that we need uh  written to the target process. And the idea here is to use the write to to start the registers  uh and to point at the write gadget so that the write gadget will write this keyword and  then its return will branch right into the uh uh infinite loop. So marking the successful end  of writing a single keyword and repeating this process as of as many times as needed to  write all the arbitrary memory we need. Finally we just set RIP and RSP uh to desired value to  start uh uh uh stack pivot or something similar and to start running over the ROP chain. One uh one  lovely location for uh for the new stack is the unused part of the existing stack and here are  some tips of how to do this right. Uh first you need to maintain some distance from the  official top of stack the RSP value in order to to provide some space for stack for natural  stack growing as as if the stack is used by Windows API calls. But on the other hand you  can't go too far because the stack is limited by one megabyte so something like 64 kilobytes is  probably in the in the in the right neighborhood. Now you need to grow the stack uh uh one page  at a time, one guard page at a time in order to get from the TOS to where you really want to  start writing your own stack and you do that by touching the memory page size intervals so  that the uh the guard page will keep uh uh so the kernel will keep committing new pages uh as as  we follow this algorithm. Finally you need to mind the stack alignment which is set to 16  bytes and it's uh really uh observed by some functions. So the uh the prerequisites from ghost  writing is simply just a place where you can we can write some some data. There's no impact  from CFG except uh what we already know about RSP. No of course no impact uh by from CIG  because there's there are no DLLs involved and we have control over some registers which is  nice. Now moving to um shared memory writing technique uh in this case uh the prerequisite is  that we know that the uh target process uh has a shared memory section we know its name and we  know its size and now it's pretty uh predictable if we know the exact software that we are  targeting and it's built we know whether there are uh whether it uses shared memory and and or  fort size. So this is uh we assume that this knowledge is available to the attacker. So the  attacker first maps this shared memory to its own process writes the payload at the end of this  shared memory. Hopefully it's an area not used by the legitimate software. And then uh opens the  target process uh and starts looking for uh scanning its memory uh region by region trying to  find a region that matches the attributes of the shared memory uh uh section. And this and so  we are comparing we're looking for a map memory uh map and committed uh with page read write  attributes and the exact uh size that we expect the shared memory to have. Once we find we also  do a read memory to make sure that the payload is at the at the end of the shared memory. And  once we know that we can start using this as memory written to the pro to the target process. Uh  so the prerequisites obviously is that the target process has a read write shared memory and  the attacker knows the name and the size uh with respect to CFG uh it's probably irrelevant  because this memory is typically uh read and write only not executable. And CIG of course is  irrelevant. Now we move to the atom bombing writing technique. So Navy speaking uh assuming the  payload is small and it has contains no null bytes and except for terminating null byte uh  what we have here is the uh the uh essence of this writing technique. We define a global uh an  atom object in Windows that uh contains this payload for in this in the malware process and  injecting process. And then we use anti QAPC thread uh to invoke the function get global get  atom name A in the target uh process asking it to copy the value of the atom that we just  created uh into the designated address. Now uh this is uh pretty uh pretty neat. The original  paper uh doesn't try doesn't uh provide uh uh doesn't support writing null bytes. It simply  assumes that the target memory is zeroed out which is the case because they chose to use a  code cave. Uh we devise the technique to write null bytes and it's it's in our paper. The  prerequisites are again that the third must be in an alertable state and that the target  payload is allocated and writable. As for CFG and CIG there's no impact of course um and then  we have another uh interesting uh allocation and writing technique combined uh using nt  map view of section. Uh in this case the uh malware process forces uh a section to be mapped in  the target process. It does so by first uh defining a section, populating it with the  desired values and then uh opening the target process and uh doing running nt map view of  section of the target process of the section into the target process. It's uh uh and we can  also control the uh uh page attributes. You can ask for executable and and read execute and  read write. So this cannot be used for already allocated memory. So for example we cannot  write values on the stack using this technique. Uh and uh the the nice thing is the CFG wise  is that Windows once because we requested uh page executable Windows will will mark the  whole region as uh CFG valid. Um this is a uh a quite fascinating execution technique. The  unmapped plus rewrite and it works like this. We we look at a DLL used heavily in the target  process. Nt DLL is of course a prime choice. And then we first copy all the region of this DLL  into our own process. Uh we suspend the target. So first we suspend the process then we copy  the existing Nt DLL and entire module space into our process. We make a copy of it. We patch  it, this copy locally. For example we can uh patch Nt and Nt close which is heavily used  function. And then we un-map the original Nt DLL section from the target process and  use any uh writing allocation and writing technique to map and and write the uh the  patch the patch Nt DLL copy uh to where the original Nt DLL uh used to reside in the target  process memory. And finally we flash the instructions from the CPU so that it will not it will  forget everything it know it thought it knew about those uh addresses. Um and we resume the  process. Now this is uh quite elegant. And of course with with respect to CFG it's a bit  tricky because there are many all the entry and all the entry uh uh uh uh uh addresses in  Nt DLL must be also uh uh be CFG valid uh now after this uh switch. Uh however fortunately  when using Nt map view of section and virtual alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu-  alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu- alu-  and uh there are some uh tips regarding how not to destabilize the process. Uh first we  need of course to do a process wise suspend because we can't know which thread will use  the Nt DLL and when. And then the whole thing about copying the complete Nt DLL memory and  then uh copying it back instead of just say uh uh copying parts of Nt DLL is because we need to  make sure that some uh variables inside the Nt DLL space are consistent and if we just  copy code and not the uh uh some uh uh uh variables that are part of the static variables  and set that part of Nt DLL will bound to get in into inconsistency which will immediately  crush the process. So if you do that copy the whole region. Uh there's a bunch of uh call  back override execution techniques uh uh that uh operate under the same uh concept uh we  have uh set things from set window long PTR to uh shuttle like uh uh uh techniques through  ALPC, controlling checks, etc. The idea is that uh we write we write some code into the  target using any writing technique then we find or obtain a memory object with a virtual  table of call back uh table. Uh this may be tricky because uh uh it's not uh not all  processes uh have all objects like uh ALPC or some sometimes some objects only exist in  console application, some objects only exist if the uh application has uh private clipboard  and this finding or obtaining uh can be done via a standard API like get window long PTR or  via memory search like as is the case with ALPC then we replace this object or call back uh to  point at our desired execution point which must be CFG valid target because windows will  check each and every of those uh uh execution techniques in each of every one of them CFG is  is checked and it may also require some adjustments to the object on to the code. We  trigger execution which may be tricky because some uh techniques are not uh uh deterministic  and we cannot really force uh the execution uh uh upon them and finally we restore the  original object and call back so the process can resume normally. This is an example uh  control inject uh in which uh we uh encode a pointer to our desired address and then we  copy this pointer uh to where to the control C uh handler in the target process which is uh  the address of kernel base single handler and finally we trigger execution by uh first uh  simulating uh pressing the control key using send input and then uh sending the C character to  the target process. Now we move to a nice technique that we developed uh we uh the uh  nice writing technique we developed based on memset on memmove in which uh the idea is that  we write uh arbitrary data to the process uh uh byte at a time and we use NTQ APC thread uh  with uh the target function invoked being memset. This is a classic uh NTDLL function so it's  it's not there's there are no CFG problems here and since memset takes three arguments the  destination address the byte to write and how many copies we simply use it with the address  we desire the byte we desire and the uh constant one and we can loop through our buffer and  copy it to the destination address uh by the way along Weinberg uh we will be presenting  here at today at 4 p.m. I believe they develop a similar uh technique. The prerequisites are  that the thread must be in an alertable state we already discussed that and CFG is not affected  because as I mentioned NTDLL memset is CFG valid. Finally there's this the execution  technique we developed we call uh stack bombing uh in this case uh the idea here is that we  overwrite uh a thing uh the return address on stack to point at our desired uh destination  address. Now if the thread happens to be in an alertable state it becomes pretty simple. The  code for an alertable a classic alertable state internal function is this as I said uh the  the code the the thread is hanging right after a syscall at uh at entry point plus hex 14 and as  you can see what will happen next is an immediate return without touching the stack or the  registers so that if we modified the the value pointed to the value on stack pointed to by  RSP we are bound to get execution. Of course the implementation is much more uh sophisticated  and complex. There is a uh nice proof of concept uh in our paper and in our uh uh get uh the  repository. Uh and the beauty of this uh technique is that uh there's no impact on CFG uh so we  can use RopChain and start executing even if CFG is enabled in the uh in the target  process. There are two techniques that we could not uh make um we could not implement  successfully for Windows 10 the set win event hook and the desktop heap technique. If you  manage to run them on Windows 10 X64 version 19.03 please please contact us we will be  delighted to know. To summarize we looked at sick uh sorry five writing techniques and you  can see the compesion here and in our paper. We also looked at over 20 execution techniques  and uh you will see that uh techniques that are CFG agnostics marked in the yellow uh at the  right hand side column are pretty rare. There are uh one two three and ours is the fourth  and I we believe this is the future of process injection. Uh a quick bonus if you need to  load a DLL and a system DLL into an arbitrary process maybe and you don't have a writing  technique to write its path uh into the process first maybe your whole RopGuy maybe your  favorite RopGuy is there. Uh we have good news for you. KernelBase.dll contains uh the names of  uh more than a thousand system DLLs including some things like MSHTML.dll shell32.dll and  wininet.dll and you can use that uh to load the uh the DLL using load library. And with  that I hand it over to you Itzik. Thank you Amit. So as Amit mentioned our research was not  only theory there's also the practical implementation side of it and as we went through  and scraping different proof of concept trying to compile together we decided to take it to the  next level and create Pinjectra. So in a nutshell Pinjectra is a framework that allow you to  combine mix and match different elements as Amit presented writing and execution and  obviously the payload in a mix and match style. And we're gonna sit in the next few slides.  Feel free to go to the GitHub right now and download your copy. Okay so once you'll go to  the GitHub you will see that the Pinjectra solution is basically made from four major  projects. As Amit mentioned some of the injection techniques requires an artifact, a DLL. We  already provided it for you. So the first two projects here are DLLs that are implementing  certain interfaces so they can be easily used for the purpose of the injection. The other two  is the Pinjectra itself which contains the library of the knowledge as well as the  implementation and also for your convenience we also released a test process. This is a dummy  program that puts itself into an alertable state as Amit mentioned it's a prerequisite for  certain attacks techniques and so this will do the job for you. Now let's step a little bit  outside and understand what's the philosophy. As I mentioned Pinjectra is a mix and match  it's using object oriented so we leverage the CC++ static type system to create different  classes from different types and so it's very easily kind of mixing together into a full  attack. And how does it look like? Pretty much like that. So what you can see right now is  the implementation of our new technique the stack bombing in Pinjectra. It's very easy, it's  very clean, it's very elegant. We're looking on three major classes here. The first one code  via which provides the actual execution so that's a class of an execution technique. Then we  can see the net QAPC thread that's the writing technique and then at the end we can see the  rope chain that's class representing of the payload. The mix and match philosophy means  that you can now play and try different techniques, different primitives and see how they can  combine together. You can obviously create the new ones and then explore different avenues. And  now all this wrapped up in a very nice model. At the end of it there's a method for this  class called inject that expects the process ID and thread ID and there you have it. And now  let's go into a demo. No. Some technical difficulties. Okay. So this is the first class of the  application. Okay. So what you can see here is two CMD consoles. There's a red one which will be  the attacker and the green one which will be the attack key or the victim. So right now we're  just going to run the test process. Again as I mentioned the purpose of that was to be the  victim of the process injection. As you can see running it will conveniently print the process ID  and thread ID as well as we'll put it into unrotable state. Going into the pinjector we will  run it once without any parameters that will give us the usage of all the different attacks that  are possible within the demo. Now finding the right combination with the process ID and thread  ID will invoke the actual injection. In our payload by default we're using a very nifty  low box word. So that's the process that you will have if you have a successful injection  using pinjector right now. Okay. And as a bonus which we've seen for the last second there the  process itself continues to run as interoperably. So again the process doesn't crash it  keeps running. Moving on to a few other techniques that the meters mentioned and how they  can be implemented within pinjector. Here's the ghost writing technique. So as you can see  we're using conceptually the suspend inject resume design pattern not to be confused with the set  thread context technique that the meters presented for the classical sear. Then we have the ghost  writing as the actual writing primitive and then that accepts the payload. So again a pretty  fairly simple way to combine different techniques into a one fusion process. So let's check this  demo as well. Okay. So the same idea applies. We're creating a green process to be injected to. And  then we're going into pinjector. Again running it without any parameters we will see the  different usage that contains the different options. Giving it the process ID and thread ID. And we pop the  box. Thank you. Thank you. Thank you. And now we're going to the next step. We're going to the  next step. Okay. Again continuing with the series of demos that we have planned for you today. As  Amit mentioned the very exotic and interesting technique of the unmap and map which includes  many different steps in the way. Again with pinject probably broken down into these three  different classes. For the people here that were keeping notes on the actual class names you can  see the code via suspend inject and resume underscore complex was already actually used in our  own implementation of the stack bombing. This is just one of the features of using these libraries  the ability to reuse existing code and logic. And so we do not have to reimplement the  conceptually execution technique. We can then just focus on the create file mapping map view  file and PN map and map of the section. This is the combination that essentially identifies  these technique. And of course the payload that has been accepted as the payload comes on top of  it. Okay. Oh yeah. Okay. So the idea again is we're creating a green process and a red process. In  this case as Amit mentioned our test process was not complicated enough to include all the  different results and APIs. And so basically we also provided this very small batch file to  simply return the P of the explorer. So in this case we're going to actually attack the explorer  itself. So that gave us back the PID of the explorer process. And now going to pin check  how we're going to use that as the destination of the process injection. Takes a little bit of a  time. And here it is. Okay. The set window long pointer is quite an interesting implementation.  As Amit mentioned we need to retrieve the actual structure and then change the callback within  it. So for here it's actually a mixture of an execution technique which stands on its own.  That's the code via set window long PTR. And then what we actually did is within the framework  we refactor one of the most primitive techniques which is a combination of virtual allocation  and write memory in conjunction with the payload. And the connector that actually brings them  together is a metadata that calls complex immutable advanced memory writer. As you will  dive into the framework you will see there's different types of classes to accommodate  different types of attacks. That is actually a converter that we created for the purpose of  this attack. So let's jump into the demo. It's important to mention that since this attack  requires retrieval of a specific structure it's much easier to find to implement the discovery of  finding of explorer within the attack itself and that's what you're going to see right now. So  there's not going to be any green screen right now. It's only be contained within pin check  tra. So we'll pass zero zero as an indication that again pin check tra method will come out with  the PAD and TAD of explorer while using the set long window PTR API. And here it is. Okay. And  that's but not least let's talk about the atom bombing technique and how it's implemented  again within pin check tra. As you can see the Q user APC is used as the code execution  technique and then the sequence of open thread, open process, virtual allocate and global add  atom A are the actual writing sequence. And again you can see you can control the different  parameters and you can control the function that retains the payload and having said that  let's see how it looks on our platform. Okay. So here again we will be using the P of the actual  explorer to perform the actual uh testing. Again we need a much complex process providing the PAD  and TAD of explorer. Takes a second there and boom. Excellent. Thank you. And with that back  to Amit. Thank you Itzik. So what have we seen today? Uh we have we have actually three  deliverables you know through our project. One is a mapping of the vast territory of true  process injection and together with that we provide an analysis and comparison. It's all in a  single collection repository companion however way you like to call it. Uh it's part of the  DEF CON uh deliverables uh from our side which so it's a PDF document uh for your uh  enjoyment and pleasure. It's also uh on our website. We also provide this uh library that  Itzik demonstrated called the PINJECTRA for a mix and match generation of process injection  attacks. Now this is extremely important because a lot of the POCs out there will couple a  single uh new say memory writing technique like in atom bombing with a single execution  technique just to demonstrate that. And this becomes the atom bombing process injection  uh technique. So if you're if you want to test your environment against or your system against  uh atom bombing you may as well test that with not just a single execution technique but uh uh  the all the array of possible execution techniques that that can be coupled to to atom bombing.  And that's exactly what we provide with PINJECTRA. The ability to couple or to match any almost  any writing technique with almost any execution technique and thereby we allow uh red teamers,  blue teamers, uh security researchers to cover almost all the possible all possible uh  combinations in this uh in this universe. Finally we also describe a new CFG agnostic  execution technique and I remind you that this I believe that this is the future of process  injections. The ones that are based on uh uh CFG agnostic execution techniques which we call  stack bombing. And with that and coupled with that we also uh this we also uh uh described  a new memory technique using a memset and mem move over APC. So that's our three deliverables. Thank  you very much ladies and gentlemen.
Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_0_347.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_348_407.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_408_455.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_456_503.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_504_551.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_552_635.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_636_755.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_756_1787.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_1788_2123.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_2124_2723.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_2724_3191.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_3192_5819.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_5820_8615.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_8616_10223.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_10224_10475.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_10476_10523.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_10524_12311.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_12312_18671.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_18672_21107.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_21108_21539.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_21540_24203.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_24204_29843.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_29844_34955.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_34956_38855.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_38856_39599.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_39600_42227.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_42228_46607.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_46608_46979.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_46980_48239.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_48240_53351.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_53352_54911.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_54912_54971.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_54972_55787.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_55788_58535.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_58536_58643.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_58644_58739.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_58740_58955.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_58956_59951.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_59952_60731.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_60732_60791.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_60792_60935.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_60936_61007.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_61008_61163.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_61164_61523.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_61524_62375.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_62376_62843.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_62844_62951.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_62952_63599.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_63600_64139.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_64140_65267.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_65268_65327.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_65328_65375.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_65376_65555.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_65556_66479.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_66480_67163.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_67164_67235.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_67236_67427.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_67428_67619.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_67620_67667.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_67668_68063.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_68064_68183.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_68184_71807.png Itzik_Kotler_-_Process_Injection_Techniques_Gotta__Gq6-1xrmFHQ_71808_71920.png