 Cool. Okay. Well, welcome everybody. We are going to be giving the talk exploring Linux memory manipulation for a Steels and a Bastion strategies to bypass read-only new exec and digital environments Probably the title is self-explanatory about what we are going to be doing is to abuse Linux memory in order to bypass some file system-based defenses and also to get RCEs in well, yeah to to try to make it easier to pivot where you are talking about Disturless environments, we will explain what this is if you if you don't know about it so for the people that Read this title and doesn't start of a and doesn't understand a thing Don't worry because we are going to be starting from the beginning We are going to be explain you why we develop this technique and also how it works So you should be able to follow everything also We have a lot of demos for the people that are already experts in things related to this I will ask you to wait to the final fireworks because things are going to be getting harder and harder So we are going to start easy and then we are going to start doing the complicated stuff. So just great for the end Also, as you know, this is our first DevCon so far. This has been a great experience We are amazed with the with the community with the conference So I would like to start this talk asking you for a round of applause just for DevCon because it has been a really great great conference Cool. So who wants all of you know about this comment. I'm sure so I'm Carlos follow up Technical leader at Halvour and I have a lot of certifications I was the captain of the Spanish speed team in the European cybersecurity conference a couple of years ago I'm also member of the winning European team in the international cybersecurity challenge last year I'm also the author of hacktree's hacktree's clouds and peace Thank you I am just a lost nerd in their wilderness I'm still studying telecommunications engineering. I love Pwn I love see assembly And Linux internals and I don't think I have much more to say about me. So let's continue. He's great Okay, so what are we going to be talking about we will start with an introduction about what the technique We are going to present you the initial technique we developed called DDX tech And then we are going to do a lot of demos all these demos has been already recorded But we are going to be doing all but one life because we really like to do things like even if they can fail So let's hope it will go. Okay, and at the end we have a surprise We developed a new technique that we weren't prepared. We weren't expecting to be to present in this talk But yeah, go yesterday finalized the initial step. So we are going to be doing a demo and we will expect that it works Yesterday worked most of the time. So let's see Okay so Cool, everything started maybe two three years ago on the things that I was working in this company And they decided to move all the containers to these first containers and my boss asked me hey take a look to this new Distance container because they it is it is said that it's very complicated to Compromise even if there are vulnerabilities in web servers in these containers is very complicated to compromise them So take a look to them and let's find out what an attacker could do in this kind of containers So the question was is this truly the new hackable system? The reality is that in that time I didn't know much about digital is also about containers So when I just started taking a look I discovered that I don't even have a cell in these containers I don't have a sage. I don't have buzz. So it was like men Even if someone finds a remote code execution here They are not going to be able to execute cut to execute the list to execute who am I they cannot execute a thing? So to me it looks like pretty led you did it's adding a lot of security And I didn't know a way to to bypass this at that time also I started playing more with with with Container with Kubernetes and in corner that you have this easy flag that you can set to true Which is read only which will make the file system read only everything except one of two folders that have the no exact beat Which means that if you manage to comply to compromise a read exact container in Kubernetes You are not going to be able to download binaries and execute them because in the only place where you can write You have the node execute bit and you don't know how I know you need is as a red teamer to compromise a cool net is competitor see these cool net is token and don't be able to download Cube CTL and execute it of course You can use cool for insight But you need to use cool to contact the QB API manually and it's just annoying So yeah, it makes your your life much complicated and at that time I thought hey Okay, so I cannot write in the file system But what happened if I could load something in memory and execute it There is nothing preventing me from doing that And I knew at that time that there were a lot of different techniques for do this in Windows It's super easy to do this in Windows, but what about Linux? Well, there weren't some many and the word that were in there weren't that reliable So at that point I started my conversation with Diego and well He came up with a very strange idea that ended up working perfectly But before getting into this technique, let me tell you about the state of the art in that time about how to load things in in Linux memory and execute the stuff At some point we found this block from sector seven that told you that if you managed to write things in memory you could use this Cell code using the syscall memfd create that will allow you to create a file in memory That is readable from the file system So you could create a file in memory load your binary and execute it This will allow you to bypass these protections And also I will they were developing the technique that now Jao is going to explain We found that David Buhanan was doing something very very very similar But just smaller and actually he was using a couple of extra techniques that we ended up Implementing in our final technique called DD exec But at that point that was the the state of the art You couldn't do much and it was kind of complex and and dark how to do this So we came up with DD exec So the idea that I that I had at the time was to trick DD into Okay The idea that I had at the time was to trick DD into overwriting its own memory through the mem file in the procfs file system Um It turns out that somebody had that idea earlier like three years before me That was the post from sector seven Then I discovered that David Buhanan Had a tweet Where he used A way to to to To great to to the memory of the of the shell of bash or the or zssh to This has the benefit that it doesn't need to disable a slr Because when we when we tricked DD to into our writing its own memory We needed to to tell to tell it at which address you needed to to write And that address must be passed in in in the arguments So we need to know um at which address Write before the d doesn't exist And that was the problem With bash we have the benefit that bash already exists. We use an inherited file descriptor And that way we can we can write into a bash's memory And we can check the the mappings that bash has Before hung so um Well, Buhanan The the tweet from Buhanan was What did was um just Write to bash memory to execute a native code a shell code And it didn't allow to to run a binary So the tool that I made that I had to to develop in in shell scripting What what it did or what what it does did the exec is to parse The binary And prepare a shell code that will perform the same The same process that the kernel does upon each call to exec v So Uh, we we need to load the loader in memory. We need to load the binary Because each elf has A headers that say the kernel or the loader Which portions of the binary need to need to be in memory and in which address And with which um with what protections So We we create those mappings We read the data of these binaries into these mappings we we fix the the permissions Then we prepare the stack we need The kernel leaves some information for the loader. It is called the auxiliary vector And this has the data like At which address is loaded The binary and where are the headers of the binary and stuff like that So we prepare the stack and then jump to the loader sentry entry point and the loader will Will parse the binary will will see which libraries i needed are needed Then load them and link them and then Jump into into the binary sentry point So we did the exec we prepare all the stuff and let the the loader Do the rest So he's playing like very very easy. Um, just so you get An idea of how complex this actually is All the thing that he said that he's preparing the memory and everything is actually a cell code that is going to be created Using cell script. So he dynamically creates a cell code to load a binary inside memory Using cell script. I mean if you read this it's like it looks like the code is sophisticated, but it is not it's just super ugly So, yeah Just so you get the idea. Cool. So let's start with the first demo Where we are going to be using dd exec to bypass these these protections So what we are going to be running? I have a cool net spot running this with with this read only root file system Which meant the file system read only and this allow us to download for example qctl and execute it And we are going to be executing qctl using the dd exec technique So I have the demos prepared here so I can copy paste and I don't break anything We are going to get a cell we are not stealing the distro less part. So we still have a cell if I run mount Do you see this? Do you read this? Yep, cool. You can see that uh rudies uh mounting in read only and also something interesting is that Dev shm here is read write, but it has no exec. So even if we have already here Keep ctl if we try to execute it we are not able. So what we are going to be doing is to load a binary With dd exec in memory and un-executed Let's start loading ls for example so What we are doing here is just uh base 64 encoding ls uh send it to dd exec and here we have the arc zero And the arguments we want to pass in this case just does h So it takes a couple of seconds to run because it needs to to load in memory and Sooner or later here we we just executed something from from memory So of course ls was already in the system. So it wasn't that that complicated to execute it Um the thing about big binaries for dd exec is that it takes a couple of minutes to run So here what you can see is that we are going to be running dd exec in this video Just because I don't want to waste five minutes of the talk waiting So I have just cut the video and we'll show you that you can actually run qctl So if you check the last line, we are loading qctl in dd exec Um, this is the magic of video. I just cut it and it just worked and you will have the the help of qctl So you could load even big go long binaries with this technique Yeah The problem with qctl is that it is a really large binary. It is like 40 megabytes And um because the dd exec is programmed in shell scripting All the processing of the binary is done with pipes between commands and This makes everything every really really slow Um so With qctl, um It it it lasted running like 10 minutes 10 minutes. Yeah. So that's why we had to cut the footage um Okay, so After After some months, I came up with the idea that Dd can be used Just to seek through the file descriptor that points to the mem file in Which is a presentation of the of bashes or or the shells memory So we seek through this file And then write with just Redirecting an echo or a printf or something like that Uh, so we can look for other seekers Um Well, I didn't see the This slide. Yes. So I'm going I'm going to explain why Do we have a pointer? No Okay, so POSIX file descriptors have a really cool quirk which is that um Um When they are inherited They are in inside the kernel. They are exactly the same file descriptor the structure that describes The state of of this file descriptor is the same so, um If we I have here like an example we have we create a um A file txt And we create a file descriptor The file descriptor three with read permissions And then We tell dd to write at offset three Uh, we tell it to write through the through the through this file descriptor And we tell it to to write a zero bytes When we read from this file descriptor we which was displaced Did you perform an lcc school in this file descriptor? And to this to To move the pointer inside this file to the To the to the third byte So when we read we will see that we are we're reading actually Three bytes after the the start of the of the uh file Um, so and this is even They are two different processes this this works just because it is the same file descriptor um So now we can just use dd to to seek um And we can use other other seekers Oh Like tail or cmp files that Recommands that allow you to specify um An offset at which start to reading We can use them They they weren't useful before because Before in in the demo in david's demo Didi was used not only to seek but to write Uh, and it didn't use this this quick of the file descriptors using this quick of the file descriptors We can just seek and then use printf to write Well So something fun about this technique is that now we don't depends of dd So we found an idiot that was trying to search for this technique when we released it And they were looking for dd using big numbers. So it was a very Easy thing to bypass. No, you can even change the dd name to uh to a different binary But actually we now you can use like 10 different common binaries It lean is just to to move the file descriptor And and and write in any position you want in memory. So this actually allows you to bypass the only idea that was catching this technique And um, potentially the new ideas that we'll try to catch the the technique. So let me show you very very fast A demo about this because actually in the same ddx sec Script that we have shown before You can actually in the case in the seeker the binary you want to use and it will be using internally this binary So here we are using compare and we could also be using um xsd. There are more. Um, There are more prepare inside ddx sec So you can just go to the read me and take a look to the ones proposed in there But actually any binary that is executing on lst With a few other requirements is going to be able to allow you to just load anything in memory So actually we develop a very resilient technique in order to load things in memory and bypass these kind of protections Cool. So let's move forward Now let's just start talking about distrust container So if you ask gpd for uh some months ago about what is a distrust container He will tell you this but basically what you need to know is that he has the minimum needed packages to execute Whatever you want to execute. So if you want to execute a python Web is going to have python is going to be having python dependencies But he probably won't have bus. He won't have ls. He won't have cat Let's say that he will just remove all the libraries and commands and and and packages that you don't really need to run What you want? So this is great because it makes the container much much more smaller Also, it makes it more secure. It makes very very complicated to Exploit vulnerabilities because we are used to executing stuff that we expect to be there That's the problem I had at the beginning before I started thinking about the the memory stuff So let me show you real quick how a distrust container looks like So the previous demo we have run them in my current macOS, which is arm These techniques work for both arm and x64 now we are going to go to a Kubernetes environment in in aws This also works in current environments in the cloud that are in x64 So this way you can see that all the techniques kind of work in both architectures So i'm going to update the credentials Actually the pods that we are going to be using for the next demos are this one We have a node prototype pollution digitalless container And all of them have the read only root file system This is using the node digital is from a container from google. This is one Using python another one using python and then we have a php that is using the new Chainword digital is images just so you can see that these techniques are working with both google digital is and chain link Chainword digital is container and also we have a wuntu machine inside the same Kubernetes environment because we need to capture some river cells to mimic a real environment So what i want to show you here is that we are going to be getting a cell inside the flask digitalless container In this case we have a shell some digitalless containers. We have some cells, but if we execute ls we Don't have it who am i? god it see Oops, well do you imagine that god not phone so yeah Whatever if you find a cell Yeah, so you know you can still use the buildings of the cell so we could be reading the hc password using some the read v2 And if we try for example to get a cell inside the node um digitalless container We are going to see that we don't even have a cell here So this is how a digital container usually looks now you should be familiar with this trace This is the demo so far the demos are working. So this is pretty good Okay, so let's move forward. Let's do these python digitalless demo This is the one i'm going to be putting the video because actually we are not using our own technique We're just using an old technique that already exists, but i want to show you anyway The thing is that um Well if you find a common injection in a web cell probably it has a cell Just because usually to to execute commands from scripting languages the cell is going to be used So usually you will you will find this But anyway because you don't need you don't really need a cell If you are compromising a digitalless container and you want a rubber cell even if you don't have bus If the if the web server is running in python you can have a python web cell So you won't be running bascomans, but you will be able to run python code, which is still pretty pretty good Also scripting languages such as python pearl and ruby By default install some libraries that allows you to call to call row syscalls And that's actually everything you need in order to load something in memory and execute it So this project right here uh file less elf exec is doing that It is going to transfer some python ruby or or pearl Is going to transfer a binary rapid into python pearl or ruby code and allow you to execute from these scripting engines So for this uh for this in these specific cases in these specific digitalless cases You won't need to use our technique the scripting language is enough So I just want to show you this real quick and actually we are going to be seeing a video Here we have a vulnerable python pods running our web server that I have poured forward to my localhost LS doesn't exist cat doesn't exist Using the built-in command. We can see that we have python. Of course. It is running in flask So we are going to be getting now. We are going to be abusing. Sorry. I wasn't expecting that We are going to be getting a rubber cell now A python rubber cell if you're going to be playing with distressed containers Forget about bars reversal. You're going to be getting no php python rubber cells. Here we have it Now what we are going to be doing is uh just down here We execute ubuntu. We are going to be preparing kubectl to be execute with python So we have download the project I just told you about file less elf exec We are downloading here kubectl Now we execute the file less execute to prepare kubectl and actually this script looks just like Looks like this So basically what this is doing is getting the binary in base 64 Decoding in memory and just calling the syscall execla to execute it Again, if you can call syscalls from the scripting language You don't need to do extra stuff to call syscalls. You can just do it So in our case in a rubber cell what we need to do is to create a children because it's not whenever we And executing this command our our web cell is going to be dying So here i'm just changing the the code to well to fork it to execute kubectl in in a children I'm going fast because we have a lot of things to do yet. We are just starting so um Okay, now we are going to be we expose in this ubuntu server The kubectl.py that we have prepared in our python rubber cell. We are going to be downloading this in memory again Okay, and now If we just exec it we are going to be able to run kubectl in memory in python again We haven't used our technique But just so you know if you find a digital is with ruby pearl or python You have a very easy way to just call syscalls and execute things in memory But what will happen for example if we have A node server we have an express web server with an rc vulnerability Well, there is no sh in the server. So we can still get a node rubber cell Again get used to getting this stuff in digital s you can use node to enumerate the the the server So you cannot execute ls, but you can create node functions that behave like ls So you can enumerate the files And node cannot call syscalls directly, but we could use a cell code like ddexec To modify a new node process to execute anything we want So what we are doing here is to abuse the the exact technique in order to load anything we want even in node Who cannot call syscalls? So in this case, I'm going to be using the cell code that Use the syscalls create memfd that I told you about at the beginning We are going to be creating a file in memory Then we are going to be loading kubectl in it and we are going to be able to execute kubectl In another distro less container in in node And actually I'm going to try to do this demo live. So this is going to be a good one cool So Let me get we are going to be in our target machine wound to I'm going to be forwarding For 3000 to my local machine because there's where the the vulnerable Server is running and here. I'm just abusing a prototype pollution to rc vulnerability in order there to get a reversal This is outside of the scope, but if you're interested in about how to do this you can check my information in haktrix So it was executed And I forgot to capture the reversal so we had a real problem here No worries. I just need to restart real quick, which is going to take like a minute The bus but now we can be prepared to capture the reversal Yeah Never forget the most important part of rubber cells the listener Sorry about this. So Kubernetes take a minute in order to restart the bot So that's what we are now waiting for but in the meantime we can just prepare The I think he was looking at me angry. Cool. Okay. I suppose this should be now ready Okay Back on track. Um, actually, let me let me take a look if I have any other Listener in there that could be bothering and actually have one. So this wouldn't have work again Executed and we have our node reversal great And now we go with the demo. So I told you that you can use That you can use node code JavaScript code in order to enumerate the current machine So you could use for example the os library to get a tmp dear information about the architecture or the network information So you can still enumerate this this release code And you can also execute things in memory, which is what we are going to be doing now I have the demo here so you can follow it better So here what we are going to be doing is importing some stuff and we are going to create a new JavaScript file with the code that we want to run and the code the cell code that we want to roll So we are going to be using the syscall trick in order to know where we need to override inside the memory We are going to be overriding the memory be a prox self-mem and this is the the cell code that is going to be executing the the the syscall Create mem create mem fd. Yeah So we prepare the file through our rubber cell We write it in the file system and we check that it exists. So it exists right here Now we call be a fork this new child process that is going to be executed our Our cell code now we want to check if this work, of course So this is what the function is going to be doing and we can see that we have a memory file descriptor that we call dead just to for the sake of a stillness, I guess file descriptor 20 proc id 59 So this should be working Okay, and now we are going to be creating this download function that basically is going to be able to download To download something from the internet load it in the in the mem fd and and run it Okay, we download it It should be working and now if I execute the memory file descriptor It should be executing a qctl and here you have the help of qctl So we were able to bypass these problems protections by executing things in in memory So In order to to make this more more useful. I decided to make like a ddx sec a demon of ddx sec So we can just load filelessly this program or In the end I actually made it a shell code. So we run the shell code With any of the of the of these techniques that allow us to to run native code We run this this shell code and we can tell this this shell code to load a binary with the arguments And then just we will have a we will be able to to run any any program we want And Again Cool So basically this will allow us to use what I have showed you but to load binaries Like more frequently are more useful instead of doing everything once and again It will allow that just to send the binary and load it and execute it So in this final demo before the bonus that I hope we have time for that What we are going to have is a php digital is we are going to be using the chain war Images for this In this case, we don't have a cell. We are going to be getting a php rubber cell We are going to be loading the new the new demon And actually we are going to finalize this demo loading a bc box because we are in this or less It will be very ironic if we can have a cell in this or less. So that's what we are going to end up doing So let me get let me show you that in php we don't have Any bus any sh sh file not phone. So we are going to be getting A php shell and now we are going to be getting a php rubber cell So imagine that we have compromised our web a php web application with a a nursing And we got a a rubber cell with php Okay, we have it here And now maybe you want to follow the explanation Okay, so what we are going to do now is Execute another another php another interactive session of php which will we will communicate through a pipe with And we're creating there the the pipes And now starting the process Okay, so This this interactive php we will send it commands To to write a shellcode also through the through the mem file in in the proc proc fs file system And we will run This this shellcode that I made this demonized ddxec We have we have the shellcode in arm 64 or x64 And and now we have Okay, he he made a mistake And now we are writing the shellcode because there is a shellcode that is a stager That reads the the other shellcode because the second shellcode is really really large And and now I have created the dysfunction that is called memexec And this function is is the one that Is used to to communicate with this with this demon We can throw it on uri to A binary it may also be a binary inside the on file system And we we pass it the arguments and we can and we can run any command In this case we are we are downloading them from um Massive And to finalize this demo what we are going to be doing is load a busi box cell inside this rubber cell So what we have here is that now we can for example call for example call set to enumerate Ambient balls or run pwd basically we put a a bus inside a distro less which was the the main goal of this So we just defeat distro less security measures So now the the bonus technique Um, this is another technique And that is um Getting that old and new at the same time um Didi exec has a problem that we need to to pass the file And Unload it and a loader is really really complex. I have uh skipped a lot of Um peculiarities that elf have um and extensions from BNU and sound microsystems and things like that they have they have added um That's mayhem so we you can have like compressed sections and lots of things and did exec isn't um Doing that stuff So another another way to to load file as lia binary Is to use the elopen But tricking the loader And to thinking that The the binary is Somewhere that it isn't Um Okay, so this is a technique that was um presented in a in a paper And I think in 2004 um So the idea that this the this people have was to um You have the binary that you want to execute bro in memory the elf um In some way you get to to hook to the syscals that the loader is going to execute And um and then call the elopen passing to to this function some fake path Since you are hooked to the to the syscals you can detect when the loader is trying to open um This file path that you have that you have given it and Return a fake file descriptor and in in subsequent um syscals you can see if the file descriptor that the loader is using is the fake one that you gave it And in that case you fake this syscal so in case um That you read That the that the loader is trying to read from this file that doesn't exist in the in the file system You can just mem copy from from the from the place that you have it in draw in memory And write it where the loader wants to to read the data um Okay, so um On the paper they didn't discuss how to hook to the syscals And there was Um someone his alias was mimics um That in github has an implementation um That used Call signatures to find the places that the calls to the wrapper functions That the wrapper functions to the syscals and overwrite that calls With calls to to its own code The problem with this is that code signatures may vary between between libraries and so this isn't uh, particularly useful because then you if you go to if you Have access to uh, to a system you need to download this library and get the this code with these code signatures and It is Really complicated Um So my idea To hook to these syscals was to install a wrapper to install a signal handler for the signal Seek ill which is a signal that the kernel sends to a process if this process turn tries to execute um an instruction animal instruction and then A go through the memory of the loader looking for each a syscal instruction And replace it with an embodied instruction um Then so now we are just uh, we have the hook that we need and we can trick ld with Just like the paper tool Okay Well, uh, uh, they also discuss it Discussed it to to load uh libraries The the but um, if you if you make a binary look like a library you can also Get ld to load this This this binary So later we are going to show you the links to all these tools that we have just so you did the segment Did it open um, but here just want to show you that this is actually working so we have here a A dvm container That I have already download memdl open dot ish And here what we are going to be loading basically is just uh ls the sla uh passing in the standard in the the binary So we do the id like this you can see that it's actually much faster than the ddxx technique And and well we still are working on this to improve some things. Yeah, um this is actually Some project that I I haven't dedicated a lot of time. Uh, this needs a lot of research I I have detected that it has problems with binaries that aren't position-independent Uh, but well, I think that I will manage to to fix these issues Um, cool. So you want to show the code? So, um, this is the the shell code Um It is it is long and it is complicated. Right now it is only implemented for arm64 There is a proof of concept written in c that is much much more understandable. You can see the the The the installation of the signal handler We have also the The replacing the replacement of of the of the the syscal instructions with with um invalid ones and we can see here um How this signal signal handler is taking from the stack? All the arguments that were intended for for the syscal Uh Checking which syscal it was and faking um Each one Cool. I think you you have all this code in the in the repository with some comments to help you understand it So actually the repository you can find it in here Um, here you have mem deal open our remote lever injection Well, we have it. We are going to be sharing the slides, but if you want to take a quick photo I will leave it for 10 seconds Um, also all the demos that I have been doing about these controllers You have them in this repo if you want to to try them yourself I hope to find some nice ctf in the future using this technique Um, what else? Well, also jago wants to share with us a very well upon challenge you have It is just a fun really small challenge But I think it is kind of weird It is really easy to solve but to understand why it works is really interesting if you I have shown it to I posted in twitter and I think nobody liked it So if you if you if you get to to solve it and tell me why it works I will give you a hack Some final spam to end this to end this talk Me and my mates at hacktree start preparing a hacktree's aws red team expert Certification that we expect to release in q4. So if you're interested in aws red teaming Just follow us in twitter link it in or go to this page And thank you very much to to you people and to defcon for organizing this it has been a great pleasure to be with you