 memory deduplication is widely applied to reduce memory consumption. Today, we are going to see three attack techniques that exploit memory deduplication. We have two incredible security researchers here with us today. That will show us how these attack works. To the left, I have Antonio Barresi, and to my right is Eric Bosman. They will then use the chance to also introduce themselves. Please help me welcome Antonio and Eric. Good morning, everyone. This is memory deduplication, a curse that keeps on giving. Unfortunately, it's just Eric and me, so Ben and Kave couldn't make it. But they say hi, and I just want to say that the credit goes also to them, so we prepared the talk together, and a big part of the content comes from them. So Eric, as he was introduced, he is a PhD student at the FUSEC, Networks and Systems Security Research Group in Amsterdam. So if you want to see what they do, go to the website, fusec.net. I'm Antonio, I'm co-founder of ExorLab Swiss IT Security Company in Zurich. So the work that we're going to present, actually, there were a lot of other people working on that, and here are some acknowledgments. Yeah, so let's start. So the message today is actually quite simple and straightforward. Memory deduplication is much more dangerous that you might possibly think in the beginning. So it comes along like a nice little feature that helps you save memory, but we're going to show you that it's actually dangerous and much more severe. And we're going to do that by showing you three attack techniques that all exploit memory deduplication one or another way. Before we do that, we'll look at memory deduplication so everyone knows what it is. We're going to show you the site channel that gets introduced by it. And then we start with the three attacks. So first, we have Cain. Cain is a cross VM leak attack which basically allows you to leak base addresses or other secrets with higher entropy from other VMs. And we applied it to ASLR because we thought it's an interesting case. And it only relies on memory deduplication. We'll then show you dedup as Makina. This is a attack against a process. And actually it got the Pony Award at this year's black cat for most innovative research. And it relies on memory deduplication and row hammer. And basically it allows you to read and write through JavaScript in edge without any soft vulnerability. And then we're going to present Flip Feng Shui. Flip Feng Shui is a cross VM bit flip attack. So basically imagine you could flip a bit in another VM. And the only requirement is you have to know the content of the page, of any page. So how would you actually compromise that system? So we're going to show you, so first of all, how you can bit flip precisely. And then we're going to show you two techniques to actually compromise the system with that bit flip. After that, we will conclude. So let's start with memory deduplication. So memory deduplication is a method to reduce memory consumption. And it's usually used in a virtualized environment but not exclusively. And it was also enabled. And the emphasis is on was in Windows 8.1 and 10. So the idea is that in virtualized environments, for example, the virtual machine monitor will try to be quite a resource or try to save memory. So basically it will over commit certain resources like memory and memory deduplication is a technique to reclaim certain pages in a clever way. Or easily speaking, run more VMs. So basically it's a nice feature, right? The idea is you can just have more VMs on the same hardware but you'll see that it has certain implications. So let's look at how it works. So basically, this is an example. You see memory pages of two virtual machines and the physical memory of the hardware. So let's say you have the picture of the Mona Lisa or a same process running, so the same code pages or something else, some data. So basically, in a normal scenario, you will have both address spaces filled up with these pages and all consume one physical page. So when memory deduplication is enabled, the memory deduplication implementation will try to identify these duplicates and then it will merge them so that the blue space gets free again. And it will mark these pages with a copy on write semantics which basically means if someone writes to it, it has to do something else. It's not going to work. Now, one implementation is kernel same page merging with KVM. I'm sure most of you know that. So if you have Ubuntu server or Ubuntu system, usually that's I think even now enabled by default. And you can check it. So there is like the run file under the sys file system where you see if there is a one there, it's enabled. And then there are certain parameters that allow you to define how fast the memory deduplication should work. And there are other implementation as well. So the problem with memory deduplication on most implementations is that it doesn't respect the security domain. And so basically, even between two different VMs or if it's done for processes, if you have two different processes, you cannot trust each other. But it still works across these boundaries. And actually that's the dilemma of memory deduplication because in the end you want to save memory and it makes a lot of sense, right? If you have a lot of VMs running the same operating system. So it makes sense to cross these boundaries. But the problem is it introduces a site channel. So let's look at the site channel. So if you have a page that belongs to you, you'll just write to it and that's it, okay? So the problem is if you have memory deduplication, you have copy and write. So now if you write to it, you need to go to the kernel. The page has to be duplicated again. Test out the page tables and then resume the process again and then you basically can write to that page. So you'll see that there are a lot of more steps involved here. And this introduces a one-bit site channel that allows you to see basically if such a page exists in another process or in another VM. It works across VM if it's implemented in the virtual machine monitor across process or as we will see, we will see one instance of that attack even within a process. You have different security boundaries. Think about your JavaScript code, right? So it might be interesting for your JavaScript code in a browser to find out certain things. So let's look at the attacker perspective now. So what does an attacker have to do to exploit that? So basically here, the attacker has his memory. This might be a VM or a process and then there is the victim. So there is a secret page that basically knowing that that page exists might help the attacker in one or another way. So what the attacker has to do is the attacker has to guess a page. So in that case, he really has to guess the content of that page. The attacker has to wait a certain amount of time, write to it, so modify his copy of the page. So this is totally legitimate. You don't need more privileges, right? Measure the time and then see if the right time is above a certain threshold. The attacker can deduce that page existed in the other VM, for example. And if the right time is below a certain threshold, the attacker can deduce that didn't exist there. Okay, so let's look at the first attack, Kain. So Kain is cross VM address based layout in Prospection. I actually regret already the long name every time I have to say it and basically only relies on deduplication. And the idea is to use that to break ASLR. So basically you have a VM that runs next to you, memory data application is enabled, and you will be able to find out what the base address, for example, of NTDLL is in the other VM. So let's recap what you have to do as an attacker. So first you need a secret page that allows you to deduce interesting information. And in our case, it's the ASLR base address of a certain DLL, for example. So the question here is, what page should we use? Then of course, there are certain practical challenges. So how long should you actually wait for, because you'd have no idea how fast the memory data application scheme is. And then in the end, you have to practically detect that it was merged. So you can measure right time, but you'll see that in practice, there is also noise involved. So sometimes right time is higher and it's not because of memory data application. So we looked at the suitable pages to break ASLR, and I mean, certain straightforward criteria are, you have to know as an attacker that the page exists in another VM. It has to be read only ideally in the VM because if it changes too often, then it will not be deduplicated. And it has to be page-aligned, so you really need to know the content mostly of that page. And then if you wanna break ASLR, you need ideally a page that has a base address in there, so basically the green part is totally predictable for an attacker, and the only thing that the attacker doesn't know is the base address. Or another possible page would be a page that actually has different values that were derived from a base address, from the secret that you're interested in. And the other thing you have to know is also the offsets of these secrets within the page. So we were looking for certain pages and we are sure there are much more, but luckily when we were looking at the first page of every executable PE image in memory, you'll already have a hit. So if you look at the PE file format, it looks like on the left for an image on disk. So there is an image base field there which basically gets updated with the runtime base address in memory. And this is exactly what we need. We can predict into all other bytes except for the base address where it has 19 bits of entropy. And there are of course other pages that fulfill that criteria, but we thought, I mean, why should we look further if you already have one? So we use that page in the POC then. So now the problem is you have this page, you can basically ask that memory data application side channel if that exists or not, but the problem is you still have to guess the base address, so you have 19 bits of entropy. So 19 bits of entropy in X64 windows is used for the base address of DLL for example. So as you need one page per, I guess, it's more than 500,000 pages that you will need, right? So if you will do that after each other, basically it will take you a lot of time. But of course we can just brute force it, right? So we can use much more memory, all the memory that the attacker actually has, right? So the attacker has much more memory. You can assume that usually you have maybe, you have a different VM2 for even more gigabytes. So you can just fill out the entire memory that is at our disposal with all the guesses. And in case of 19 bits of entropy and one page per guess, it's two gigabytes, which actually is okay. So what you do is you have these pages and then you allocate them and then you try to detect it. And it's a classical brute force attack on that memory need application side channel. So the other challenge that we had, the practical one is how long should we wait? Of course we could just wait like hours, right? And at some point it would work. But it depends, so we want it to be a bit better. So in the end it depends on the memory need application implementation. So how fast is it? So you've seen the parameters for KSM. So depending on the parameters, it might be faster or slower. But it also depends on the memory usage. So if you have a lot of VMs running, in the end you'll have to compare all the pages to each other. So you have to go through all the pages. And if you assume the worst case, then your guess page will be compared with the secret page at the latest point in time. So there is a trade-off for the attacker. So if the attacker waits too little, then the attack will just not work. But if the attacker waits too long, then the attack time increases. And that's also not favorable for the attacker. So what we came up with is a detection mechanism to detect this memory need application. Basically, the time you'll have to wait till you have certain guarantees that your page was compared with another one. We call it sleep time detection. And the idea is, as an attacker, you can just allocate a lot of random bytes and a lot of pages. And then you copy every second page of the half of your buffer to the other half of the buffer. So what you create is basically the situation like on the slide where you have a lot of merging opportunities. So you basically give the memory need application scheme a lot of work. You create a lot of pages that can be deduplicated. And then you wait a certain amount of time, like 10 minutes. Try to detect how many of these pages were merged by doing your detection magic. And then if the detection is above a certain threshold, you say that's the right time. So you use it in your attacks. And if not, you just increase T and then you try again. So the last practical challenge is how do you actually detect that the page was merged? And what you have to do is, I mean, you have to write to it and you have to measure the right time, right? So what we did is we, every time we have a guest page, so that's the orange one, the merged one, we have pages, adjacent pages that are for sure not merged. And we know that because we can just fill it up with random bytes, okay? So you create the buffer in such a way. And then you just write to it and you measure the cycles. And then you basically see this signal. Now, of course, there might be noise. So we developed certain heuristics. We didn't invest that much time to do that, but the ones you see there work pretty well. And that was fine for us. Works for me. So now the last question is how to handle noise, right? So we just implemented it in a quite conservative way because there is actually no harm if you have certain pages or certain false positives. So what we did is we implemented a round space system where you try to detect it, then you do it again with the guesses that might be potentially correct. And you do it over and over again. And in the end, as the noise will not affect the same guess all the time, it will work. But it might take certain rounds. So I'll show you some results for Windows attack. So we implemented it to attack, to basically leak the NTDLL base address of a neighboring Windows 64-bit system. So if you look at the entropy, you see basically for data, it's quite high. So that approach wouldn't work that easily. At least not if you have no control over how the secret is aligned. So basically for DLS, we have 19 bits of entropy. And if you have the base address of one NTDLL, you basically can use it in your exploits for all the other processes because it's usually not re-randomized. So we did it with a standard KVM KSM configuration with Sleeps Millisex 200, that's default. And basically you see when we attack one single VM, it took us a bit less than five hours to basically do that. And we had like some rounds till we reduced entropy from 19 bits to the actual base address. We also wanted to show that it works with multiple VMs. So we speeded up the memory need application by having Sleeps Millisex 20. And there you see, even if you have more victim VMs, it works, it just takes more time because the sleep time detection will tell you to wait more because you have more memory that is used. So in the end, how it looks like, so we have a video demo, but we don't have that much time. So I'll just show you the screenshot. We have a demo for another attack later. Basically, here you have the attacker VM and on the right you have the victim VM and you do your magic, you allocate these pages, you measure write times and so on. And in the end, you just have the base address of the NTDLL in the other VM, that's it. So the attack is rather slow, I would say, but there were a lot of speed improvements that we didn't actually follow up with. But one way would be to have more random pages in between so that the noise will not affect your guests or the probability is lower, that happens. And the other thing is you can also use more than one guest page, right? So have redundancy already, because you might have, for example, relocated code pages that all have that secret. So you can just use many of them, right? The only thing is you cannot use the same page because if you have it two times with the same guest, then you create this merging opportunity and you have a false positive. So you need different pages that all have the same uncertainty or the same secret. Now, Cain is, I would say, a cool attack, but the problem is it's still quite limited. So one problem is we don't have any control over the victim memory, right? So we really have to rely on how these pages are, what the layout of these pages are and also where the secret actually is. And we need to find these pages. So there is no control, but some control would actually help a lot. So we didn't really investigate at how we can do that cross VM. And then, of course, it's a leak, right? So you still need a vulnerability to exploit the base address, for example, the secret that you got, if that's not enough. But last year, I mean, there was a lot of, there were a lot of talks and a lot of publications about Rowhammer, even here at the Congress, Clementine and Daniel presented Rowhammer.js. So basically they showed that it's possible in JavaScript. So let's say we were optimistic that we could do more. And then Microsoft basically enabled memory deduplication or we noticed for Windows 8.1 and 10, cross process, but it's disabled again. So it's not enabled anymore. But let's say it would have been cool, but it didn't go that well. So for the next attack, we call data-based Makina. We tried to take it a step further. So in this attack, we're going to combine deduplication as a side channel attack with Rowhammer in order to exploit Microsoft Edge, Microsoft's new browser from JavaScript without making use of any software bugs. Or well, if you consider, if you don't consider deduplication a software bug. So we're going to leak two secrets and we're going to use deduplication to do this. The first secret is a heap pointer. It's a location to data we control. And the second secret is a code pointer. And those two secrets are needed to together create a fake object in our memory. But then we have a problem because, and this fake object will allow us to do arbitrary reads and arbitrary writes in memory. But we have a problem, JavaScript of course doesn't allow us to create references to this fake object, it's just in data. So we will use Rowhammer to flip a bit in a pointer and point this pointer to our fake object. And then we are basically, we can take over the process. So in contrast to Cain, in this attack, we won't only be probing for existing pages in memory, we will assume that we can manipulate the data of the victim in some way. And this is not really unlikely. If you think about it, every time you do IO to something you want to attack, then you're manipulating memory in this process. And in this case it's from JavaScript, so it's even more easy. And this allows us to not only probe for secrets that just happen to be in pages that we can leak, but we can craft memory pages that just contain the secrets that we want to leak. So it's quite a bit more powerful. But still there are some problems with this. The secret that we want to leak might not be somewhere. The secret we want to leak is probably somewhere in a page which contains other information that we don't know and then we cannot craft a page to leak the secret. So we need to find a way to kind of encode the secrets into a memory page. So I said that we can retrieve the secret again. So the secret, the memory page that we want to leak should contain only the secret and data known to us. So this could be that because this data was written by us into the outer space of the victim or it's just data that we know, data that we know the contents of in some way. And there's a second problem. We might want to leak a secret which has too much entropy, so much entropy that we cannot possibly brute force the whole, all the possible secrets. And for this, we have found some ways to get around this and leak secrets iteratively. The first method we tried was we call alignment probing. In this case, we manipulate the victim into creating a memory page or putting the secret somewhere across memory page boundaries. In this way, we can only put it into the memory page we can partially leak the secret in one round and then we have to get the victim to create a memory page with a slightly more of the secret in one page and so on and so on and we leak the whole secret. The second primitive we tried was we call partial reuse where we assume that the victim has a secret somewhere and then we write data, for example, in a buffer that was previously used to store the secret and then we write data in this buffer and overwrite only part of the secret and then again the entropy, again such that the entropy is low enough to leak it. And the first of these two primitive alignment probing is what we're going to use to leak the code address in this case and we're going to make use of Microsoft Edge's JIT compiler. So every modern browser has a JIT compiler compiling JavaScript to native code and for every chunk that's translated in Microsoft Edge the function epilogue, so the last part of the translated code is always looks the same except for one thing, namely a code address. And what we did was create lots of JavaScript functions which are just too big to fit into one memory page such that the code address spans multiple pages and then well normally the code address is 19 bits so it would need two gigabytes of memory. In this case we need only 16, I believe. And yeah, so in this way, in one sweep we can leak part of the address and in the second sweep we can leak the complete value. So now we have a code pointer but we still need to leak a heap pointer and there's a problem with this. We didn't find a situation where we could leak the heap pointer directly using the two primitives before and the heap pointer has quite a lot of entropy. So this is an example of a heap pointer in Microsoft Edge. There is some advertised randomness on Windows 10, 24 bits of randomness and if we only look at that part we'd need 64 gigabytes of memory just to try every possibility and then we need to multiply this by a bit to get redundancy because there's noise. But if we look at how a pointer actually looks like there's also some kind of lots of non-determinism which actually increases the entropy of the pointer quite a bit and yeah, we don't have hundreds of terabytes of memory to probe. So we needed to find something else. We could improve this a bit. We found another side channel so if you allocate lots of arrays then every one megabyte the browser will ask the operating system for an extra megabyte of memory and then the first object that fits into the new allocated one megabyte it will take longer to allocate and that's something you can detect. So then we have a timing side channel and then we can reduce entropy to 20 bits but we'd only already need at least four gigabytes of memory so that's also not nearly good enough. So we had to find something else. Well, luckily we found something else. Something very much like, the intuition is very much like that of the birthday problem which in a surprisingly small group of people the chances of two people sharing the same birthday is actually becomes pretty high more than you would naively think faster than you would think naively and the intuition behind this is that you're not comparing one person's birthday with a group of other people. With other people you're actually comparing everybody's birthday with everybody else's birthday and when you think about it this is exactly what memory duplication routine does as well. It compares every page with every other page. So how can we exploit this in practice? Well, we're going to assume that we don't have one secret to leak but lots of secrets and then we have lots of guesses and then there's a, yeah, you compare every guess with every secret and then you get, yeah, you need way less memory. So in practice the victim has secrets and then you kind of need this you don't need as many different guesses to actually get the match. So how do we exploit this in practice? Well, we allocate lots of objects and then we get, due to the other side channel we get a list of objects which are probably on a megabyte boundary and then we allocate the large array which of course is in practice just memory pages and then we put a reference to or a pointer to each object in this array. So, and then there's one pointer per memory page. So these memory pages kind of encode the addresses of the objects and those pages we're going to probe for and then on the other end we're using a typed array which allows us to completely control the binary contents of memory and then we're going to create references to objects which are 128 megabytes apart and then recreate the contents of the pages the contents of the, how they would look like if they were in the array. So you can see the secret pages are close together and one megabyte apart and then the pro pages range across the entire address, the possible address space that Edge might possibly use and then in the middle there's a hit and then we get our heap address belonging to an object where we control the data. So now we have the all the information to create a fake object. Now we're going to use Rohammer to create a reference to this object to allow us to use it. So the object is a typed array, the fake object that we make which allows us to basically control, yeah read and write the entire address space. So this typed array object, this fake object we recreate in a JavaScript array that we know the address of and then the next JavaScript array as a pointer to it and then we recreate it in such a way that if we flip a bit, the pointer will point to our object instead of the array and for this we're going to use the Rohammer attack. Yes, like Antonio said last year, some of you might have seen the Rohammer.js talk. We were able to reproduce their findings and on Windows 10 and use it for a tech. In the Rohammer attack, the problem is that DDR memory uses capacitors to store data and when you read it, the capacitors are drained. So yeah, these capacitors are stored in rows and then because they are drained, there has to be some kind of cache which doesn't lose its value. Which is static RAM buffer but it's only a limited amount of memory. So when the memory controller needs to read a different row, the data has to be written back to these capacitors and a different row is read to the buffer cache. The problem is that this creates some interference and if you did this in quick succession at specific locations, then and then after a while, some bits may flip in neighboring rows and that's what we use to flip a bit in a pointer allowing us to get a reference to this object and basically taking control of over the process. So that's the second attack. In the third attack, what you call flip function, we actually are also using Rohammer in combination with deduplication but in a different way, we won't be using deduplication as a software side channel anymore but we will be using it to make Rohammer a more useful expectation primitive. And our target will be one, yes, so in our attack, an attacker will be in control of one virtual machine and we'll take over another virtual machine on the same system. So like I said, Rohammer is a very powerful attack but it's also quite difficult to exploit because you can corrupt bits but it's not really, you don't really control which physical bits in memory are vulnerable to it. And if you can flip bits, you have to, the data that's being corrupted has to be useful to you. So you kind of have a problem of getting the right data into the right location for you to exploit. So it's unpredictable in which physical page the flip will happen and it's unpredictable in which location in this page it might happen. A flip function can solve the first part for you so given that you can flip a bit in some location in the page, a flip function will give you the ability to get an arbitrary page you know the victim has and put it in the location where you can flip the bit. Another thing to mention is that with Rohammer, if you discover you can flip a bit somewhere, it's very likely you can flip it again and again and again and again. Yeah, so we're going to look for pages that we want to, in the victim, that we want to flip and then make sure that these pages are put into a location where we can flip these bits. So we thought memory depletion is a kind of an attractive way of doing this we thought and we're working on the Windows 10 attack and we thought well what if we, yeah so if we do Rohammer find a bit flip, what if we find a page where we want to flip a bit, we just replicate the same content of this page and then wait for Windows to merge them and then hope our page would be the location it would merge to but sadly enough on Windows, Windows allocates a new page and points the old locations to the new location. However, we found that on Linux with kernel page merging, it didn't so and it had some other things that are advantageous to us. For example, Linux tries to give consecutive physical memory to virtual machine hosts for efficiency sake, so which makes it easier for us to do Rohammer and find bit flips and also makes it easier for us to make sure that these bit flips are not too much make sure that these bit flips occur in our own memory and not in someone else's memory which yeah we wouldn't want to corrupt a system before we can exploit it of course, crash the system before we can exploit it. So once we know we can flip a bit that's useful to us, we replicate the content and then wait for KSM to merge memory and we can know in a deterministic way whether KSM will merge it to our page and then we do Rohammer again and then we can exploit the target victim. So one example how we did this was by attacking the authorized keys file. Authorized keys files usually contain public keys and these public keys are not supposed to, yeah, they don't have to be kept secret. I bet lots of you have probably uploaded their public key to GitHub and their public, so. And what we see here is in yellow we see the, so this is an RSA public key and in yellow we see the RSA modulus base 64 encoded. Of course we're not supposed to factorize this modulus because then we can get the private key but in red here we have characters which contain at least one bit that when flipped will remain base 64 encoded but we're able to factorize the modulus within one minute. So that's what we did. Flip a bit in the modulus, factorize it and then reconstruct the private key and log in. We have a second example where we target GPG and up get to exploit the updates mechanism in WN or Ubuntu. So this is a two-stage attack where we first correct the sources.list file to redirect the updates repository to a domain name we control and we also corrupt a bit in the GPG key ring to corrupt the sign in key to a key that we can reconstruct and then we can backdoor and then we can backdoor packages being installed. So we have a demo for this as well. First, so this attack. So what you see here is a machine running both an attacker virtual machine and a victim virtual machine in the top right corner. There's the victim, well, in a minute. So top left there are some debug information. The bottom part is the access log of a HTTP update repository server that we control and the middle part is used to create a fake package. So now nothing happened yet and up get update is run. So this is all fine, but now we're going to flip a bit in the sources.list file and then when we do get update again, there will be an error because now it will connect to our repository. Of course, this step doesn't have to be done, but it's just to show that it now connects to the first to our repository. Well, then we have to wait for a while to find a bit that we can exploit to corrupt the GPG key and when we have done this, we can reconstruct the private key and create a new package with the new signing key, creating a new package. And then when the update upgrade is run, first we do a less still okay, but then after the update, our code is run. So in conclusion, I think, yeah, I hope that we hope to have convinced you that memory duplication can be dangerous. If you're thinking about deploying it, we'd like you to think again and think again and think again and then maybe conclude. Well, maybe let's just disable it. Thank you very much. So we have time for questions. If you do have questions, please come forward to one of those four microphones. Does the internet have a question? None. No question right now, okay. We have a question on the microphone on my left side in the front, please. Please speak loudly into the microphones so we can hear you while people are leaving. I would like to ask, how does this apply for large pages? So I think in all your examples, you had small pages for eight kilobytes, so how does this apply to two megabyte pages, for example? Yeah, so kernel same-page merging employs large pages, but actually, sadly, it was good for us, but sadly, the kernel same-page merging prioritizes merging over huge pages. So actually, we create huge pages at the start and to do the row hammer part. That's the consecutive memory thing, but when kernel same-page merging finds a page which is identical inside this huge page, it will break up the huge page and merge anyway. So that's actually the worst case scenario. Okay, I see, thank you. Great, thank you. Then the next question would be right behind you. Yeah, thank you. Yes, about the process of deduplication itself, does it use hashes or other things to actually speed up the comparing or some hardware acceleration maybe even, or what's just the cache and the timing before impacts of that process running on the background? Yes, so we didn't do research on latency, but I think it does use some form of hashing both on Linux and Windows. Yes, and the next question, please, and well, before you ask the question, could you please ask the audience to remain quiet at this point? Thank you. So these attacks, they require that I, if I'm the attacker, own or at least have interactive access to a virtual machine hosted on the same host as the target machines, right? Yes. Okay, so what are the implications for a, say, VM or whatever environment, thinking of desktop virtualization, where actually the virtual guests are being used for interactive access, and so you run a JavaScript and a browser or whatever, because I'm, like, every week being approached by companies trying to sell us desktop virtualization. So the idea of running that gives a complete new, large open door for Melva's spreading across virtual client computers, right? If there is desktop virtualization. So our second attack, they did, as Makina was done on Windows 10, so there we could leak information because Windows 10 does marry the duplication, not only for virtual machines, but also for its own processes. And Windows has disabled it, but if you run Windows on a hypervisor where the duplication is yet again enabled, then yeah, you have the same problem again. Thank you, and then I have a question here on the right, please. Do you also have the problem if you, are you vulnerable if you have both ECC memory and exempt any cryptographic secrets from de-duplication? So I haven't seen a practical attack with ECC memory on Rohemmer, I don't know. And I guess if you have cryptographic secrets and you don't de-duplicate it or you put some randomness in there that is impossible to guess, then I'd say there's not much you can leak from that point on, but it's something, I think it's not, yeah, you shouldn't burden an application developer to be aware that their memory, even to be, even be aware of the content layout of their program that's for most of the time very much low level stuff that yeah, application developers have no, shouldn't have to have any concept about. So I think this is really up to the operating system and hyper files offenders to, yeah, not yous, basically. Thank you, and in the back please. So when you merge the pages, you can have more of, you can have two in those examples, you can have more of them. How do you know which page will be the one that will be the last one? So, I can merge into it because it would be good that it's the one you control, so we can flip the bits and how do you know if you have like five VMs and every one, every has the same page? So it's kind of complicated, so the, so in KSM it's the oldest VM that gets merged to, but there's an exception if you first merge two pages and they are put in the first, so it first merges to already merged pages and then it merges to the oldest VM. And so the attack becomes harder if you're the second VM. And so to flip things, you need to be the first one, so then they will merge into you. Well, not necessarily, but the attack becomes a bit harder because so what you could do is if, so the merging happens because files are in the page cache, so if the files are not yet in the page cache in the victim because no one has tried to log in for a user for a long time, you might be able to first create two pages in your own address space, wait for it to be de-duplicated, then log in to SSH and then SSH will load it in the page cache and then it gets merged to your page. And you win because you're merged already ends. Okay, thanks. Thank you and a question here in the front, please. Yeah, so if I understand it correctly, the attack works only if you know, if you detect the time difference between when a copy on write happens and when it does not, wouldn't it be able to have implementations of de-duplication with some artificial timing added? So there's no real difference. So, well, the copy on write takes time. So there's, yeah, that's probably not, no, yeah. So there's always going to be a time difference because you don't want to have artificially, you don't want to artificially slow every write operation, that's just. Would it be theoretically be possible to do it if timing is not a constraint? Then you have to, all the write operations, you have to slow them down as well, right? I mean, this is not feasible in the end, so. Thank you. There is a question from the internet. Yes, the question is, can this be applied for long PGP keys? Can we leak them? So leaking the complete contents or breaking them or? Doesn't say so in the question. No. I suppose it's about leaking them from memory. If you can find a way to, for example, first load them. So it really depends. So it takes some effort to find the situation. So you have lots of opportunity to find situations where you can leak data, but it's really difficult. It just takes time to find the right circumstances because it's just so much you can explore. So we didn't look for a situation where we could leak GPG keys, so I wouldn't say it's impossible. I do think that some crypto applications really make, try to not keep private keys in memory longer than needed. So I wouldn't know. I wouldn't know. Maybe you can try and find out. All right, thank you. Great. And then we have a last question over here, please. Maybe do you have some advice for the Linux kernel programmers? I think in the second example you said, for example, the page de-application used, I think it was Windows 10 was better. They did first copy the page to be de-applicated in a free page and then pointed the two pages to be de-applicated there. And in Ubuntu, it was that they just point one page to the other and drop the page. So the Microsoft approach is here more safe. Yeah, I'd say so. I don't know if they were aware of this, but in this case, well, maybe they were. I don't know. In this case, and there's certainly some approaches or make it harder, and some approaches make it easier. Of course, the relocation doesn't prevent us from leaking data, but it would help maybe with making Rohammer harder, although our group also has a paper on Rohammer on Android where we don't make use of memory de-application, but we make use of a different mechanism in order to control where memory pages get relocated. Yeah, from Rohammer, we can't do anything because we would have to change the memory architecture. But maybe you can publish some advices. What to do better with, for example, memory de-application, what you found for in your researchers just as an idea? Yeah, so there are some mitigations. We don't know if, yeah, but they always have some performance penalty drawbacks. And so I don't know whether they will be implemented or are standards enabled. OK, thank you. I'm sorry we have to cut it. Thank you so much. So please help me thank Antonio and Eric for a wonderful demonstration.