 And 30, let's get started. I think we've given out enough. Anybody has any assignment two questions, I'll take them in the next two minutes. Soon, if you're in this room, you've probably completed it. I don't want to do a poll, so I won't do that. Yeah, it'd be fun to talk about what happened and how there are an intended way that I wanted to break it, and another way that you all found that was also really cool. So it's good. Good work. Hey there, can you help me? All right. Do we get information we did in the non-intended? I think so, yes, I will. So I think it's a little bit more difficult, but it'll be like two or three or five points. That's not how many people did it. If it's only a little bit, I would get it. Cool. Well then, let's get started. Can we get started? I think you've known. I think you should be clear, if you read all my posts, I was trying to push people in a direction. So if you can figure out if that's the direction you went, if those things make sense, then you'd be like, oh, that was the intended path. See that other people were pushing in the other directions? But I didn't really anticipate that was the really unintended way. So that's, unfortunately, I can say for now, right, that there's not enough like I could do anything. If we're going to look forward, we're going to look around. All right. So Wednesday, so on Monday, we talked about path attacks. So we saw that if a program uses the path variable to look for an executable, the path variable, right, all environment variables are controlled by us, by the attacker. So we can influence that path variable and make it be whatever we want to get the program to execute whatever program we want. The same thing occurs with the home environment variable. So we talked about home is used by the shell when doing the tilde expansion, right. So if the program tries to access something like tildemyfile.txt, we can change the home environment variable to point to wherever we want. And to make this program execute now, it's our version of this myfile.txt. So whether this is a security vulnerability or not, right, depends on what the application is doing with this file. But if this is a setuid application and it uses this file to sign up for missions to give you or uses it as some sort of configuration file, now we, the attacker, have full control over the contents of that file so we can get the program to edit or read any file that we want. So how do we prevent these attacks? Signing, what's that? Signing what? Signing what? Signing the file. Signing the file. Yes, we can use fancy crypto things which we saw how well they work. Even alleged experts like myself can get it wrong. Right, so we can sign the file to make sure that it's a file that hasn't been tampered with and that it has the right signature. What else, what are some other ways we could prevent? So that would prevent probably the home CH route so we could execute the program as CH route so it only has access to there. Yeah, that would limit the scope of the attack, right? But if we can still modify the path and home directories inside that CH route, we could maybe manipulate the program somehow. There's a key problem here on both of these spaces. We need to fully contain the problem. I think it's a good line of reasoning. Like for using the CH route way, the user could still access sub directories of the new route and in the other technique, I'm not sure what the other technique is, but there are still other files that could be accessed. Right, so what's the key problem with both of these attacks here? Environment variables. Environment variables, it's not just the environment variables themselves that cause the problem, right? It's not the existence of the book page. Activity to them. Yeah, well the fact that it's not also not just accessibility, right? The application could read all of its environment variables. But what is it changing based on those environment variables? The path itself. Yeah, it changes what files it's executing in the first case and what files it's opening in the second case based on values that are controlled by food. Well, the attacker, us, right? We control environment variables. They're not defined in the application itself. So what would be, yeah. How about running that in a container? You're still, you're restricting what it can do, but it can still do anything it wants to in that container. Yeah, but they don't have access to the navigator even if that comes down, it doesn't take that direction. It depends on how you work your containers, right? I mean, what useful things are happening inside that container, right? It's still, the vulnerability is still there, right? It's just you're limiting the scope of what the attacker can do, but attackers are very cluttered, right? Attackers only get smarter as time goes on. So even if you restrict it's end in there, if that's enough for them to do what they wanna do, then they don't care, right? So how do we fix, like the second case, right? Your application is reading a file, tilt a slash, mine file that TXD. How do we fix this? Absolute pass. If we get an absolute path for this tilt a slash, mine file that TXD is the application ever gonna read the home environment variable? No, then we can't influence what file it's gonna open, right? Same with the path, right? If we execute files from absolute locations, if we exact slash user slash bin, or slash, I can kinda think of more LSS, slash bin slash LSS, right? Then it doesn't need to look up in the path which file to execute, right? The path environment variable is only used when it can't, it doesn't know where this file is located. If you just said execute LSS, well now it has to look up in the path about where is LSS, right? So that's actually kinda the big, one of the big takeaways is that if you're ever executing an external command, you should always use absolute paths of what to execute. That way you know your program is only gonna execute that file. Similarly, you should never use home relative paths. Kind of the exclusions here are just, don't do that, stop doing that. You're hurting yourself, right? There's all you got to exhibit a few of these environment variables. Yeah, so how do you deal with, well, so yeah, there's a lot of flexibility, right? You have to either, you have to trade, you can see that there's clearly a trade-off between the flexibility and, so what could be some ways you could gain the flexibility of using the path, for instance, right? Path is very useful. What's the key problem about relying on the path environment variable? Separate, that's where you are as, it depends on how secure we need the application to be. I mean, we're talking about stuff, we're talking about set ID. That's different than if we're talking about order that needs access to relative paths or... Also true, but here, talk to the folks like, so let's focus on set-UID applications, right? Because these are the ones that are much more interesting. These are the ones we can control, right? These are still good practices because you never know when, you can't control where that application's gonna be executed, right? So word on your system or my system is probably not vision-critical, but on a government system where it's being used to access classified information that is critical, right? It's just the environment there, not the application itself. Before running, can you verify the bot video with what exactly is on the system? So what, okay, yeah, so why? Like, what's the core problem with relying on that path environment variable? It can be changed by the attacker, right? It comes from the attacker. So one way to get that same flexibility is to override it with our known good environment variable. That could still be tricky because what if the paths that we're putting in there don't exist on the system? And then the attacker can create that path and then now they're able to influence. So it's also becomes very tricky of how you do that. You have to guarantee that every directory you put in the path can only be writable by you, the user of this program, and not writable by anyone else. It gets to be, it can be very tricky. So you're better off with doing absolute paths. Any questions on this attack? Yes. Something on this attack, how the commentator can change the path variable of the target system if it doesn't have physical access, something like that? Yes. So in all of these attacks we're looking at, we have local access. So we have local access to the system. We're trying, but we have normal user access. So we're trying to leverage that into better access on the system. So in this case, we are executing the program. Programs when we execute them inherit their environment variables from us. So in this way, they'll get the environment variables from us, the user, and the running is set UID. So the running adds the permission to the route, and that's how we want to control it. Okay. So there's other, so we're looking at file accesses and file system changes. So there's other kind of games we can play. So what kind of, unlike a Linux Unix machine, so what types, what's a link? What type of links are there that get the sense of the file system? Symbolic. What was it? Symbolic and hard? Symbolic means soft and hard things. And now, are there different types of links? What does it do? What's the purpose? It's like a shortcut to another. Yeah, it's like a shortcut, or if it has some name, and it means, okay, this path, when you access it, actually refers to some other path. They're kind of like pointers in the file system. They say, okay, if you want to access this directory, hey look, this directory is actually somewhere else. Let's see, can I do this without you? Okay, so here you can see in my, like, my tilde, so when I do ls-la-tilde, what's it looking at in here? Home, yeah, so if I do environment, so if I do echo home, right, this is gonna tell me this is my current home directory. If I echo path, this is actually the path of everything that's gonna execute on my system. So I've been jumping here, probably clean this up, it's on point, but over the years you use the same system and you just, what is this, some Ruby, RBM stuff that I never use anymore, some other scripts I was using like four or five years ago, but I just keep putting them in here. Rather than change it and have something break, but anyways, so we can see that I have in my tilde slash, let's say, I don't know, teaching folder, that's a link to drop-off slash teaching. So when I, so if I access teaching slash, slash CSE, 545, right, so when I access that in here, it knows, okay, this path, when it sees an element of the path and it says this path to the symbolic link, that means substitute this for in my Dropbox folder slash testing. So in this way, the benefit is I'm constantly working on my Dropbox, so I never have any problems, hopefully. So it turns out that symbolic links can actually be turned into really cool security problems, all actually a few different security problems. So for instance, some applications will verify that a file exists, but not check, hey, is that file a link to another file, or is it a certain file or the permissions of that file? So how might we be able to take advantage of this? So let's say an application checks that a file exists, and if it exists, it opens that file and reads and writes to it, a sent UID application. Yeah, so if that file doesn't exist, right, so first we could create a file with our own name, right, and then it would open that file and write to that file, then we've gotten that application to write to a file that we control. Could be interesting. Even more interesting is to get that program to write to any file on the system. So if we create a symbolic link from that file to, let's say, EDC shadow, and then get it to, or EDC password, and to get it to write out a new user account on the system, now we've actually tricked that application into writing to a file that wasn't intended. So this is the basic idea. So if we can create symbolic links and get that application to open files, if that application checks and says, okay, I'm only gonna open files in this certain directory, right, so it checks, it's constraining itself to one directory, and then it opens one of those files, it writes to it, does some, any kind of permission manipulation. Well, now, using symbolic links, if we can write it into that directory, we can create a symbolic link to any place on the system, and we can get that application to write anywhere for us. We can get it to write to the SSH authorized key file. We can get it to write to, I think of other cool things. EDC password is a big thing because you can add new accounts to the system, EDC shadow too. And so another actual kind of wrinkle to this is oftentimes applications will create temporary files, but they'll not actually, they oftentimes won't check, hey, did that file successfully created? Is that thing I created a file and not a symbolic link? Okay, because if we can guess what that file name is gonna be, then we can create symbolic links to other files and use the same mechanism to get the application to open files that we want. So let's look at an actual attack of this. So this is called the DDAB gather attack. Anybody actually ever use this tool? The common desktop environment? I actually have to look this up. It's a super old Unix, graphical user interface. So this is the utility, this DDAB gather, and it was set to ID root because it needed to do administrator stuff. I don't know exactly why. What it did was it tried to create, it created a directory, a specific directory and gave that permissions on that directory to 0555, so let's 0555 read execute, yeah, read execute for each user group and world. So it seems like a normal thing, this is what you wanna do, right? You wanna create a temporary directory, you wanna store some files in that temporary directory, whatever, but, so the file name that it was trying to check was var dt appconfig, app manager, generic display zero. So this is the file, this is the directory that I was trying to do and change these files, but it didn't check, hey, is this thing already exist or not? So it would open this file, set it to be 0555, and then start changing it or doing whatever it wanted to do with it. But it didn't check, hey, does this thing already exist or not? So what if we could write into this directory to var dt appconfig, app manager, what files would we wanna change to be 0555 if we can read, to be able to read? The important thing is that we can read anything. Shadow. Yeah, etc shadow, right? If we can get access to the shadow file, then we can start cracking some passwords and trying to break the application. And so it's exactly how this attack works. So if you looked at the permissions on etc shadow on this system, root had read permission, everybody else had zero permissions. Right, we've seen how to read this. So we can see, okay, this directory is linked by root and the group is other. So here the user is just read and all the other permissions are nil. Nobody else can do anything with this file. So then what we can do is as a normal user, we could create a symbolic link from var dt appconfig, app manager, generic display zero, point that symbolic link to etc shadow. So now, when we run dt app gather, it's gonna try to make a directory on this var dt appconfig app manager. It opens it, it tries to set the permissions and then it says, oh, file exists and it probably errors out because it wasn't expecting there to be a file there, instead of a directory, but it still did stuff. So then we check the permissions of etc shadow. What are the permissions of etc shadow? And we want to be 555, read execute for everyone, right? So we've got this program to change, it's a set UID program, right? It has all the possible capabilities of root, but the way it's coded and the way the program is intended, it should only do this one little thing, right? But instead we're able to actually trick it into changing a file that we control and making a file that we want read accessible because it just changes permissions without checking if that file already exists. So how are we gonna fix these effects generally? So what's, what are some of the takeaways here? We should not only check if the file exists, but also if it is a symbolic link or points or something. Yeah, so we should be checking before we open files, right? What type of file is it, right? It's an important thing, our modern unix Linux systems, right? Files, you can actually have multiple types of files, right? What are some other types? So there can be links, symbolic links, hard links, there can be actual files, there can be directories, what else? Devices, yeah, there can be devices, right? They can actually be the hard drive itself. They could be pipes, so unix pipes, right? Or sockets, I think it's also called like unix sockets, right? So that's a way for applications to communicate. So yeah, if your program thinks that it should only be reading from a file, right? You better make sure that when it opens something that that thing is a file, that you need to actually do these checks to make sure your program is doing what you think it's doing. So you should check for unexpected types. You should check if it's a symbolic link or not, right? That's going to affect what you're doing. So what was so, this DTAP application, right? Was creating a temporary file. What was the problem with that? It wasn't checking if the file existed or not. Yes, but what else? Why else could we do it? Let's say, well, let's say it still wasn't doing that, is there another way they could have tried to hide this or prevent this? A lot of error catching logic, but they got some kind of error, right? So it aired out, but it still changed file permissions even after it stopped the error. Yep, yeah, so it had file error permissions. So what kind of file, this was like a temporary file, right? Yeah, so it was predictable, right? We could predict exactly which file it was going to open and so we knew exactly which thing to create. Is that UID? It should immediately, I don't know the exact UID thing as soon as it's, or like things could be done with them. That's a general set UID approach that I think we may talk about later. It's often hard though, because this was right at the start, right? It hadn't gotten to do the thing that it probably wanted or needed to do, right? For a web server, it's really easy because you only need set UID to find support 80. And once you find support 80, you never need to be rude again. So you can get rid of that. But for a lot of applications, the whole point is the program needs, the whole program kind of needs to be run as root. Then you get into, well then we should design our programs to separate the privileges out, right? So that only that thing that needs root is root and whereas everything else, all these temporary files and everything are in separate processes with different permissions. That is a good design goal. Yeah, so one of the big problems is we shouldn't, these temporary files are predictable, right? We are able to know the exact file that was going to be created and we were able to create it first, right? So the fact is that it was a symbolic link and it was a temporary file that we could predict, right? So this is another instance where essentially randomness or lack of randomness comes into impact security, right? So where's another place that we saw this randomness? What was that? TCP sequence numbers? Yeah, so TCP sequence numbers, right? So if the sequence numbers aren't random enough, we can inject in the TCP strings, we can hijack TCP strings, we do a lot of really cool stuff. So if you want to make temporary files not be predictable, you should use this system called make S temp. So what's the S for here? Secure. Secure, yeah, really annoying, that was just one letter. Should be like make temporary, secure comma, every other version is insecure, don't use them. End comma. Actually, for me, that's one of the crazy things about these languages. Once you have make temp, right? You can't ever change that name. So you have to make a secure version of make temp. But a secure version of make temp means the other version is inherently insecure. So you should have called it like make temp insecure or just delete it and never ever use that stupid function ever again. That was actually one of the things that impressed me when I looked at the Windows 8 metro apps is they're using JavaScript, right? I mean, they use JavaScript and C sharp and everything, but they use JavaScript, but functions like eval in JavaScript are very inherently insecure or like write HTML also insecure. So they actually change the names. So by default, it does proper escaping and everything when you write HTML. There's a separate version called write HTML insecure so that you as a programmer actually know that you're doing something insecure when you're calling this function. So you better make sure you're doing it with the right versions. And it's interesting thing about like, all this is the S. It can be termed as makes temp, right? It's a great project. This is actually, yeah. In my mind, a lot of the cause of the problems is developers don't understand the difference between the two, right? And it's clear from the name. Why would you ever understand that? Okay. And we get to one of my favorite class of attempts, talk to, talk to, fake talk to. It actually does stand, oh, that wouldn't be any fun. I was gonna say, it'd be fun to guess what this acronym is, but I think it's too long to try to come up with something coherent that's mildly security relevant. Okay, so this whole thing stands for, it actually is kind of nice. So the talk to kind of sounds like a clock, right? Fake talk, talk to. So it's time of check to time of use. So the idea is, if your application, so as we just saw right before, the application checks. So the problem was the application wasn't checking that that file doesn't exist before creating it, right? That was the example we just saw. So you wanna solve this. How are you gonna write the code that checks it? Can you read that now? 200%, okay. Can you read this? Okay, so we have this, what was the var? See, I only get the actual one. Of course, that's exactly what I wanted to do, okay? var, dt, app, config, app, and there it displays zero, right? So this is the file. So you're writing the code to check this. So you wanna check, let's just talk about checking if this file exists first before opening it. So what are we gonna do? If, what, like, we'll just make out a function, so they don't have to be perfect. If there's a fire. Do you remember that stupid thing? Okay, so if the file does not exist, then what? Like, open that file, right? Does it check? Right? Does the check that we wanted to do the check that probably all of us would implement until you take this class and so you realize there's a problem with this? But, how do you do this? This is what you do, right? So you're the operating system. Right? When you, this file exists call eventually goes to you, the operating system, right? So you're the operating system. How do you determine whether this file exists? Generically, I don't have to go into that. I read the ex2 file header and then do all this other stuff. Should reverse the path down? What do you get there? Yeah, should reverse the path down. So you start at root. You see, does that have a folder called bar? A directory called bar. Does that have a directory called dt? Does that have a directory called app config? Does that have a directory called app manager? Is there a file or directory called generic display zero? And then you say, you return true if that file exists or you return false if that file does not exist, right? Perfect. Then, you're the operating system again. We get to this line, then we open up this. What happens here? Let's do this again. It does the same thing, right? It says, open, okay, start in slash. Does that have a directory called bar? Does that have a directory called dt? Does that have a directory called app manager or app config? Does that have a directory called app manager? Okay, open the file in their generic display zero. Which is, wow, we can say at this point it just opens the file. Yeah, it's gonna be able, I know it's all other stuff, but it's a little bit more. Did this actually solve our problems? What was the problem? One problem was that we were able to create a symbolic link there before the program access it, right? So does this solve our problem, right? So why doesn't this solve our problem? Well, from a security perspective, there's a big timing because you're traversing down the directory twice. So an attacker could create a file in between the first and second problem. Yeah, so in this file exists check, right? Operating system checks all the folders. Checks returns true or false so that file doesn't exist. And then later, right? So, you know, are these two lines gonna happen simultaneously? Can, how many things can happen in between those files of these lines executing? Not more than two lines. Say that. Not more than two lines. Not more than two lines. I get it. What? I don't know. I'm not sure you think about that. A lot. We'll go with a lot. We'll go with a less mathematical version of a lot, right? Maybe not in this process, right? This process has very clear. So maybe if this thing happens, this thing happens, this thing happens, right? But what else can be running on the system? Anything, right? We can be running multiple processes on the system. We can be doing anything we want on the system. So what if in between this var-dt-act-config act-manager-generic-display-zero file exists, check happens. It says, nope, the file doesn't exist, right? Then before anything else happens, we create that symbolic link. Now when we open it here, what's gonna happen? It's going to open a different link. It's gonna open that symbolic link, right? It's gonna open var-dt-act-config-act-manager-generic-display-zero, which actually is a symbolic link to ETC shadow, and it's gonna chmod ETC shadow as zero by five. So this is the exact, I mean, this actually why it's such a cool name, Taktu. There is some time, right, between the time of check when you're checking, in general, Taktu is checking permissions, basically. So there's a difference between you're checking some permissions and when you're actually using that file or those permissions. So here I'm checking permissions. I'm going, okay, var-dt-act-config-act-generic-display-zero does this file exist? And then I'm trying to open that file by the string so the operating system has to find that file again. And in between anything could have happened. So how can we exploit this? No, no, that was just wrong code, sorry. That was bugging me. So if you want to exploit something like this, using the other thing we just wrote, what would you do? What are some techniques? What are your goals here? Such that context switch after running the first. Yeah, so we need to somehow, in between these two lines, right, we want, before this line, we want them to do that file not existing, and then after that we want there to be that symbolic link. How do we do this? Probably we can be listening to some function calls. I mean we can list all the processes that are being currently executed in the system and then if something like this props up we can just say, okay, we can quickly go and create that. I don't think as a normal process we can listen to the system calls of other people's processes. So that requires debugging and more privileges. And once we can debug a process we can actually have to pull control over it. Like what I meant was, as we mentioned, we would be traversing through the folders doing this. So that would be a process system called. So that would be listed, even if it's not within the scope of this file. Interesting, I don't know if that's true, but that could be a way to do it. Yeah, actually you could see the traversal and then when you see it hit some app manager thing then you change, you make the symbolic link, yeah. Maybe root force it. Root force it? Yeah, I'm sorry. You run into both of them and do separate threads and you just slightly start delaying the one that's gonna run the file because it's just gonna fail out every time. So as soon as it fails out and then reset you do it again, do it again, do it again. Yeah, that's actually the easiest way to do it is you just can have one continuous process that all it does is create the symbolic link, delete the symbolic link, create the symbolic link, delete the symbolic link over and over and then you just keep running this because you only need it to work once, right? Once it works once, it's fine. So you just keep going on that. And you can actually, so here you're trying to get in between these two checks, right? So there's some time in there. So how do you increase that time so that you're actually more likely to get in there? Any more processes? Yeah, you can run more crap. It doesn't have to be processes that do that, right? You just run additional, create additional processes on the system so there's more load so now the operating system has to switch between all the threads and everything. So you can actually increase this pretty significantly before these two, between these two. So you're increasing your chances of hitting it and you only ever need to get it once. So there's actually another way to do it that is really cool. So that's creating load on the system. You're basically trying to slow it down. What happens when one of these things in a path is a symbolic link? So let's say it opens up VAR, it opens up DT, it opens up Accomfig, it opens up App Manager and App Manager is a symbolic link. Yeah, at that point too, right? It's gonna go there and then it's gonna look up generic display zero in there. So it's actually possible so you can actually create these symbolic links that I think the limit is like 30 or something. You can have these crazy symbolic links that the application has to keep going down in order to finally resolve this generic display zero. So the idea is you make this process really long and this process of the open really long and so you're increasing those times you're increasing the time between the actual checks. So you can actually do this. It's pretty crazy and kind of fun to do to like make all these symbolic links and it just increases the time that you have to do this. So that's why it happens like that. It literally won't change between now and then. Okay, so talk to time of check, time of use vulnerabilities. They're all about trying to explain this race condition. There's some race condition in the fact that you're checking something versus where you're actually using something and even though that gap is really small, as we saw, we can make it bigger and we can just keep trying over and over. We all need to get that overlapped once and then we succeed. So the time of check here is checking assumption A on some entity. So we're checking, does this file exist? Then the time of use is we're actually using that entity and we're assuming that A is still valid. So just like in that example, we've opened, we've checked, does this file exist? And if it doesn't exist, then we open it and we're assuming that the file does not exist when we open it. But we can control that. There's that window in between there where we actually, as the attacker, we have our own time where we can invalidate that assumption. We can make it that there actually is a file there, haha, even though you just checked. It seems kind of crazy to think about it. If you were to look at that code and be like, is it ever possible for the file to exist at this line? You probably say no, right? I just checked right above there that that file does not exist. But the file system is independent of your program, right? Other applications can mess with the file system. So that's kind of the key there. So yeah, you basically need to get your time of attack in between the two checking, right? So if you can do that, you're golden. This can also come if you have some kind of race, so this is kind of like a, we talked about it as a file system access problem. This can also come if you're having a multi-threaded, multi-process application where you're accessing the same data, right? So somebody's writing to the data and they're checking that it's not valid or invalid and you're actually able to put some kind of, to change the data in some way to alter the execution of the program. So it's kind of more of a general way to talk about that. So specifically in Unix, the access system call, this is a system call that returns an estimation of, hey, can the program access this file? And it's based on the real ID of the application. So what's the real ID of the application? So what are the different IDs? User ID. Of just user IDs, not group IDs. There are group IDs. There's another set of these for group IDs. Just a second. Yeah, real ID would be the ID that the system would, the process of it, so when it is ready. Yes, so real ID is the ID of the person who basically created that process, right? And what's the other type of ID, user ID? The actual ID. Effective, yeah, exactly. Effective, actual ID. Effective means, hey, I'm executing as if I was this user ID, right? So effective ID, so when we run a set UID application, our real ID is our user. That program is running as real user atom ID. But its effective user ID is root. So when it's file accesses and execution, it's accessing it as if it was root. But this access system call tries to estimate, hey, if we were atom ID, could we open this file? So why don't this be useful? So you're running a set UID, yeah. This particular, I can access it at this age when we can live it. Yeah, whether the person who executed this program could access it, right? We know we're root, we're effectively root as a set UID program. We know we can access everything. But we may want to check, hey, could the user who ran us, who started this program, right? Maybe we want to execute something, open a file on their behalf, but we don't allow them to access any file, right? Only those files that they can actually access. So the open system call, right? Open is how you open files. This checks the effective user ID. So key question is, what are these taken as their parameters? So access takes in a character pointer, a string, right, of a filename, and the same with open. So the code looks like this, hey, if the access to filename is okay, right? This user can access this filename, or I guess writeable locating, so can the user access and write to this file? If that's zero, so zero in system calls means that it was successful, right? Not zero means that there was some kind of error. So if it can, then open it, right? So open that filename as writeable. If that fails, then send an error, otherwise write some buffer to that file descriptor. So what's the problem here? What is the code trying to do? Just grab it in English, what are they doing? What was the intention? To create the file and write something to it. Not necessarily create, but yeah, read, write, dimensions here. It will, I think it will create it if it doesn't exist, open file will. But it could already exist, we don't really care about that. But what's this access check? Why the access check, yeah? It's trying to downgrade the power of being actually choosing it if they don't want it. They only want to write to this file if you, the first real user ID actually got it. So this is from a set new ID application, right? And it's trying to ask, hey, could Adam write to this file? And if I could write to it, then so my pass in filename for access to EDC shadow, should say no, Adam can't write to that file. The program's running as root, root can write to that file. But Adam can't write to that file. And on this next line when we call open, it's checking can root open this file. So what's the problem here? How do we do that? Can we use like access on the basis? Because access is usually made over the anyway. Right, it either had to be, well, the same. It had to check the same thing, right? Or what's another problem here with the filename? I mean, how do we specify filename? I just a character array, so then what does the file system have to do? What does the upgrade system have to do? Right, it's just a string, you have to parse that as they go in each directory, open up each directory to finally find the file. But how do you attack this? Attaining a tag to do what? So what would you do? You could describe it like a high level. Well, it would check if the file exists and if the permission says that either that it doesn't exist or doesn't have rewrite permission statement. After that, you would actually need to check the file into that directory. So what's the check that we need to pass? So let's do that first. So first, how can we pass this check? Create what? A sim link to what? To the file that we can write to. Yes, okay, so the first thing, well, okay, let's see about that. So first we can create a sim link to a file that we, ah yeah, we can create a sim link to a file that we can access, like cat or food or whatever, any file that we own we can create. And then in that time between the access check and the open check, then what would we do with that sim link? Switch it to the file that we really want. To the file that we really want to write to, like ETC Shadow or ETC Password, right? And if we just keep doing this and keep running this code, at some point our buffer's going to get passed to that file, because you need to, You need to check if this access check the permissions on the sim link itself or doesn't have. That's a good question, I don't know. I think it resolves. Yeah, so it'll resolve to the sim link, because that's something you can see from the example is my sim links have their own security permissions, right? So Eric's question was, well, does access actually resolve the symbolic link to what it points to? Or if you pass it to symbolic link, does it just check that and open check the other one? Probably check the other one. Couldn't check, yeah, probably both. I mean, it should go all the way to the end. That's the only thing that makes sense. Otherwise it would be super trivial to buy that. Cool, okay, so we'll stop here and when we get back and talk about how to fix these vulnerabilities.