 Hello, everyone. My name is John Hammond, and I want to do a quick little video on a challenge from TAMU CTF, which was a recent CTF just going on the other couple of days. And I wanted to showcase this miscellaneous category. There's a challenge in here called blind that I thought was kind of cool and kind of neat. So I wanted to showcase this. All it does, it gives us a little net cat command to go ahead and connect to it. I'll fire up my terminal so we can work with this. I'll move into a TAMU directory. I'll make a directory blind. So we have a spot to work in. I'm going to go ahead and make a simple connect.sh script that we can just slap that in. So we have a good practice saved for how we're going to actually interact with that. So okay, let's go ahead and mark that executable so we can work with it. And let's go ahead and connect. All it does is it says execute. And then we can seemingly type in anything we want. But the question is what's going to really happen once we enter? What's this returning is this number 127, which is kind of odd and kind of weird. But considering that saying execute, maybe that means we can execute code. But what kind of code are we executing? We don't know. I guess right now we're blind, right? So we could try things that you would normally expect on a Windows machine like LS. And that gives us the number zero. We could try who am I and that gives us the number zero, etc. But we don't get to see the output of the actual command that we might be running. So that's kind of a hiccup. Because maybe that number that's returned to us is in fact the return code, or kind of the exit status of what we're trying to run. So I thought, what do I do with this? I can't see any output. We can't redirect it to things like maybe one can redirect to standard error or something. I guess that didn't seem to work. We still don't get any output whatsoever. I want to try things. Well, maybe I could have it reach out to an external server, and I could post the command output there and actually be able to see it. So I try to do things like curl to say, like actually reach out to a web page, or w get or ping. But this 127 command that was repeatedly being returned to me that status that return code is telling me, well, hey, we don't have this command, we don't have this accessible to this instance that we're connecting to. Seemingly, what we're able to do, though, is run these commands locally, and that zero is going to tell us it was successfully able to run a command. Because the exit status of anything that succeeds is going to be zero. So in bash that dollar sign question mark, or return the value of the last command's return code or kind of the exit status, you could do some research on that if you wanted to bash, let's see, I'll get to bash return code. After a script terminates that variable from the command line will give the exit status of that script or the command that was executed, and zero is on success or an integer in the range of one 255. So we saw that 127 repeatedly, is that mentioned here? Yeah. So a command that doesn't exist, like a bonus command or something that we don't know what it is, bash doesn't have that in its system, it's not going to be able to return that or run it. So it's going to exit with the status code of return code of 127. So we know, okay, that's what we're up against. When we connect, what could we do though, we don't have the output of LS or anything on the system, we could kind of grep around or look for things. Maybe there is in fact, a flag dot text file there turns out there is cat flag is going to return one because okay, that file is not there. But maybe cat flag dot text returning zero, because that does exist. But I can't use Python to go ahead and send it somewhere. I can't use curl or ping or anything x fill that data out. So what can we do? I had this thought I had this idea because it's blind, right, maybe we can do kind of a technique similar to blind SQL injection, where we could determine what values are in that flag dot text file. So the way that I was going to do this was I was going to cat flag dot text. And then I was going to actually cut with a delimiter here, not a delimiter, sorry, but a count of what number or what index that I really want to get. So if I could do cut taxi, that would successfully run. But how could we determine what that value is? Well, we could grep for something that that might be returning. So the flag format for this competition is gigam, or gig em, and that would have a curly braces following that unless it's otherwise specified it. So I could knowing that I'm getting the first letter, I could grep for G. And I'll give me a zero. And that was a success. If I were to do something else like cat flag, cut taxi one grep, and then like a, or little that I know is wrong, in this case, it's going to return a one. So we could do some testing, we can actually figure out the entire flag using this method. So let me show you how to do this. I ended up doing this in a Python script. So I'll go ahead and create one here. I'll say my shebang line as user bin environment Python. And let's grab the host and port here so I could connect to it with phone tools. paste that in host can equal just that as a string, and we'll say port can equal that. So we can specify a dummy variable like s to go ahead and connect to it on that host and port. And let's just open it up, close it and let's see what it returns for us. Let's go ahead and run that script. Okay, so we open the connection and we're prompted with execute just as we were doing when we were automating or interacting it with netcat. Now we're automating it with Python. Because we're going to be doing a lot of brute force, I'm actually going to turn off those kind of opening closing messages from phone tools. The way I do that is just set the log level to critical and point those context. And then we could do something like we could go ahead and specify a command. And we know that is going to be cat flag dot text piped to cut taxy one. And then we can grep for something like g, right? So let's go ahead and try and send that sun line command. And then let's go ahead and see what that returns for us. Here we go. Okay, so looks like it was asking for execute, we sent it a command and then we got our zero back in a new line in our execute. So let's try and carve out that return code, let's say return code equal s receive until so that way I can split until my new line character. I'll say drop equals true. So that's not included. And let's go ahead and print out that return code. And that's just going to give me a zero as in bytes. So I will go ahead and decode that from Latin one, because that's pretty safe for results. And let's mark that as an integer, because right now it is a string. There we go. Okay, so now we have the numeric value zero for the return code of the command that we just sent. But we need to actually start to brute force the characters within that flag. So what I'm going to do is I'm actually just going to create a little dummy flag dummy flag dot text. And we can say gig, um, this is a dummy flag. Good enough. So while we're to cat out that dummy flag just kind of testing locally, we can cut taxi one, we can grep for G. And that did return for us. But if I were to grep two, and I was used like, or cut up to two grep GI that would fail because the way that we're using grep and cut is that cut is actually just getting that specific index. So if I want to grab the full one, we could use a hyphen to to grab everything up until that number. You could also do that the other way and start from that second position forward. You can kind of build this out however you want. If you want to just be testing that specific character, you could be using that and then grep for that specific character. Personally, I really like just kind of building the flag out. So I'll use that hyphen prefix to the dash to say up to that number that I'm looking for. So I'll grep for the start of that flag format. Now we have that return to us. So what this means is that we're going to end up building out a flag so far, which we'll start kind of as a list. I just think that's a good way to do it. And I'll say gig them because I know that's going to be the starting flag format there. And let's say we use the f strings within Python, let's say our command will equal an f string with the length of our flag so far. And we'll grep for that flag so far that f string will allow us to put those variables in there. Problem is, we need to actually build out and test what the next character might be. So let's go ahead and grab every single possible string character. I will import string actually let's do a from string import printable so we can have them all readily available to us. And let's start to hammer this thing. I'm gonna open up a new connection every single time just because I want to know without any issues that okay, it's connecting just fine. And let's try to let's verify that command will work just fine for us. Let's get the return code first. Let's run our script. Oh, we do need to actually hit the receive command, we just don't want to print it out. Okay, so we're getting a two and that that failed because what's happening flag so far can be G, right? And oh, we actually want to get the flag so far as a string. So let's use this, let's actually create a new variable because we are going to end up using something like I'll just call it use so I can make a flag so far all put together. And then let's use the length of use and use so that's a string not a list. Okay, so now we have zero. If I were to try with the other beginning parts of the flag, we are getting that to fail. Why is that let's go ahead and print out our command. Just for some debugging purposes, five taxi gig them. Oh, we actually need to include that negative sign just as I was saying earlier. There we go. That's why you wanted to print out your command and know what you're really doing. Okay, so now we can start to loop because we have a little primitive that tells us this works. So let's do a for P in printable. And we'll update our command and our use variables. So we don't need these down here. We'll say the flag that we have so far, we'll put that together as a string, and we'll add a testing value or a P there. So we can go ahead and see what we're working with. Now let's actually print that command additionally. So we can see it working. And then we'll see hopefully with the return code, getting us a zero, we could determine whether or not we actually have the correct value. So let's try and run through this. G zero, one G one, one, etc. All those are failing. Eventually we'll get to an I. And you can see that right here, that I did give us a return code of zero. So we know, okay, that's the correct character, that's the correct next character. So we can do with the setup that we have thus far, we can just say if the return code is equal to zero, what we'll do is we'll go ahead and add that to our flag so far. So flag so far append P, because flag so far acts as a list, which we can add to, it's adding a string value. So that works just fine. And our use variable is going to actually put that all together as a string and still add that dummy value in, we're actually going to break. So we start to reset kind of the brute force method that we're using this while one is just kind of like, hey, do this repeatedly, keep adding adding to the flag as we find new characters. And our for loop is just going to be going through each potential character that could work for us. So now we can watch this happen one more time, and see if that gi gem thing starts to grow, will it successfully add that I, and you can see down here, it did. So that works for us. We know now what beginning prefix of the flag is. So we can kind of optimize our script. Let's say gig him with our curly braces. And let's go ahead and run through this. Okay, I'm going to end up pausing the video here. And we'll actually let this roll through and see how it develops the flag. And then we can talk about this more as we get back to it. Okay, so now we're getting to a trouble spot. It was able to build out the word reverse in lead speak. But what we're going to end up seeing happening next is that the way that the strings and the characters listed in that string dot printable variable are in order, we have kind of a ampersand symbol, and a hashtag symbol like a bash common. So the ampersand would normally background a task within bash. And that's going to be problematic because it's going to think it succeeded. And then it will start to try things and it won't be able to determine the rest of this get for us or the rest of our grip and cut. So we'll have to remove that one. And we should also probably remove the hashtag symbol or the pound symbol because you can see, okay, we're totally failing. We don't have the whole flag built out yet. So what I'm going to do is I'm going to take that printable variable. I'm just going to set it to the same value of printable where I am removing that ampersand. There we go. And we probably want to do the same with the dollar sign, it was kind of an accidental typo, but it might try to read a variable that doesn't exist either. And since we're doing that, we can expect there to be underscores trying to separate words. So let's actually go ahead and remove underscores, and kind of place them at the beginning of our list here. And we can also do that for the ending curly brace. So let's do printable equals printable plus or excuse me, at the very, very beginning, we can go ahead and add our underscore and then a closing parentheses or closing curly brace. So now let's see how we look. Oh, because we built this so far the way that we have, we can actually just copy out everything that we already know within the flag. And then just specify that's what we're going to start with. So now let's run this. And we can see the underscore worked for us. Now that was added successfully. And we'll start to work through the rest of the flag with that methodology. Cool. Okay, so at this point, we have found the full flag with the ending curly brace here, it's grepping for gigam, reverse shells. And it's still trying other characters because of our while one loop, but we know kind of as the human eye here that because we have that ending curly brace, we found the full flag. So the flag is reverse shells. And I'm curious how this kind of would have been solved with a reverse shell, because I didn't seem to be able to get one just kind of on my own. Maybe there was some other syntax some commands that I wasn't thinking of, but maybe that would be able to pull you out of that blind shell. Regardless, I thought that was kind of a cool technique the one that I went through, because you're essentially doing like a blind leak attack, right? So we can say flag is equal to that reverse shells. And we could probably make this a little bit optimized with like a with the for loop, having a list of the bad characters are cleaning it up. But that's it. That's our dirty script. That's how we were able to blindly leak out the flag and just using Linux commands and in that methodology. So that would net you if we go check out the challenges, I know they're using dynamic scoring for this game, which is kind of interesting. That means the point value for each challenge will decrease as more and more people solve it. I think when I got this, we're only like 34 people that had solved it or something. But anyway, kind of a neat challenge, at least I thought I thought that technique was kind of neat. I hope you guys liked it. If you did like the video, please do hit that like button. Hit the subscribe button and the bell if you want. I don't know. Sometimes I always feel so violent to me like, can you imagine just going up to a like a real life physical bell and just just literally hitting it. Alright, thank you guys for watching. I really hope you enjoyed this video. Love to see you guys on Patreon, Discord, PayPal, anything. I just appreciate your support and I'll see you in the next video. Thanks, take care.