 O'Bear is now going to present Exploiting Windows Exploit Mitigation for ROP Exploits. I know exactly what I was doing there. Alright. Go ahead O'Bear. Hello everyone, thank you for coming. Let me get sorted and we can start. Okay, so first thing first. Doesn't work. So, I bet your parents taught you well and taught you, taught you don't listen to strangers. So I will introduce myself. I'm Omar Yair. I manage the endpoint team at Javelin Networks. We are a small startup that decided to protect your endpoint on the enterprise, to protect your active directory from the endpoint. And Symantec believed in us and acquired us a few, like nine months ago. Even though I'm still not sure how I'm supposed to pronounce the new title. I'm also a photographer and you can follow me on Twitter. So, I want to start with a guide of this talk. It's a quote by Gilles Deleuze, a French philosopher. And he said, the concept is a brick. It can be used to build a courthouse of reason or it can be thrown through the window. And throughout this talk we will identify all those bricks that make up ROP exploits, Windows exploit mitigation. And we will see how we can use those to break Windows. So what's on that agenda? We'll start talking about ROP 101. I will dump down the things as much as possible. Make it simple so everyone can understand. Then we'll talk about Windows exploit mitigations and we'll see how we can abuse them. Next about ROP mitigations and we'll see how we can bypass them. And lastly there will be a demo where you will clap hands and if you will hold, we will all behave yourself, there will be a little surprise too. So let's start. We can start talking about ROP exploit without mentioning smashing the stack for fun and profit. And is there anyone in the audience that ever heard the term for fun and profit? Please raise your hand. Yeah, it's quite common and I hope you all know where the source of this term came from. And it's an article by Aleph one that he wrote on 96 about the mechanics of stack overflow. And we can't talk about stack overflow without explaining how stack semantics work. So if you call a function in a 32-bit processor, you first need to push the parameters on the stack and the stack on my slides will grow upwards. And then when the call opcode is issued, the return address is pushed on the stack and the instruction pointer jumps to the function that you called. Now that function will allocate space for itself on the stack, do its stuff and eventually it will deallocate the space and the red opcode will pop the return address from the stack. So how stack overflow works? Well let's take hypothetical example, completely hypothetical. Let's say you have a program that gets an input and looks for details about the user. So it first allocates its space for the stack, then it uses get s to receive a buffer from the user. Now a normal user will just fill out the few bytes of the buffer, but a hacker will start overwriting the buffer until eventually the hacker overwrites the return address. So now if you're a lead hacker, you won't just write random bytes, you will write your shell code instead. And on the place that you write the return address, let's say hypothetical again, you know the address of the stack, you can just write the address of the stack where your shell code starts. So now when the return code will be issued, the instruction pointer will jump to the shell code on your stack and now you can run a shell. Now this is not a hypothetical at all, that was the exact source code and the exact buffer overflow, exact shell code that was used on the Morris world and that was 1988, almost a decade before Aleph Juan published his article on a stack overflow. So the security industry actually knew about stack overflow and the potential hazardous disaster that it can make, but still didn't do anything and it was so bad that it prompted the formation of the third coordination center. So again you would think that after Aleph Juan published his article, the security industry will wake up and start protecting everyone, but no, on 2003 all he had to do to exploit a buffer overflow was to write this simple HTML page and that's a CVE by Matt Miller and what happened behind the scene is that Internet Explorer just replaced every slash character with an underline slash underline which caused it to miscalculate the amount of bytes that it needed to write and then it caused you to write like the first buffer to the stack and you had the ability to override the return address and then you could write the shell code. But now this is not an OS where you can guess the address of the the stack, this is Windows, it's a modern OS, well then Matt Miller used the different trick, he knew that the system DLS were always loaded to the same address. So he looked in those DLS and found an opcode which is jump ESP, which was always on the same address. So instead of writing the address of the stack, he wrote the address of that command. So now when the return opcode is issued, the instruction pointer jumps to the jump ESP and after it executes jump ESP, now the instruction pointer points to the stack and you can pop calc if you want. Now you might ask yourself, well how is it even possible to run code from the stack? Shouldn't it be just read write memory? Well that was uh possible a long time ago until DEP came in on Windows XP service pack 2. And DEP or that execution prevention actually enforces the read write or more precisely the non-execute code uh in memory. Because Windows throughout time always marked that memory as only read write but the CPU ignored that and uh Windows had to add another bit which is called the annex bit which forces the CPU to actually not execute code on that uh area. And DEP was actually the cornerstone for Rop. It actually made Rop what it is today. And the reason why is now that it is because now we need a bridge between actually uh exploiting a software and writing our shell code to that uh memory and running it. So Rop feels the bridge between those uh two things. Now another thing you might ask yourself, what do you mean that all DLLs are loaded to the same address? Well again that was the reality back then. Until ASLR or address space layout customization came. And with ASLR every time you boot your machine Windows randomized the base address of each DLL. So now you can't guess the address you need to find it. Now it is effective mostly on remote exploits because if you can run code on your on the same machine let's say you're trying to exploit a privilege escalation bug. Well you can just run a benign program that loads the loads those DLL and you know the address of those DLLs. So I want to take a little step back to help people that want to write exploits today to see some steps that we overlooked when we saw the stack overflow. Because stack overflow looks very simple. You just write bytes and you control the machine. So let's see what those are if you want to write exploits today. First you need to have a vulnerable software. You need to have access to that software so you can run your code again and again and again until you perfect your exploit to make it running well. Next we had a way to gather information. So on the also in case we knew the address of the stack. On the Matt Miller CVE we knew the system function addresses. Today you will need an arbitrary read vulnerability that will allow you to leak those addresses when you run your exploit. Next you need a way to manipulate memory. So stack overflow obviously you write the stack so you have a way to write into the memory. You have other ways to write into memory like heap overflow or use after free which sometimes allows you to do that. And if you want to write exploit today this kind of vulnerability is called arbitrary write. So if you have arbitrary read and arbitrary write you probably have a way to exploit the software. And the last step which I think is the most important to understand is that you don't actually write code to the target process you are trying to exploit. When you hijack the code execution it's actually a by-product of both writing memory into that process and the normal execution. So if you think about the red op code that simply jumps into the shell code from the Morris worm is the normal flow of execution of the program and we abuse that normal flow of execution to run our shell code. So now we're ready to play. So let's talk about return oriented programming or ROP. And the term was coined by Chovab Shacham on his article the geometry of innocent flesh on the bone which I think it's one of the most amazing titles someone can give. And the main idea behind it is to reuse existing code in memory and by leveraging the stack semantics. So let's understand how it works. In normal flow of execution when your program runs you the instruction pointer and the instructions control the flow of execution. So every time instruction is issued the instruction pointer automatically advances to the next instruction. So now you have the instructions running one after the other. On ROP the register that controls the execution is the stack pointer or the stack. So you are looking for a set of instructions that end with a ret. So now the instructions are running and when the ret op code is issued the next set of instruction will be fetched from the stack because that's the return address that over there. So now you're running another set of instructions that are followed by ret which fetches the next set of instructions. So now the stack pointer is controlling the execution or the stack. And luckily for us the stack is read write a memory which we can control if we have the proper vulnerability. Okay. So one of the most important terms on ROP is gadgets. And a gadget is a sequence of instructions that usually ends with a ret that allows you to perform logical operations. Let's say you can copy a value into memory. You can change the memory permission of a memory area into executable or load the values in the specific registers and many more. Let's see an example. If you want to write an assembly code that writes value into memory you will probably write this code. You will load the value into EAX, load the destination into ECX and then use the move op code to move the data from EAX into the destination of ECX. So we are working with the stack so we can replace the first two moves with popes. Let's see how it will work in ROP. So you have the stack on the middle and the memory and code on the right and the registers on the left. So we will start with the first set of instruction which is pop EAX. Now you pop that beef into EAX and the retop code will take us to the next set of instruction which is pop ECX. So now we pop the others we want to write to the 61230 and now the retop code will take you to the next set of instruction which is the move EAX into ECX. So now we are writing the dead beef into the others we wanted. Okay so most of the talks on ROP only mentioned 32 bits but we are on 2019 it's about time we will start talking about 64 bit ROPs. So the main difference between 32 and 64 bit ROPs is that when you pass the parameters for a function you need to load the first four parameters on RCX, RDX, R8, and R9. Next you need to allocate 32 bits on the stack you don't need to fill it with anything and lastly all the other parameters are passed similarly to 32 bits. How does it look like? Well if you want to call a 64 bit function to receive five parameters again it's a pseudocode you first push the first parameter to the stack now you load the first parameter into RCX the second into RDX the third into R8 and the fourth into R9. Next you need to allocate the 32 bits bytes and the call instruction works similar to 32 bit and pushes the return address on the stack so very similar to 32 bit and the example which we will see today will be 64 bit. So what do we do with ROP? Usually you would want to call either virtual protect or virtual alloc. Virtual protect allows you to change the protection of a memory address to executable so if you have the shell code already in memory you just need to change it into executable and jump to that address or you can also allocate using virtual alloc and executable memory and copy your shell code into that address and run it. Now because those two functions are the main targets of ROP the endpoint protection will actually monitor those functions and we will see later how they do it. So a lot of the time when you write ROP most of the time will be wasted looking for gadgets and I want to suggest you just to look at in NTDLL and there are a few reasons to do it. First NTDLL is loaded into every process on the system so you don't need to hope that the DLL you exploited before will be on that process because NTDLL is always there so if you find the gadgets on NTDLL you might be able to use those gadgets on every other exploit you will use and another thing that contributes to that is because NTDLL is so close to the kernel then a lot of the code on NTDLL is hand-readed written assembly and if you ever wrote assembly you know that you write it once and you don't touch it it just works. So now if you find a gadget that it's hand-readed assembly most of the chances that it works from the very early version of Windows sometimes even Windows Vista and gadgets I will show you works from at least Windows 7 and that's a lot of power if you can write your ROP once and use it on every other exploit you will ever need. So let's see some gadgets on NTDLL. So the first is the function RTL copy LUID and that function even doesn't look if you are copying LUID just copies 64 bytes from the destination you give from the source into the destination and how it looks like in assembly it simply loads the value from the source which is in RDX it's the second parameter into RX and copy that value into RCX which is the destination that you gave it but because we are writing the stack we don't need to write the return address to the beginning of that function we can skip three bytes directly into the second opcode and now we can we have the gadget that can move RX into the destination RCX. Now there is a similar gadget that exists throughout all versions of Windows the move RCX into the others in RX it's in the function RTL set extended feature mask and you can use it everywhere but now you need a way to load values into RX and RCX so how you do it? Well modern compilers are aware of thrope and will not emit pop-RX-RAT or pop-RCX-RAT in their code but what they do emit is like add RSP58X bytes which is just deallocating the stack for 58X bytes but apparently the byte 58 is pop-RX so if you skip three bytes into the middle of the opcode you get pop-RX-RAT and that opcode exist in a lot of time in NTDLL and very similarly if you're looking for pop-RXX you have the multiply XMM 0 with XMM 3 which allows you to skip two bytes and now you have pop-RXX-RAT so now we have a way to copy any value we want in memory. Next I want to show you another great gadget which is on NTDLL check stack again handwritten assembly and I should explain to you why because it first load the top of the stack into R10 then the next value into R11 then it simply deallocates the stack and returns and it's simply like writing pop-R10 pop-R11-RAT and how do I know that this is handwritten assembly because only if you read the Intel manual back then when Windows wrote their code you know that this was more efficient way to write it. So I didn't want to show you pop-R10 but if you skip just one byte you have pop-R-EDX so now you can load both RCX and EDX so you have two parameters you can pass through functions so that's thing you can start working with. Another very important gadget well obviously not pop-R12 it's the pop-RSP and this gadget is called the stack pointer, the stack pivot because sometimes when you have exploit you can only write a limited amount of bytes into the stack when you hijack the stack and this gadget allows you to write the whole rope into the heap or place where you can write a lot of code and simply pivot the stack into that address. So now you just need to write the return address into the stack pivot and you can have a rope as long as you want. Now one of the most powerful gadgets on NTDL is actually a function it's called anti-continue which gets two parameters and I can tell you that you can completely ignore the second parameter it doesn't do anything and context contains the process of specific register data which means you can actually replace all the values in all the registers of the currently running thread so now you can control not only RCX, RDX, R8, R10, R9 you can also control the stack pointer and the instruction pointer so that's very powerful gadget that you can use. Now the last gadget I want to show is RTL move memory when you want to copy a large amount of data between memory. Now I like to make analogies because it better explains things and I want to compare gadgets to the art technique called the ready-made. Okay so the ready-made technique was invented by a French artist called Marcel Duchamp and if you think the French people only contributed to the world by inventing I don't know like croissant, baguette, democracy and mimicats then they do they did some other stuff as well. So this is a this hard piece called fountain which is just urinal turned on its side and signed with his pseudo name Armut which Marcel Duchamp did and what he writes about it explains exactly I think what gadgets are all about. Whether Mr. Mat with his own hands made this the fountain or not has no importance. He chose it. He took an ordinary article of life and placed it so that its useful significance disappeared under the new title and point of view created a new thought for that object and if you think about it that's exactly what we are doing with gadgets and if you follow this train of thought well like the fountain is an art piece our little gadgets are little pieces of virtual arts. Sorry. So if you follow this train of thought and our gadgets are little pieces of art it actually makes NTDLL the public bathroom of Windows. Okay so with that thought in mind let's move on to Windows exploit mitigations. We'll stack with we'll start with stack canaries and stack canaries protect you against buffer overflow. It works by first generating a random base canary value whenever your process is started and then it writes a cookie into the stack using a calculation of that base value. Now when the return opcode is issued before the return opcode is actually executed it performs the reverse calculation and checks that the value we got is the base canary value. So now we can actually see if someone actually overridden the stack. And let's see a pseudocode how it works. So it first load the base canary value into ECX then it source the value with the stack pointer so now it's not only as an attacker you don't only need to guess the base canary value you should also guess the current stack pointer which is very hard and then you push the value into the stack. Now before the return opcode uh let's say an attacker actually managed to override the stack the uh opcode will pop the the canary stack from the canary value from the stack we'll sort it again and we'll call a function that verifies uh if the value was changed and because it did it will actually crash the process. Next mitigation I want to talk about is the Windows 8 Rop mitigation which is a very big name but it actually just detects uh stack pivots. So whenever you are calling uh memory functions on Windows starting for Windows 8 it will actually check that the stack pointer points to a valid location on the stack. So if you used uh stack pivot on your op well Windows will detect it and will crash the software. And now it's very easy to guess how you can bypass it. You simply need to make sure that the stack pointer points to a valid location on the stack when you are calling uh Windows uh 32 API. So how can you uh fetch the stack pointer value? Well you can abuse canary stack canaries. So for the first thing Technica will show you I call it a little bear told me and we will see how we can abuse using a Rop uh stack canary to fetch the value of uh RSP. And uh main steps we will take is we will first prepare the registers then we will call up a nine function that uses stack canary. We will fetch that value that cookie from the stack. You can treat it like a user read after free uh vulnerability. And then we will absorb that value with a base canary value. And if you remember before I told you that you need to have a memory read vulnerability. And if you have that memory read vulnerability you can actually fetch that base value from the DL you are calling. So we will assume that we have that value on the Rop already. So you have the code on the left on the top right you have the registers and on the bottom right you have the stack. So the stack is also split between the address on the left and the values on the right. So we will start with the pop gadget which will pop the values that we want we want to prepare the registers. The important registers we are preparing now are R6 and R9. R6 is a parameter for the function we are calling and R9 you will see later what it is used for. And now the red will take us to the next uh function which is RTL is valid process trust label SID. What it does I don't even care. The only thing I care about is that it uses stack canaries and it doesn't mess up with the uh uh registers or the uh or the stack itself. So first this function allocates place on the stack. Next it fetches the base canary value into REX you can see it over there. Now it will absorb the value with the stack pointer. So this is the uh the stack uh cookie we are using. And later it saves that value into the stack so you can see the same value on REX we can find it now on the stack. Now because we passed the parameter to the function we passed the bad parameter and the function was uh start to go into the ex into the exit uh sequence. So now right before calling the retop code it fetches the value the stack uh cookie from the stack into R6. Now it will absorb it with the stack pointer. So now we have the base canary value and it called the functions that check the cookie. And because we are innocent we didn't do anything wrong here we're just calling a function. Well that function will pass correctly. And now before I execute this I need to remind you that the uh canary cookie is still on the stack. So we are reallocating the stack but actually the stack memory is like a memory in any other place on the computer. So if anyone if no one rewritten or overwritten that value that value is still there. So now we will jump to a special uh gadget that will allow us to fetch that value. And that gadget is in RTLP execute handler for exception. Again all the gadgets you are seeing here are from NTDLL and this is handwritten assembly. And you can guess it's used for exception handling but this gadget actually allocates space on the stack. And now it calls. You can see that uh now we have the cookie on the stack on our stack uh value. And now it will call a pointer that is controlled by R9. So if remember the first gadget we use we popped R9 to control the value. So can you guess where we are going with this uh now? What gadget we will use? Well we're going to the same uh pop gadget that we used before. So now we are popping values from the stack. And the important thing is that now R9 will receive the canary uh cookie. So now we have the cookie on R9. All we need to do is to fetch the base canary value and explore it. So now the retop code you can see it will take up to the next uh gadget the pop rx you know that one. This will fetch the base canary value into rx. And the retop code will take us to the last uh gadget which is XOR R9 with rx. And this is part of RTL decode system pointer and another function on NTDLL. And now we have the stack pointer. And we can pivot from here. And continue our uh rope. Okay. So now for the next mitigation we will talk about uh control control flow guard or CFG. And the idea behind it is to mitigate uh control flow hijacking of indirect calls. What are indirect calls? Let's say you're writing cpp code and uh compiler needs to fetch the address of the function from the virtual tie table. So it will write, will emit code which look like this. It fetches the address uh of the part of the function into rx. Then loads the parameter rcx, rdx and r9, r8 for like three parameters for this function. And we'll call rx. So CFG actually replaces uh rx uh wait I'll take a step back. If you are an attacker you can actually hijack the value that will be saving to rx and then you can call any function you want or any place in memory you want. So control flow guard actually replaces the control rx with a call to guard dispatch uh I call the fptr. Uh sometimes it's just a check and there is another call rx uh rx later. It depends on implementation. But actually this function will check that rx is valid. Function and no one overwritten it. How it does it? It uses a huge uh bit field where every bit marks uh if a function starts at a specific address in memory. So it's a coarse grain. It doesn't know if those are the functions you actually wanted to call. But uh if there is a function starting there and it doesn't matter what what the LL it is it will say that it's valid. What it gives us it's that uh you won't be able to call in the middle of function and then uh mess with the stack uh the stack itself. So now comes the questions. How can we abuse CFG? Well we already did. Do you remember uh I told you that uh uh CFG replaces the call with a call guard uh dispatch cycle FPTR? Well actually that function translates into NTDLL functions called LT LT L LDRP validate user call target. And that function checks the bit field you can see it and uh down below you can see that if it finds that there is no function over there it jumps into LDRP value uh handle invalid user call target. And if this name sounds familiar because that's the pop gadget we just used. So thank you Microsoft for introducing one of the best gadgets for ops uh out there and making it available in every ad every goddamn process on the system. Uh now I need to ask sorry for all the people exploiting this because if Microsoft is watching this they probably take it away from us. But wait there is more. If you will look at them at the MSDN you will see there is a uh uh a function called set process valid call targets and this function actually allows you to tell CFG what addresses are valid. So let's say if you can potentially exploit uh uh indirect call twice you can first call set process valid call target set the target you want as a valid target then call it again. So what do you think? Do you think Microsoft actually protect a valid uh uh function that is published on MSDN? Well apparently they do. So nice one Microsoft but not that nice because if you look at set process valid call targets it's actually a wrapper around an NTDLL function called anti set information virtual memory and you know what? Anti set virtual uh set information virtual memory is actually valid call indirect call target. So you can call this function tell Windows that it's a valid target and then abuse the same uh exploit again to run whatever uh function you want or whatever others you want. It's actually like telling Windows those are not the experts you are looking for and you know the force is powerful and the weak minded. Okay so let's talk about rope mitigations. And we will talk about first about Rob Guard which is the uh mitigation that is implemented by most endpoint security today or at least a variation of it. And it uses strategic hooks on a memory function like I told you before on the virtual protect virtual alloc uh all the matching NTDLL functions and all functions that allow you to create processes. And what it does it fetches the return address from the stack and look at uh opcode preceding it to see if there is a call uh to that uh function. And if there is no call opcode before the return address then how did this return address go to the stack? Now it doesn't only check that there is a call it also checks that the call opcode actually uh calls the function that we are hooking. So that's the Rob Guard in general. It does have uh some more tricks uh to do but most of them simply checks that there is a call opcode. Now KBouncer is like Rob Guard uh on steroids if you would like. It's actually utilizes uh feature on CPU called DEST branch share records which saves the DEST indirect uh jumps or calls you had. So you have uh the source and the target address and you can actually perform similar checks to Rob Guard on those addresses too. So if you can think about it Rob Guard actually checks that the return address which is the future of execution. KBouncer also checks the past of the execution that was that already happened. Now I know that there are a few, very few uh vendors that uh implemented KBouncer but most of them only implemented Rob Guard. Now another mitigation is a Rob Pecker which I haven't seen implemented anywhere. And uh the idea behind it is to use the same mechanism as uh DEP that execution prevented prevention to mark all the memory as non executable except except for the current uh executing page and the next one. So now whenever the execution jumps outside of that uh area there will be exception phone and Rob Pecker will catch this exception and will perform similar checks to uh KBouncer. But uh because it happens a lot the uh heuristic that it use are a lot weaker than uh KBouncer. Now the last mitigation I want to mention is ShadowStack which is uh collaboration between Microsoft and Intel. It was first proposed on 2016 but it was never implemented. Uh they suggest to use two different stack. One the regular stack that you have and we all know about and another matching kernel stack that only saves the return address. So whenever there is a call up code the return address is pushed both to the user mode stack and the kernel stack and when there is a red it will be both addresses and if the addresses are uh incorrect well then you know that uh someone overwritten the stack. Uh but as I said before uh it was proposed on 2016. There is no implementation of it anywhere at the time no off. And let's see how you can bypass it. So before I will tell you my method I want to suggest you a paper to read or a black hat talk to to watch which is called The Beasties in Your Memory by Daniel Lehman and Ahmed Rizadeghi. And they explain how you can bypass uh Rob Pecker KBouncer uh by abusing their heuristic and if you think about it when they say they're abusing their heuristic they actually uh have an intention of being caught. And I don't like being caught. So this is why I invented uh a new technique called write of passage which allows you to bypass uh the route mitigations without even being caught or without going through any of the endpoint securities uh hooks. So we collected a lot of bricks so far and there is still one more brick we need to collect to understand how we can completely break windows. And this one is the system code. So syscall is the way uh you transition from user mode to kernel mode and whenever you call uh virtual protect or virtual alloc or any other Win32 uh function it usually translates into a system called function inside NTDLL. Again, handwritten assembly. So all of those functions will look very similar to uh anti allocate virtual memory. It first moves the first parameter from RCX and saves it into R10. Next, it loads the system code parameter into EAX and on the case of anti allocate virtual memory I think it's Windows 10. The value will be 18 hex. Uh let's say for anti virtual uh anti protect virtual memory that will be 50 hex. So every function has a different uh number. Next, it issues the syscall uh command and the syscall uh actually is actually the opcode that transition into kernel mode but it always goes to the same function in kernel. So how does this function know which function you want to run? Well it looks at EAX. So now it knows that because EAX is loaded with 18, it in hex you want to run anti allocate virtual memory. Now when a function finishes on the kernel it will return to uh user mode and the function will continue. So as I said before all the endpoint protection usually hook those function. So now you have a hook on the function and if your rope goes through that uh function it will go through the endpoint hook. Some vendors even go as far as override the whole function so you will not even know that it's there that know why they should do it. But you know what? They don't hook all function. Let's say anti yield execution which is actually a function uh that does nothing. It's like the insecure function of a program if you want. It just tells Windows well I don't know if I have anything important to do right now. Maybe you decide if I need to continue execution or someone else do the execution. It's a function that is no, has no interest to anyone. Maybe for us. But uh another thing that you can see how do I know that this is handwritten assembly or a macro that just copies the same values everywhere. It's because anti yield execution doesn't get any parameter. So why do you need to pass RCX on the R10 if RCX holds no valuable data? Well that's handwritten assembly. But we can actually abuse anti yield execution or any other function on the LL which is not hooked for our cause. And how do we do it? Well we will start with a proper AX uh rate gadget that loads the system call into our AX. Next we'll use another gadget that you've seen before that allows us to load R10. So now we can also prepare the first parameter. And next we will not call anti yield execution. We will jump 18 bytes directly into the system call. And now if you look at it we actually have a way to issue any system call we want using a rope. And because we don't pass through any of the endpoint protection hooks no one even know that our rope was there and no one will ever catch us. So I wrote a little tool which I will publish on my git later. Uh it's called the rope injector injector which uh first allocates a read write memory into the target process. Uh it writes the shell code into that process. Then it will create a new thread on that process and injects the rope into that process using uh uh get process uh uh get process context and set thread context and set thread context. And lastly the rope will modify that that uh area into read write execute using either regular call to virtual protect or a write of passage call to anti protect virtual memory. And lastly it will run the shell code. So let's see how it works. Okay so so I want to change things a bit. So I will not proper uh calculator with my demo. I will actually inject a rope into calc with my demo. So you need to pass the process ID to the rope injector. So now we will pass the process ID of the calculator. And we are injecting a regular rope and you can see that our shell code injected the the created a mutex called PON. So obviously it worked. Now I will tell you a little secret endpoint protection, don't protect all process on your system. They usually protect only the vulnerable like Firefox. So now when you try to inject you can see that the endpoint protection caught the rope. So now we'll try to run Firefox again and we will use the write of passage rope uh instead of the regular rope. And the endpoint point the endpoint protection didn't even see it coming. Or see it that it even happened. Okay. Okay so thank you. You all behaved very, okay you behaved very nicely so I have a little surprise for you. I have a mini talk. Okay so welcome to the mini talk. Exploiting a Windows exploit for mitigating write of passage exploit. So at the beginning I thought maybe I will show you like the blue pill and how to write a hypervisor to protect against uh write of passage but last month there was a research by Nick Peterson. He called it infinity hook which exploits the Windows even tracing mechanism to hook system calls on the kernel. So what Nick find out is that there is a struct in the kernel that every uh event log saves which has a function pointer that needs to save the timing of the uh the event that occurred. And he found out that you can actually replace that function pointer with your function pointer uh to your function. Now you have a way to get notification every time a system call was issued. So now we can hijack system calls. So obviously Microsoft responded that this is not a security boundary so I thought why not make it a security boundary. Yeah. So now every time there is a system call we can actually check what is the return address and check that the system call matches the same function that this uh function came from. And if it doesn't match well we actually caught the write of passage bypass and it actually catches a lot of more kind of uh uh exploitations not only that. So you can find uh Nick's work on Github. And okay so takeaways. First have fun. I mean even though Microsoft tries to make our life uh harder we can still enjoy it and do fun stuff with it. And we need to remember that Rope remains a viable threat even 30 years after its first uh its first incarnation. And as a security industry we need to respond faster to those uh threats. And I want to suggest we can utilize the brains on academy uh to do that. A lot of the research on Rope came from the academy and also the research about how to how to bypass the Rope mitigations. And there are a lot of great minds there that we can use. So let's do that. And lastly break it to make it better. Okay. Thank you very much. So I think we have about 10 minutes for Q&A. Five minutes. Okay I can't see anyone. Yes. Okay so the question was how much of the mitigation are transferable to the Linux world. So first I would say I'm not a Linux guy. I'm a Windows guy. Uh but I think uh Rope Guard uh is transferable. KBouncer is also transferable. Ropepecker I don't know how Linux manages the memory of the processes but I think it's also will be transferable. And uh I think also ShadowStack can be uh transferable too. So maybe all of them it might need a little tweaks from the Linux side. Okay any more questions? Okay so thank you very much.