 It's nine o'clock on a beautiful Thursday morning, a little chillier than I used to, but let's get started. Can anyone, can the Zoom just clarify that they can hear me? Everything's going good? Yep, okay. Cool, let me know I'm trying to monitor the chat. All right, and we're gonna start off as promised with homework assignment one. Yay! You guys can't see on the Zoom, but they're like going crazy in the crowd. They're just, they love it. So let's check it out. So I'll post this right after class, the actual text. I am purposely not posting it now because I kind of don't want you to get started right away. Like you, you know, the point is right now we're gonna go over things. So I'd like you to follow along to what we're doing here. Okay, so assignment one, you have over a week. So do next Friday, the 28th before midnight MST. And I just feel like I'm just some of a bouncer keeping hitting the submit button. So, okay. So first thing, sign up for the course Piazza. If you're not on there, I saw somebody in the Zoom chat asking about the Discord link. If you're on Piazza, you know the Discord link. It's not worth any points to sign up for there because I figured I want you to give you credit for working on the bulk of the assignment. But if you're not signed up for Piazza, you will miss things. I'm not gonna post, I don't respond to Canvas messages. I'm not gonna send you Canvas messages. It'll be updates on Piazza. And those will probably get reflected on the Discord, but that's kind of out of my control. The mods will handle that. Okay, so do that. If you haven't done that, just do it right now. Then you can come back. Any questions about that? Pretty simple, sign up for Piazza. All right, cool. Now the bulk, some of you were a little bit over anxious and started on the homework assignments from last year. We were changing things this year and doing things differently. That's not to say that what you did is useless. I'm sure you got some great skills, but it's not exactly the format we're gonna be following this year. So this year we're actually gonna be building on and using the Pone College system, which was created for 466. So this was kind of piloted in 466. I have a small distinction here where I was talking to Jan Schoesch-Dachvili, the professor who helped create this, about how to make a expert coach for the flag team. And the thing I was telling him was like, hey, even in high school, when we were on sports teams, we would practice for like two hours a day. But nobody really practices in cybersecurity and people don't practice necessarily for like dedicated practice. The other thing you do is you like drill skills you've done things like musical instruments or sports or anything like that. You drill the basics so you don't have to think about it in a game, right? None of the people playing in the world have to think about, how do I pass the ball over there? Like they just do it because they practiced it so much. And so that kind of, that idea came into Pone College of, huh, what if we did like dedicated practice? So rather than doing one buffer overflow and saying like, hey, you now know buffer overflows if you do 50 buffer overflows each slightly more difficult and varied so that you really get the hang of understanding things. And so I think it's been three years now where we've done this or that they've ran Pone College like this. The other cool thing that we've done with this so Pone College is a like semester long course that covers basically binary exploitation. We were able to take this content and condense it down to 15 weeks and we ran a workshop with the NSA and people in the DOD to take them up to where they needed to be. And this format is actually super helpful for that for developing skills. So that's the format we're gonna use. Obviously this is a 300 level class, it's different. So we're, and we're gonna touch on a lot more different areas. And basically the goal is you're gonna be given a series of challenges. When you solve a challenge, you get a flag. You submit the flag to the system and get points. And that's kind of the basis of what we're doing here. So this is just like a capture the flag. And actually I think the infrastructure this rounds on is a heavily modified version of one of the systems that is used to run capture the flag things. We're gonna go over right now how to approach the system. So there won't be any, as many questions I'll actually go through this. We'll go through this right now. We'll actually solve some things together so you can come back, watch this video and get a jumpstart on things. Important thing before we start. So when you create your account, you'll create a username that will be public to everyone. So there's just one of the fun things about doing assignments like this. You can see the scoreboard of who's solving things and you can see who like the first person is to solve all the challenges. It's just kind of the fun thing to fight for for the people who are slightly insane. And, but just remember that this username is public. So if you put it as your name, everyone in the class will know that that is you and because those assignments are highly correlated with your grade of the class then people will be able to kind of understand where you are. So if you don't want that, just make it an anonymous random name that's not associated with you at all. Like there's go to a random.org generate a random character string and that can be your username. Yeah. Is this being recorded? Yes. Okay. Yes, every class should be recorded. Is it actually being recorded as a good question? Yeah, it's got the little dot here. One. Yeah. Yeah, I don't have to do this again, so. Okay. So usernames, if you want to claim them remain anonymous, feel free to pick a random name. Otherwise feel free to dig in your coolest hacker name that you want to represent yourself as if you're more of a Neo or a Morpheus or whatever. Feel free to do that. So the website that I set up yesterday is pon.cse365.io. So this is the website. So when you go here, this will take you to the register page. I have already registered. So I will log in. And when I log in, it'll take me to the challenges. This program interaction is our first stop here. The goal here is to get you familiar with using the command line and just interacting with programs. So how do you execute programs? How do you pass arguments to the programs? How do you do that? Not just from bash and from the shell, but also from shell scripts. And how do you write a C program that calls another program? And we'll also look at Python as well, because while we're not gonna necessarily require that you use Python going forward, it is kind of the one of the easiest ways to write. This is basically what everyone writes exploits in now because there's really good libraries like home tools. And yeah, okay, good thing, Mr. iPad. So the question is, how do we know if we solve them if we use an anonymous name? So when you sign up, I should have mentioned this. When you register, well, it's not gonna let me register because I'm already logged in. When you register, if you use your ASU email, that way we'll be able to easily know that it is you. And then we'll have to, we'll figure that out as we go forward. So if we don't know and we don't have an account for you here, we'll have to tell you and then have to worry about it. Okay, cool. Let's go back to the thing. Okay, so yeah, when you're registered, you'll get access. There are 59 challenges. I know many of you maybe recoiled at that when you saw that on the screen. It is scary, but we'll solve some together as a class. They go fairly quickly. There's nothing, like I said, we're gonna be going over similar concepts just in different applications. So once you kind of master it in the command line, shell scripting is much easier. And then Python and binaries and C are really similar as well. So these, and just to give you a, just to give you some perspective, this is actually a refresher module that we've taken from 466. And we've, we're doing it here now because I think you guys will learn a lot from this. They do 148 levels. And so we've shrunk it down considerably here. So not as crazy. Okay, so each challenge, so the way scoring works, I know you all care about your grades, which I understand each challenge is worth two points. So 59 challenges, but with a max a cap of 105 points, maybe anything you solve after that, you're, that's like, you're just showing off that you're super awesome. You don't have to go in order. You can go in any order. It doesn't really matter. And yeah, so you can, so you can earn up to 5% extra credit on the assignment by continuing to do levels after the 50, if you want all 100 points, it's up to you. You'll know exactly how many you have solved. And it will say on the site when you log in, hey, I've, you solved 50, whatever, 50 out of 59. And then you know, hey, that's a worth of 100 points. Can you fail challenges? Sure, you can not solve challenges. I wouldn't call it failing, right? Because we don't know if you've solved it or not solved it. But yes, it's essentially a binary. Either you've solved it and got the flag or you haven't. There are already solves for the first four. Yeah, I'm not surprised the website is live. So I knew people would be, yes, use your ASU email to register. Okay, some helpful tips before we jump in and we'll start solving some of the initial ones as a group. And then I'm going to demonstrate how to approach. I'm going to show you in class, everything you need to know for the extension. Okay, you have as many attempts as you want. So this is, yeah, you'll see, like you'll actually spin up a Linux like environment with the challenge in it. You'll have a terminal where you can access, you can actually do this 100% on the web, or you can SSH into it and use your terminal or putty or whatever to access the challenges. There's a lot of freedom in how you want to approach this. The assignment is not publicly available. This description is not available. The POM site is available. Okay, read the program's output. So we'll go through this together. Each program will tell you what it wants and what it's checking for. And so this is, and oftentimes there'll be hints there that say, hey, go read about this thing, like FIFO pipes or go read about symbolic links. So just make sure as you're doing it, you're keeping track of what it's asking you. It may ask you, hey, pass this specific string as my argument to get the flag. And then you do that and then you get the flag. Cool, all right. So we'll just jump in because I think it's much better than me chatting. So program interaction. Oh, I haven't, I need to log in. Sorry, log in. Program interaction. So when I hit that, there are two buttons for me here. A start button, a practice button, and the flag. So the practice button, I will launch that quickly. It should say challenge successfully started. If it says something else, let me know because that means we got problems and I'll need to fix them. From there, you wanna go into the workspace and this is actually gonna load up, assuming everything works. Yeah, so this will load up. I believe this is VS code running on your instance, tunneled over the, over HTTP. So I should, where is my terminal? That's interesting. I should go yell at Connor. Says I'm connected, says this, this, this. I swear I checked this last night and it worked. See, maybe it's because I opened up. It shouldn't be, but let's just check this out. What if I start the challenge? So the difference between these two modes, as I'll show, is a practice challenge. You are rude, which means you have full control over everything. You can just read the flag. You don't have to do anything fancy, but it doesn't get you any points for doing that. Are you crashing the website right now? Quite possibly. Okay, so I should go in and kick you all off. I claim that it's all of you messing with the website. So, okay. So the way you can access the website is, so in your profile, or so in settings, you have your username, your email, you can change your password here, whatever, under SSH key here. So this is, I'll post links to articles of how to create an SSH key. So this is a, what we'll get into with cryptography. This is both a public key and a private key. So you keep the private key safe. You can send it to anyone. So this is my public key. I can not care that you're all reading my public key because you can't derive my private key from the public key. But as we'll see with cryptography, I can prove to like this website that I am the one that owns this private key based on that public key. So for instance, what I do is, now this is something you gotta be very careful about while you're doing in front of, I have it there. When you're doing this in front of a bunch of people because if we look at my dot SSH directory. So there's four different files here. This ID, RSA, ID, ED, 25519, these are both my private keys. My public keys start with dot pub. And so if I want to add my key there, I would go dot pub. Now, again, so it's really difficult if you're doing this and just hit enter, that will show you all my private key and I'm screwed and you'll get access to any site that I have access to. If I do that pub, then I can see my public key. So I would copy this, paste this into this box here, hit update, and then what I can do is SSH, I believe it's hacker at phone dot csc365.io. There we go. So now I'm in, so this was the level two container. So I'm the user hacker. I can run ID to look at that. I should be able to now, I'm gonna go in, start level one, practice. Oh, does it just change like that? Improvements. Okay, I'm in the sudo group. So I can run the sudo command and be a group, I believe. Yeah, in the root directory of every instance is the flag. So we're gonna kind of get a bit of a crash for its information here. The flag file is owned by root. That's what it says here and here. Owner root, group root, and only root can read the flag. Does that mean as the user hacker, if I try to read that flag, it'll say, hey, permission denied. You cannot access this file. Now because I'm in practice mode, I can read the flag. Of course it's just a practice flag. So it's not gonna tell me anything. It's gonna say, hey, this is just a practice flag because I, as this, I have full root access. I can do whatever I want to this system right now. And I should be able to start, let's just reconnect. Wow. But now if I look at my ID, I'm just in the group hacker. If I try to use sudo, I can't. If I do ls-la flag, if I try to cat the flag out, it's gonna say permission denied because I can't do it. And I can't do it as sudo either. And it's telling me, hey, well, this is because we broke the sudo by name. It doesn't matter because I'm not in a sudo group. So there's no way I can read this flag. So how do I read this flag? So first let's look at where I am. PWD prints out my current directory. So I'm in slash home hacker. If I look for slash, I can see that there's a directory called slash challenge. If I go into there, I'll see two things. So this is something I noted in the, on the page. So the thing I want to execute the program is interaction underscore level one. This checker.py, you're welcome to look at it, read it, whatever. But for reasons we'll get into later, if you execute that directly, you won't actually get the flag. You can only get the flag if you execute this interaction underscore level one. So level one will be underscore level one, two will be level score under two, and so on. Now, why can the question would be, well, let's say I'm able to, actually let's just execute this and see what happens. So I can use a local path to execute it. I can say in the current directory, dot slash interaction underscore level one, that's going to execute this process. And it's going to say, okay, performing a bunch of checks. You pass these checks, you receive the flag. Awesome, performing checks. Make sure the parent, checking to make sure the parent's process is the batch shell. If this is a check on the parent process, then most likely is what you want to do by default, blah, blah, blah. The process, so this is the challenge itself, checking, hey, the person who's calling me is user of in batch, and to pass the checks, the executable must be back. So you have passed the checks because I'm running my shell now, which is the batch program, and batch is executing this program. It's a success. You've satisfied all the execution requirements. Here's your flag. If I can take that flag, put it into the website, submit. Correct, so I just hold the first level. So the first one is literally just execute the challenge. There's a decent number like that, or somewhere like that that will be more and more difficult. And okay, now the question is, why did that happen? So presumably whatever's in here is inside the file of flag. How come I can't see it, but this program seemingly can, and can show me the flag. Yeah. The program has high efficient access to the user. Yes. So the reason is if we look at the, so there's several things to look at here. One thing we can notice is if we look at challenge, it's like this red color. So my terminal is automatically showing me that it's something weird and different. And the reason is if we look, so these on this output here says read, write, and executable. So this means these first three are for the owner. So the owner is group. This means group can read the file, right to the file. And an X means execute and S is special. We'll get to that in a second. The second one is the group. So this means anybody with the group group can read it or execute it. This last one is everyone else. So hacker, the user hacker is everyone else to this. So this means that I can read this. So I can cat out this file. Of course, it's a binary file. So like it's going to be ones and zeros and stuff that is not going to make sense necessarily. I can read it and I can execute it. So this S is special. But if we look at, we can use which cat to tell us which thing to execute, which, and I'll explain that in a second. So I get user bin cat. So I look at the binary user bin cat. It is read, write, and executable by root, readable and executable by the group root and readable and executable by other. And yet I can't cat out the flag. It'll say permission denied. You have this program to get to it. So the key difference is in this S here. So the way process execution works on Linux is right now, if I run the ID command, that shows you what user ID I am. I'm user ID 1000, which is the user hacker. I have group ID 1000 hacker, which means that every process I execute executes as the user hacker. Right? If I could run a process and run it as root, then I can just have access to the whole system. So what this means is when I'm typing this in, what I'm doing is saying to bash and we're actually gonna look at how this happens. What I'm telling bash is, hey, execute the program, user bin cat, pass it the argument slash flag and the operating system says, okay, you're executing this process. This process user bin cat is going to execute as the user hacker because that's who's starting me. This is different because of this S. So this is the set you ID bit, which means when you execute this process, run it as the owner of the file, not as the user who called it. So when I run this, this actually runs as root. I wish there was a good way we could see this, but I can show it pretty easily with bin cat. So I'm looking for, I'm listing out all the processes that are here and then I'm grepping for cat. So this, yeah, so here bin cat is running as the user hacker and so that's what it's just waiting for our interaction there. And that's why we're able to execute it. So this is basically how the status of all the challenges are. There's a flag file that only root can execute and the only program on this entire system that can execute as root is the challenge file. So that's the basic format. Any questions on the basics here? So you can all solve the first one. Super easy. Yeah. Is there anything that I want to explain? It tells you what it is. So these are kind of like self describing challenges. So like that one, it's kind of silly because it's the, so we can, it's kind of silly because it does all the checks and then just gives us the flat, right? Not all of them are going to be like that. So usually it will fail. You read the output to see, oh, it's looking for X, Y and Z. So let's do the second one together. I think that'll be a good, good example. Oh, that's still level one. Not what we want. Level two. I fixed this. All right. I'm just going to try this real quick in here. Maybe I can see what the deal is. Unable to retrieve. So something's going on. You should be able to do this all in your terminal. You should like, so I'm sorry that that's not working right now, but actually I can show you really quickly in the dojo in the 466 version. This is what it should look like. So I log in. Actually the first challenge I think is the, basically the same. I then go to the space. So I can have a terminal here. So this is the terminal running in the browser. That's exactly like the terminal I was just aged into. So I can do the same thing to change the challenge directory. I can then execute, they call things different, but I can execute the same thing and get the flag. Do that all within, within here. And you can even believe, yeah. So you can even save files. So you can save files from the editor here in your browser onto the remote system. So I can call this hello class. And then when I, sorry, I know this is small text, but now if I go to my home directory, I can see that there's this hello class file. So cat, yeah, so it says hello world. So that's the contents of this file that I just added to the browser and saved into the thing. So you can edit things in there. You can do kind of whatever is comfortable to you. Okay, yeah, must be these things aren't installed or something is wonky. Okay, what were we doing? The second level, okay. So where do we go? So we're in here. Oh, the other thing I'll mention is that so if I cat where I touch a file called hello world 2. And then I change to, and then if I change to level one, so I start this again, it's gonna connect. I look there, I have the same file here. So what this means is you're everything in your home directory persists. So anything that you save there will persist from execution to execution. Everything outside of there will be erased and will be completely gone. So if you want to save stuff, save it into your home directory. Your homes will always be slash home slash hacker. So that's consistent for everyone so you don't have to worry about that. Okay, so now we're going back to level two. Let's do level two together as a lovely class. So it's the first thing I do. I excuse the challenge. Yeah, new challenge, interaction level two. For those that see like I'm not typing this all out. I type like the first letters and hit tab. Tab tries to autocomplete based on what it thinks I mean there. It's a nice shell feature, so you don't have to do all that. So now I excuse there. And okay, it was saying, hey, this challenge will now perform a bunch of checks. If you pass these checks to receive the flag, forming checks in the parent process, checking to make sure the process is the batch shell. So again, we're executing this from batch. This is good. This is, so it's saying that our process is executable as user bin batch. To pass the checks, the executable must be batch. Good, we've passed the checks in the parent process. This program expects you to enter a simple password specifically and it's giving it us this password. Send it now. So it's asking for input. So if I put hello, it's gonna fail because, and it's not gonna give me the flag because I did all of the requirements. I entered the wrong password hello instead of this thing. So I can just copy this thing, execute it, reading the input, paste that in, hello. And there we go, I get flag. Paste that in there. And then I'm level done, go to level three. See, we just did these in, what was that? Less than a minute for the first couple, but nothing crazy. Let's do the third one. Challenge successfully started. Go back here. Now enter the batch shell. So the tests, okay. So we could read this. This is actually, I believe all the same except for here. So this test is, hey, my argv1 should have a value of bx, whatever, whatever, let's check. It actually has an assertion, it fails. And so what it's looking for is arguments passed into the program. So we're gonna look at that in a second, exactly how that's done. But essentially all it wants is, oops, hello, that's not what I wanted to do. It wants us to pass this as the, it's telling us argv1. So argv0 is usually the name of the program that you execute. And argv1 is the first argument, argv2 is the second argument. And this is literally, what happens is under the hood, and we'll look at this, is what batch is doing is saying, oh, you wanna execute this by trying to challenge interaction level three. And then you wanna pass it, the argv0 of slash challenge slash interaction underscore level three, and argv1 of whatever this is. And so if I hit enter, it'll say, great, good success. You successfully did this and put it all there. And it's checking that you passed in the correct argument to the program. So again, this is just about how to interact with programs, execute programs, give them input over standard input, pass arguments through the command line arguments, pass arguments through the environment. These are all things that, oh, that's not gonna be a good flag. This should be a good flag. But, all right, there we go. We just solved the first three levels. So now let's get it to be more difficult. Let me think. I should have got the, exactly up here, but let's try level seven, maybe, but seven. So then eight should be the one, next one, let's kind of. So level eight says, so the test, making sure the process is a non-interactive shell script. So we did not satisfy the execution requirements because we need to actually write a shell script that's going to execute this command. So a shell script is nothing more, so I'm gonna use this thing as EmaxPerson. So I'm gonna create a file called level eight.sh. And essentially, so what this is getting you used to writing scripts because oftentimes when you're approaching a security challenge, you want to script thing. You can't just type in the commands or maybe you need to read something from the command. So oftentimes when we're doing some kind of binary analysis or trying to exploit a vulnerability, you actually first use one vulnerability to leak information about the program and then use that to create your exploit that you then send back to the program. So the actual, like the shocking thing for a lot of people is that it's not complicated programming usually or complicated math. I mean, the only where it gets complicated, I guess, is doing like while loops when you're trying to brute force something maybe or I guess the other complicated thing is doing like a binary search over a value to try to determine things, but overall the types of programming is not super crazy. So what we want here is a back script or a shell script is literally just all the commands that we typed into bash just turned into a script that will automatically do that. And what these ones when it tells you, hey, I want a non-interactive shell script, it wants you to write a script that does whatever it required. So like calling the process. And so we, what's the program we want to execute? Yeah, it was challenge, what interaction level eight, I think is where we are. And so it wants it to execute that. So one thing would be, let's just do that. And then if I try to execute this shell script, it says permission denied. What, why do I have permission to do this? I just created this. What's the matter here? Yeah. Yes, so the problem is it's not executable. So the permissions that we have on this file and we looked at those permissions, the only permissions on this file is the owner of this file can read it and write it. The group can read it and everyone else can read it, but nobody can execute that. So to do that, we use the change, C-H mod, the change of, I can't remember what mod stands for, I should know that I'm, and if I didn't know how to use this, I would write man, C-H mod. And it would tell me that changes the file of the mode. There we go. That's the file mode, that's where the mod comes from, the file mode bits of each file. So again, if you're unfamiliar with any of the things that I'm demonstrating and talking about here, please, any command that I run, you should be able to run man, that command and that shows you the manual like this that tells you exactly how to use it, what all the options are. So we can do C-H mod plus X is to add, C-H mod plus X is to make that executable. So the plus X means add the execute bit to these file modes. And, so now we can see this is exactly what we want. So now we can see the permissions added this execute bit here and we've got that. So now we can execute this and why don't this even succeed? I know the thing I wanted to go wrong, but it doesn't give me the right error message. So, okay, let's look back at this file. Yeah, so the thing I'm missing is the shavings at the front. So what this is, if you've seen this before, you can do all this through general ASU EDU SSH. No, no, you're gonna SSH directly to this system so you don't use the general. How do you save in Emacs? Is that the question? Control X, Control S. So this is a way on Linux to say, okay, this isn't a program, it's not a binary file. What the operating system actually does when you try to execute something looks at the first two bytes and says, okay, does it start with a half symbol and then an exclamation point? Shabang, I don't know where Shabang is from. Bang is an old term for exclamation point. And then it says, okay, I'm gonna pass this file to bin-bash and that's gonna execute this file. You can use this to have a Python script that's executable, a Perl script, whatever. There's actually really cool things we can do this do here. So let's look at this. Yeah, there we go. So then everything works. So it's actually then it's calling bash and then what bash is doing is executing all the commands in our level eight script. And the only command that's happening is executing this. So this was kind of lame, let's we can do anything we want here just like we're on the terminal. We can say echo, hello, I'm going to solve level eight. And then we could actually change directory to the challenge directory and then we could execute dot slash level eight. And if I execute that, so it echo that hello, right? So just running my commands one after the other and you can, I'll be perfectly honest, I don't like remember all the crazy bash syntax but you can do branches and loops and variable like get variable names and do all kinds of crazy stuff. A lot of actually like server administration and these type of things are like a one-off script that you just wanna do stuff. Usually happens as a bash script. If there's something you find yourself doing in your daily life that you want to like executing several commands on a system, it's often really nice to put them into a shell script like this that will automate everything. Any questions on shell scripts? So this is literally just taking what you typed in and putting it in the interactive bash into a file, a script that's repeatable and executable. But nothing super fancy. Now let's go to level 16. So I believe the next seven or whatever are all using shell scripts instead of the other thing. I think I wanna skip one. Let's go here. See, I told you we'd be going through a bunch already in classic of this. You're like, I don't know, 10% of the way done. All right, level 16, Python one, and so 24 should be the binary. I'm actually gonna start with the binary and then go back to Python. How do you close Emax, X control C? I have to actually think about it. I feel my muscle memory just does it and I actually don't remember what keys that was being. So it's actually tells us a lot about, so it's failing and it's also giving us hints. So this is an important thing. Okay, so performing checks, checking to make sure that the process is a custom binary that you created by compiling a C program. So the goal here is you're gonna, for these sets of challenges, you're gonna write a C program that's doing exactly the same things that you did interactively by typing into bash and writing bash scripts and as we'll see, writing Python scripts. It's the exact same thing. So if you've already solved the other one, it's just porting to this new language or to a different language environment how to do this. Okay, make sure you're, well, that's weird. And annoying, but anyways, okay. This is a check for the parent process you find the exact family of system calls does not relate. So it's telling you hints of like, hey, if you're using exact, that's the wrong thing to use. The executable that we're using is user bin bash. If you're surprised by this, then it's telling you that parent process, yeah. It's saying, anyways, there's a lot of actually good hints in there. Okay, so let's look at, so this is exactly what it's saying. So system is a C command or is a system, no, libc. It's a libc function that will execute whatever command you pass in and pass it to bin sh. So this is just like as if it was kind of a shell script. And what we need to do here, level 23.c is write a C program for this. So what do we need to write for a C program? What's the entry point? The first thing that executes. Main, yep, in main, in arc C, character pointer, arc v, return zero. So is this gonna get us our flag? Please say no, no. Why am I doing this? So that we can see that we can compile it, right? The very first step, what I always like to do is to create a first very basic POC and then from there expand it out to do different things. So let's go there, PCC, level 23.c, I look, it creates an a.out file that is executable, execute a.out. How do I see that it actually returns zero from main? Yeah, so the return, wait, it's dollar sign question mark, yeah. So the return status of that program, the shell gives it to us in this special shell variable. So the cool thing here is if we go back, let's emax this, let's change this to minus one. DCC, execute it, echo it, we can see 255. So that's one byte. So negative one of one byte all zeros. Okay, so we can now successfully do that. So what's our goal? What do we wanna do with this program? Yeah, we wanna execute challenge, interaction, or challenge slash challenge slash interaction level 23. That's what we want to have happen. And what we're gonna do is basically do exactly the same steps that bash is doing when we're typing in slash challenge slash interaction level 23. So at the low level, and so this is gonna involve two things, two system calls, fork and exact VE. So actually let's start at the low level. So as always, if I do alt X, I can do man and I can do man exact VE so I can get the man page in my emax browser so I don't have to go back or I really use this a lot. So exact VE is a system call. So exact VE takes three parameters. The first one is a string, that's the path to the file you wanna execute. The second one is a pointer pointer. So the argument vector of argument you wanna pass to the program. And the third one is the environment pointer. So ENVP, we'll talk about the environment in a second. And so actually we can see that when I talked about the shebang, it's actually here in the exact VE that tells you, hey, the path name that you're trying to execute must be a binary executable or a script starting with a line of this form. And for details in a later case, see the interpreter script. So you can actually learn all about how that works and how Linux decides what to execute and all that stuff based on these things all from reading the manual. So let's see, so path name must be a path to a binary executable. RV is an array of argument strings passed to the new program. By convention, the first of these strings, RV zero should contain the file name associated with the file being executed. Does this mean it has to be the file name that's being executed? No, what's the word that tips you off to know? Convention, yes, conventions do not mean that it's mandated. It just says traditionally it is, but hey, nothing is stopping you from passing anything you want to RV zero. ENVP is an array of strings conventionally of the form key equals value which impasses environment variables to the new program. The RV and ENVP arrays must include a null pointer at the end of each array. All right, so let's go with this look like hope. And then this is really cool. So it tells us what's happening. So the argument vector and environment can be accessed by the called program main function which is defined as this. So this is exactly how when we type in parameters into the command line and we're passing arguments, what Bash is doing is eventually calling exact VE and passing in all the arguments we pass as the argument to exact VE which then ends up being our argument vector inside of our program. And the same with the environment. So if you actually don't know, you can specify this precise environment variable to get this and alter the environment of your program. So main actually can take three arguments. So arc C, the number of arguments are V the number of parameters, the actual parameter value, sorry, not the number. And the environment pointer is the environment. And another important thing, so exact VE does not return. So when we call exact VE, it should never come back to us. Why? Because the operating system completely replaces our process with whatever we're executing. So if we'll get into later, kind of more precisely how this works, suffices to say that when we're executing a program, so if we execute bin Bash and then that is, we call exact VE on something else, it replaces bin Bash with whatever we call. Now the question is, hey, but what if we wanna see if that execution was successful? So for instance, when we executed our program, we were able to get the return value, which means, hey, our Bash program must hang around somehow, right? It doesn't just get completely replaced because then we wouldn't actually be able to interact with Bash at all. So how does this work? Well, that is because of, oops, four ground three. That is because of a nice little, yeah, that is because of a nice little system I'll call called fork. So fork is how we create a new process. There's the newer API called clone, we can ignore that for now and just kind of focus on fork. So fork is a system call that takes no parameters. You can't pass in anything and what it does. So fork creates a new process by duplicating the calling process. So think about this, so you're Bash, you call fork. There's now two of you. You can think of it, Yann and some of his lectures talks of this like sell as a mitosis when it sells like split into new cells, right? It's kind of like that, you're split out, I mean, I should say the first thing when I'm doing hands splitting. So you can see on Zoom if you've never seen something like split into two before. So the new process is referred to the child process, right? So the one that gets created, the new one is called the child and the old one is called the parent. How do we know? So remember, we're writing code for this, we call fork. Now all of a sudden our process is duplicated it's exactly the same, exactly the same code that's executing concurrently in different processes. But we need some way to know, hey, are we the child or are we the parent? Yeah. Yeah, so the return value, right? It clearly can't be the thing that we pass in because we don't pass anything in. It's whatever the return value is. So let's kind of keep reading here. The child process and the parent process run in separate memory spaces. So this means it's a complete separation, right? They can't touch each other's memory even though they came from the same place. At the time of fork, both memory spaces have the same content. Memory writes file maps and unmaps performed by one process do not affect the other. The child process is an exact duplicate of the parent process except for the child has its own unique process ID. This makes sense. Every process on the system has an ID. If we create a new one, it obviously would need a new ID. The parent's ID process ID is the same as the child's. Yeah, so the operating system keeps track. That's how it has the relationship of parent child. Pa-pa-pa. Okay, these are not helpful. You can get into a lot of like, you can see it's pretty, okay, good, there we go. Okay, on success, the PID of the child process is returned in the parent and zero is returned in the child. So this is the key that we can look at to say, okay, was my fork successful? Did I successfully create a new process and which one am I? Am I the parent or am I the child? And this fork exact VA situation is very common in order to say, oh, I wanna execute some process to do some work for me and maybe you can get the results back or whatever. And so what we can do here, so what we wanna do is have a child execute challenge interaction level 23. So, oh, and the other thing we always wanna look at, the other thing that the man pages are super helpful for. Yeah, man fork. If you've ever wondered how to know what includes to put into your C programs, I know I was guilty as a student of never understanding this and just like went to the last project I did, copied all the includes through it in and then when I couldn't find what, like if I tried to compile in a complaint, I would just Google for what thing to include and then just throw it in. It's right here in the top of the man page. So it actually shows you here and I actually just copy these and paste these in. And this will then, those are the includes that are necessary to call for. I can look at exact VA and I can see I've already included this one, so I'm good. So I shouldn't have everything I need to execute this. So I need, so very first thing we're gonna do is this fork, right? So now we have to think, okay, now after this thing executes, I'm executing in two different places at once. So what do I want the child to do? Yeah. You want the child to execute? Yes, so I want the child to change into challenge interaction level two. So from the man page, if we went back and re-read that return value, we'd see that the parent gets the return of fork as the child's PID and the child gets zero. So I can have an if statement. If, oh, I hate the way that looks, okay. All right, that bracing is really horrible. All right. How do you do that? You can use whatever makes you happy. All right. So if PID is equal to zero, yeah. So now we're in the child, now we want to do the exec VE. So kind of if we think about it right in pseudo code, we want to exec challenge interaction level 23. For the arc V parameter, we'd want an array with the first one of, let's just say interaction level 23. And we don't really care about the environment. So actually we can do a trick here. We can actually just pass in whatever our environment is to the, to whatever we're executing. So we have this ENVP pointer. I'm missing a C in my interactions. Are you saying I can't spell? Yeah, it's okay. All right. So now I can do exec VE slash challenge interaction level 23. I need to create an array. How do I create an array in C? Yeah. So I can do a character pointer array. I think that's correct. We'll see the compiler will yell at us. And then I can just set, hey, I want RV zero to be interaction level 23. And then what do I want child RV one to be? I want it to be null, why? Exactly. It's what it told us. And if we think about it, we're passing in an arbitrary number of arguments, right? We could actually have, I think it's up to 1024, 2048 or something. It's a large number of arguments that we could pass in. But how does the OS know, right? In C, we'd have to pass either the array and the size or we'd have to have some way of telling it when there's no more elements in that array. So we use the null pointer here. So this says, hey, there's only one argument here. So when we execute this, arg C should be one, arg V should be essentially exactly this. And the environment pointer will be whatever we put in there. So let's see child RV and VP. Okay. Should I do anything after there? Yeah. Okay. Yeah. So the one thing to remember is if exec VE is successful, it completely erases this process and we will never execute this code ever again because it's just been replaced by whenever this new process is. So it shouldn't, I should never, I should be able to do anything here and that should never happen. Of course, if I was doing correct code, I would get the return value of exec VE check if it was negative zero, which is negative one, which I think what the doc say means a failure. And I tell the user, hey, I couldn't execute this file like you messed something up. But for now we can leave it like that. So what do we want to have happen if we're the parent, happy nice parent? Yeah. I may want to watch for their turn value for the child or I may want to stick around until the child's done executing. So there is a, my key bindings are slightly different. We'll need these, but we already have types. Yeah. Which fork is the child and which is the parent? So that's a good point, child. So if the PID is zero, we're in the child. Otherwise we're in here, which is the parent. And then what we want to do is wait for our troops. So what does the wait do? All of these system calls, I use the wait for state change in the child of the calling process and obtain information of the child's status change. That state change is considered to be the child terminated, the child was turned by a signal, blah, blah, blah. In the case of a terminated child performing a wait, blah, blah, blah, but child is always the same. Good things called return immediately. I believe we want wait PID. The wait system call suspends execution of the calling thread into one of its children's terminating. Oh, cool. Okay, so we should just be able to call wait on success. Okay, so I think we can actually just do this and pass in null, W status. Oh yeah, okay, so this is a return value. So if W status is not null, that means we can pass in null and that should be fine. Okay, so all we're doing is then waiting and saying, hey, when my child make me sleep until my child is done. And that way we just stick around until it's done doing whatever it needs to do. So now, okay, now tell me all of the mistakes I made. Hey, look at that. It only takes, I mean, there's 140 people on set. It's only like 300 people in order to write code for the first time that can files correctly. And if it didn't, I would have blamed it on you. All right, the thing to always remember before you do these things is what do I expect to have happen? So before I get enter here, I should think like a scientist in my mind, what's my hypothesis of what should happen? So what do we think should happen based on the code we wrote? Yeah, it should, this process should execute. It should fork, exec another process, that child process should exec VE the challenge binary. And we think based on what that told us that, hey, what it's checking is that it's called from a binary file that we compiled. That's exactly what we did here. So we're hoping that it executes and then gives up, we pass the checks and it gives us the flag. So it's important to do that before you hit enter because if we do this and then we don't see any output, then something is wrong, right? Our understanding of what should have happened is wrong. Maybe one of these syscalls is wrong. Maybe we need to start debugging. But if we just wildly like start executing things without a hypothesis for what should happen, we'll not actually know if we're successful or not. There we go, okay, cool. Okay, the executable that we were checking is a home hacker ADOT out. You did not specify all the execution requirements. I must fix the following issue. The program must contain a function called phone college. Okay, well that seems to do that. We should just be able to add a function. It doesn't tell us what it needs to be. So let's just write a function that returns 42. One of the key, so this is the other frustrating thing when using compiled languages, maybe you feel this way too is you then rerun the binary. You see that nothing changed. And then you go back, edit the text and then go back and nothing changed. And then you forget to compile the code because you have to compile it before you run it. This happens to me every so often. So just remember to take a step back, think, did I recompile things? And then I should execute them. So the function isn't being. It's possible. We'll deal with that if we need to. So let's just run it. Hey, there we go. Okay, so looking through here, okay, we've passed all the checks on the parent process. So we did pass the check that, hey, it is. So now that it expects us to enter a simple password, there we go, we just passed the checks. And now we got our flag for level 23. Pretty cool, right? So we can use a similar template for other types of things. If we needed to pass an argument to future levels from a binary, we know how to do that. We can change that code to pass different arguments. Yeah. So, yeah, we'll deal with that afterwards. Let's, I want to focus on the content. So it's all recorded. And then, okay, now the next one we want to go back to, I think level 16. Cool. So this is Python. So this is what we need there is a, oh, you know what? I wonder, let me do something. Oh, sorry, there's just for my internal, understanding and debugging. So what we need to do is Python. So, okay, we've done this, bash interactive, we've done this with a shell script. We did this with a binary. Now we need to do this with some Python. So should be there. We have Python three. So we'll do emacs level 16.py. Okay, this will be what we need. Let's see. So Python is, if you've never used Python before, feel free to go through a tutorial, get a feel for it. It's actually one of the most easiest, like we use Python a ton in not just when we're hacking, but for our research projects and stuff. It's not crazy. It's pretty easy to do. And especially since we're doing these in several different languages, it should be pretty easy to pick up. And I'm going to give you some stuff to get you started here. And to tell you, like all of the things that we're doing, and to tell you like all of the documentation, basically. So what we're going to want to use here because we're going to want to execute a different process is the sub-process module. So I think we should be able to do most of these things with just this run command, which under the hood will do a lot of the things that we want it to do. So we can run something. We can look at some of the arguments here. We can pass it arguments. We can set a directory for it to execute from. We can read the documentation to understand what these inputs and outputs are. We have this capture output. So we can actually capture output into our Python program and manipulate it and do things that we need to do. So we can look at some of the examples here. So we can do sub-process.run ls-l. You can use ipython as an interactive Python or you can just run stuff. So I usually use this for development. So I can do import sub-process, which is just like kind of in C when we said, hey, paching, pounding, include this thing. Yeah, there we go. Okay, it does show up. So we can see when we run this, it actually runs ls and passes the argument dash l. So we can change different arguments. So we can see this is already much easier than what we saw with C. We don't have to deal with low-level arrays. We can actually pass things as arguments of what we want to do. And so, yes, we have import sub-process. So our goal is to right now execute a challenge slash interaction at 16. So if we go back to the documents, we can see what we need to pass in at the first is an array. So this is all the arguments. Do we need to give this arguments? Ah, sub-process.run, thank you because we want to execute that. And I think we don't need anything else, right? Yeah, so I think let's just run this and see what it does. So I'll need to do, because I can't execute it directly. Why can't I do that? The permissions. So I could actually do the same thing. I could set up a shebang that had a, I think a user bin Python or wherever Python is and that would actually work. The other way is I can just call Python and pass this level 16.py. So this challenge will now perform a bunch of checks. If you pass these checks, we'll receive the flag performing checks in the parent process. We'll now check the process of non-interactive Python instance. The Python's SQL is 3.8, oh, blah, the SQL must be Python 3.8. You've passed all the checks, good job. This program expects you to enter a simple password over standard input. We copy that, go ahead. Boom, we'll also be, the goal here is to learn all these things, right? You're learning these skills together. So feel free, share resources on Piazza on Discord when you find a good thing for like, hey, if you don't have a ton of experience with the command line, there's some really good articles out there that can help you go through that. I'll also post, Yann has a really good command line overview there that we can go through also with these, you know, these functions. Now, we're gonna, the goal here is for you to develop skills and learn that's gonna help you further in the course as we do more cool crazy stuff because the cool thing here what you're doing is you're writing a program that interacts with another program that calls that program, that executes things, that passes arguments that we'll get into reading input from that program and doing stuff with it. So these are all super cool.