 Hey folks, Adam DuPay here and we're gonna be today we're gonna be playing through the Poneable.kr And this is going to be a live hack So we're gonna I'm gonna be working on the input challenge and this is actually something that I haven't solved yet So this isn't a walkthrough necessarily. It's more of a me trying to live hack through a challenge So let's see how this goes So when we SSH to the machine we can see so we're SSH-ing input to at Poneable.kr The important thing that it tells us is mom how can I pass my input to a computer program? So presumably this challenge is gonna have to deal with how we pass in input to a process So if we look So we have here we have our program And it says welcome to Poneable.kr Let's see if you know how to give input to a program. Just give me correct inputs Then you will get the flag. So it seems pretty straightforward. So I've already copied down the source code to the machine So let's look at it here. So We can look through this so this is the C code we can see this message that we just saw printed out We the first check if argc is not equal to a hundred return zero So this means that we have to execute this program passing in argc as The value there as so we need to pass in so remember the first argument to argv is typically The name of the program to execute. So that's argv zero And so we'll need to pass in 99 arguments Let's see other interesting things if string compare argv a is If that's Zero then return zero. So this is interesting. So they're indexing into the argv vector using a character So that will presumably Let's open up a new terminal here. So going into the terminal here man ASCII So if we look the character of a so I don't remember I don't memorize these things these tables So I always have to look them up. So we have a so a is going to be decimal 65 so at the So it's a zero index. So at the zero index sixty-fifth index. We need to make sure that that is equal to a Null byte so it's remember. This is a string like Containing null. So this would be a string of length zero. So this is interesting Then the next string compare string compare argv be so this will be one right after the a needs to be 20 zero a zero d Why is this interesting? Well, 20 is a space zero a is a new line and zero d I believe is a line feed, but we can check that very quickly. It's a carriage return. So it's a slash r So it's a slash n and a slash r So now we go back and say stage one clear, okay That actually seems like that should be very easy to pass and we should be able to do this just from Passing in input so we could actually do this just on the command line So and we can see there's actually helpful comments here So this is about manipulating input in terms of argv and here this next one It looks like in terms of standard IO. So standard input output. So we can see there's a character buffer of size four allocated on the stack. It's reading from File descriptors zero. So if we remember this is actually passing in This is interesting So it's past so it's reading from standard input into the buffer and it's reading in four bytes And it's checking to make sure that those bytes are zero zero zero a zero zero ff And if it's not then return zero so that's is ensuring that the standard input to the program is this Now another interesting thing is now it's reading from file descriptor to the buffer and It is calling memcomp on that to compare that to zero zero zero a zero two ff For return zero so it's gonna say print stage two clear So this is an interesting check because it's reading from what is traditionally remember zero is standard input One is standard output and two is standard error. So standard error is usually something you write out to but here It's reading from that. So we're gonna have to manipulate this so that it can actually read from standard input And then here we have the environment. So now it's reading from the environment variables. So here it's saying hey compare get Env so get environment D e a d be a e f Compare that with this value. So get read in the environment variables this value So we have to be able to manipulate the environment to include these parameters And of course the trick here is that these are not ASCII characters. So this is gonna be something that will have to create The next stage here Interesting. So the next stage here is a file. So open up a file Which whose file name is a new line character and read that file and then Read four bytes from that file into buffer that same buffer again and check is that buffer all zero So we'll need to create a file with the name zero x with the name of a new line character and Inside that file. We need to put four zeros. So this is actually pretty interesting to pass stage four and Finally here we have our network. So we have a network section and So here it's gonna Create a socket It's going to use. Let's see our VC. So the one after so we do ABC. It's gonna do our VC It's going to set that equal to the port. So it's gonna listen on this specific port and What is it gonna do? It's gonna listen there. It's gonna accept It's gonna receive four bytes. We need to send it D E A D B E E F And if we get that then it should be stage five clear I'd have to look up Exact I'm gonna guess off the batch that this is going to be a TCP Packet one one thing we could do is just rip out this code into a C file Compile it execute it and see what it does to see what kind of socket it's listening on but I'm gonna go ahead and guess that it is going to create a TCP socket if not, we can easily change that for new VP and then it will output us the flag So it's gonna call system slash bin slash cat flag alright, so how do we do this so My initial instinct here is to always maybe create like a Python program or a bash script that will set up the environment here But one thing I'm worried about is how to set Environment variables that are arbitrarily named like this. So this is something that we can easily do With a C program by calling. So an important thing that we're gonna do is man Exact Vee so exact Vee is the system call and this is how you actually execute another program And this is what when you're typing in bash or any other shell. This is actually what gets called So here we have exact Vee. We can pass in the file name that we want to execute We know exactly what the file name is we can create an argv vector and Here we know we have to pass it a hundred variables an array of a hundred and we'll need to construct an environment pointer that has what we want in there and So we should be able to Execute this and so that way we can call this Program passing in the exact arguments that we need So this should be good. So we're gonna go with that because we should be able to Create all of these values. So we should be able to create the argv. We should be able to Manipulate the standard input and standard output so we could pass in variables to standard in and standard out The environment pointer that should be easy we'll construct in the environment pointer to deal with that and We should be able to actually just use this to create this file this new line file So we'll basically use the reverse code here. So with that we've got to start Executing so let's do Create a solution.c file I'm going to Rip these headers. So rather than thinking about what headers I need. I'm just gonna use exactly what these people need That's that There we go. I will also need because I know I'm gonna call exact Vee So again, I always love love love using the man page Because it's going to tell me hey look, this is the header that you need in order to call this program so here I have this now I'm going to Do you do my int main in argc character pointer pointer argv And I actually don't care about the environment for this guy. So that should be fine So this is going to so basically what I'm going to do is Create essentially a new arg New argv vector. I will eventually need a new Envp Envp pointer Because at the end of this what I'm going to do I'm a call Exact Vee now, what do I actually want to execute? So It is called input. So Let's call it. So this will need actually the full path And so because I want to test it first Let's do Because I have it here so I can run this Program locally So here I have input. So this is actually a ridiculous path, but let's use it anyways So a key thing and let's make this a character pointer path We'll call it executable and slash input And that's the way I can change it when I copy and paste this to the actual source code to the server I can change this to whatever I want. So now I have my exact Vee EXE and now I'm to pass a new argv and new Envp So exact Vee what that's going to do. That's a Linux system call It's going to completely replace this process by executing the other process. So I urge you to look at how The process works how this exact Vee thing works and look at system calls and how they're implemented. So And basically what I'm going to do is I'm going to try to create this program exactly as if What I would what this program is looking for so I'm going to have an argv section to set up argv properly standard IO slash fd file descriptors create the environment correctly create the file and Network I'm going to put a question mark here because I think I'll be able to do this from another process So because I know it's going to wait for this so I could just create From another process I can connect there and then I can Pass the parameters that I need the input to pass this network check So I don't necessarily know that I want to do this Excuse me in this C code. All right So one thing that we can get off right off the bat and we can be And if we go back to the man page We should be able to see that these are So here it says environment argv is an array of argument strings past the program by convention the first of these strings should contain the Founding associated with the file being executed Environment pointer is an array of strings conventionally of the form key equals value Which are passed as environment to the new program both argv and environment pointer must be terminated by a null pointer So this means a null pointer. So this is going to be I'm going to set this to a basically an array Of I need to figure out how I want to do this. So the environment pointer I really only need one of and this is where My syntax is going to come in handy or Going to be messed up. So you want one more than you actually have So I can set environment pointer zero is going to be equal to and I know that I'm just going to pull it up here input.c I Know that I want So what I want in my environment pointer is I want this value is equal to this and I don't want that So that's going to be the first key value pair in my environment pointer And I actually don't want anything else in my environment pointer so environment pointer one is going to be null and That should pass that check once we get there At this point, I'm going to compile this to make sure I'm on the right path I'm not quite sure about my syntax here. So I like to compile as I'm going gcc pollution.c And what happened? So we can actually call s trace to see it calling let's see Exec v e with this file null and with one variable. So a environment pointer that contains one variable So that's awesome. So we saw that that works Good. So my syntax did work there. So now we know what do I need for this? I need space for Well, I need the argc to be a hundred. So I actually need to pass in a hundred and one remember if I come up here argc is Not equal to a hundred So I need to pass in a hundred values, which means my I need to I Will need to what I'm going to do is let's say to set this up Yeah, I equals zero I less than A hundred I plus plus is going to loop over all of them basically what I'm going to first do is just initialize everything to the I'm going to initialize everything to the empty string. So I'm going to say new argv one argvi is equal to the empty string and Then I'm going to say new argv 100 is equal to No, so this will set the last element in the array equal to null and let's see does this check out It's gonna be a hundred. So I will never be a hundred. Yes. So the first Zero through 99 will be set to the empty string Now I can actually just make sure that I Can do exactly what they're doing here So I actually don't need to know where exactly this is all that I care about is that It's going to be set to the correct values so if I do this correctly and We know from looking at you know, I already need to set I Need to set this to some port. So let's do 8080 just a random port Now I can actually test test this because I have if I'm correct and I did this correctly I will get to this printf stage one clear. So if I go here I should be able to you always got to compile this. Sometimes that bites me but Stage one clear great. So we passed a hundred arguments there And we actually know what is it waiting for here? Well, it's waiting for reading in from standard input so we want to be able to now Change the standard input that we're going to pass to this program. So the next step is to get past this There's a couple of arguments here. I think maybe an easy one is going to be Basically change standard input for this executing program to read from a file So what we'll do in our solution is we will write out a file that has these bytes four bytes 000 a 0 0 ff And then what we'll do is we will redirect the standard input of these exe ve Program so that it's thinking that standard input the file descriptor zero is that program And then so I'm gonna have to actually dig into and figure out how to do that It's been a while since I've played with it's probably in the dupe family of keywords. So that should be fun. So But I have to go for a second. So I will be right back All right, so now what we want to do is we want to create The bypass this check of the program. So here we're going to need to Create two files and in this directory And what we're going to do is put these contents in those files four bytes into those files and then we are going to Change the file descriptor so that file descriptor zero reads from that file and the other file descriptor So we'll need two file descriptors int new standard in Equals open And I'm going to need to look at the man pages for this because I definitely don't remember how to do all this in c Uh, I will need a different section of the man page to There we go flags. So And let's make sure we include these files. They may already be included, but hey It doesn't hurt to actually include these all right good, so int Open we want the path name to be uh dot slash Well, it's called first. It doesn't really matter Flags though, we're going to want to Look at the flags. Ah, we want to write only we're going to write out this file. Oh write only And then we are going to call write on this file. So we're going to do man open to write We are going to write out. So this is going to be pretty easy We're going to do exactly what the opposite of what's being happened in here. So we're going to call Write to this file descriptor new standard in The buffer so we're going to want these bytes and it's super easy if we just copy these exact bytes That will make it the easiest and we're going to write four bytes Into that file descriptor great Int new standard air open dot slash second Again Actually now that I think about it, we'll probably want to change the Change how we open we may now that I think about it We're probably going to want to seek on these files because after we write the file descriptor We'll be at the essentially the fourth or fifth bit. So we're going to want to Yeah, I think we're going to want to seek because our child is going to want to read from it So if we can't we don't open up these files and file descriptors so that we can read from it We're going to have a bad time So now let's write to New standard error that I add that in here I don't know but let's check this Write that those four bytes to that new standard error file, which will be second And then I think I'm right about the seek I think it's called f seek. No, okay. Well, let's just look for seek See if there's just a seek function F seek. Okay f seek. So we want to Man to open So, aha, here we say read write l seek. So there we go. That's what we Need to do So l seek reposition So what was tripping me up and throwing me off is that f seek includes a file pointer and here all we have is a A file descriptor and integer. So these aren't the same thing. So we want to make sure we're using the right file. So Uh l seek new standard in to offset zero What in the world is this wence parameter l seek function repositions the offset of the open file associated with file script fd to the argument offset according to the director Wentz as follows seek set the offset is set current Oh, so you can seek based on the start of the file like set it to us like absolute um File location you can set it based on an offset. So here we want to make sure so it's important to read the documentation l seek new standard error zero seek set. Good. So now those are seeked. So now I need to figure out how I want to Duplicate so the idea is How I can So now I need to read this code and figure out how I can get The file descriptor set up properly so that I can Make sure that standard input is now reading from this file and standard output is Standard error is reading from this other file descriptor And I have not done this before so Let's dive in So this may involve some googling and I think I'm just going to record this just so you can see kind of what the process is like Dupe two so okay, so dupe just gives us a Creates a copy of the file descriptor dupe two For the same task dupe instead of using the lowest numbered unused file descriptor It uses the descriptor number specified in a new fd The descriptor new fd was previously opened. It is silently closed before we use. Oh cool. So Atomically requirement functions race conditions So I think I can just use So I think I can call dupe two With the old Creates a copy okay, so the old file descriptor so I want new standard in so this So this is my new file descriptor Let's see. I want to Huh, this is interesting. So it's going to happen when it outputs those bytes I guess we shall find out so dupe two This is gonna be new standard input and I want it to be zero. So I want standard input to be From there So now this should duplicate. So this new standard input should be standard should now be file descriptor zero um So it's going to close it before reusing it And then we're going to do another dupe two. We're going to want our new standard error to be file descriptor two And now we know that this if this compiles, we know that this should work. So if we see or If maybe we actually may not see it it may go to that file that we just created first We may see this stage too clear. So let's try this and see what happens and we may need to debug it if Something goes wrong. So Compiles fine without errors always a big shock when that happens stage one clear And let's look at So those files did not get created. That's interesting. Let's see Solution dot c All f open I didn't close those files, but that's because I don't want to close those file descriptors um Can I write files here? Yeah Okay, let's create these files and see what happens. So first and second I shouldn't need to do this, but let's do it anyways. Well That's awesome. Okay, so it looks like so we can see that part of the problem is um That we did not create those files first. So that means this is actually going to fail when we When we try to do things so what we should be doing here So we actually saw that we passed stage one stage two and stage three so stage three was the environment pointer So that means that's good. We set up all that stuff correctly. That's awesome Um, now we just want to make sure that we actually create these files So how can I just I want o create if file does not exist it will be created So this is the mode that I want so i'm going to or that or that And now we can see I don't have those files compile Boom stage one stage two stage three clear. So that is awesome So then stage four is this file descriptor. So we need to create this file and again, this is going to be actually pretty easy and straightforward what we're going to do is just do exactly what we did before so we um Going to open this file. We're going to call it x0a I think that'll work. We'll see what happens That's going to be annoying to have that file there. But hey, we will do the best we can And what we're going to do is the same thing Uh, of course, I don't want to call this new standard in because that's going to mess may mess things up. So this would be We'll call this new line because it's a new line file. So we're going to write out to new line This buffer four bytes And i'm going to call close Yeah, so close that file descriptor All right, so we should be able to get past that. Let's Gcc it That's interesting. Why did that not work? Oh weird interesting. Look at the permissions for second. The permissions are nothing there I have no idea why those permissions are getting set like that I just deleted that file. Okay scp The actual program good so that comes back to us Um, so even the first is not That is very interesting Oh, I wonder if we can Let's find the mode. So let's add that there. Let's see the argument flags Let's complete that. Okay, but what about It doesn't say with the mode parameter. There we go mode specifies the mode to is creating a file So I can must be polite but Oh, interesting. So it's just reusing so that's um Okay, so these are just unix permissions. So these would be really easy So interesting so basically from this create I bet it's the reason why those things are different is because it's using the value on the stack And so they're just using whatever was there And we will be super generous and just give everyone permissions to these files There's the other open 0777 Sweet All right, and now the problem is I have this Yeah, I have this now I have this file this new line file there that has bad permissions Uh, let's just Yeah, so the problem is now we have first and second are quite correct, but Hey, I think we'll maybe take what we can get Maybe I need zero permissions or funny. Let's try that second First second. Nope that didn't change anything. Okay. Well That's strange. We'll just go to that for now Looks like some of the permissions are getting set correctly. So that's good The problem is now I have this new line file. So Uh, yes, so I want to delete this file now. So first I need to unlink this file Uh, and that should delete it There we go. So I got stage one, stage two, stage three and stage four clear And since we actually passed stage four, we're actually know we're on the network So that means we can actually use netstat here to see netstat n l t so if listening tcp We can see so we're listening on port 8080. We know it's tcp So now we can actually just say echo Or Let's use python to be a little bit nice. So python-c print Da da da this We're going to pass that to netcat localhost 8080 Stage five clear. So now we should get the flag Awesome. So here's the here's the thing. We don't have a um So we can actually get rid of this unlink business here because we don't need that anymore Although I'll have to run this to get that file out of the way. So the solution.c We should be able to run this. So what I'm going to do I'm going to There's a lot of people have found the wall command Maybe I'll find something to tell people about how to do this. So Let's go into our own directory Ah So I'm just going to this is a poor man's copy paste. So we're going to copy paste this here We're going to run fin on this solution Remember we need to change this exe value so that the proper thing gets It's input here. So I believe we are in Slash home slash input two slash input Um, and the other thing we have to think about is That's fine. I don't care about what I have in info file The other thing we need to think about is when we cat It's going to call bin cat flag and remember all these files that we're creating are in our local directory um So I'm going to have to actually ssh there so I can properly Get that input. So let's do Uh ssh input two. So now I have two shells here. So the problem is we're going to cat out Once we get this correctly, it's going to use the current working directory to find flag So it's going to do bin cat flag. Of course, the problem is there is no flag So what we can do is create a symbolic link Uh to home input to flag Call it flag and now when we try to Uh slash bin slash cat flag Of course, we can't do this because we don't have permissions, but The executable that we're going to execute will have these permissions. So I can call gcc w all solution dot c And should be able to call a dot out we pass stage one stage two stage three stage four And then we'll go here and we will copy that same python Command that we had here go back to there There we go. So here should be our flag. Mommy. I learned how to pass various inputs in linux. Let's pass it into the flag parameter And it will tell us to log in first because it's been too long since I did this so I will log in Log in okay great input And there we go. That's how you solve this challenge. So hopefully this was helpful in Understanding how to think about these types of challenges. So that was a lot of fun and I'll see you next time