 What's going on YouTube? My name is John Hammond and this is an attempt to showcase some of the Facebook CTF. This went on just this past weekend and it was pretty rough. I got to admit I am not going to do this any justice by attempting to showcase some of these. I did not solve much at all really and it's over now but I wanted to at least bring to you one of the web challenges that was the products manager challenge. So this originally did not have a whole lot of solves but slowly got broken into and then it came down to have a lot of solves and it's point value which was originally a thousand. Facebook CTF had dynamic scoring so as more people solved it it would decrease in value and now it's down to a hundred which I think is the minimum that some of these can be without being explicitly set less than that. You can see some of the miscellaneous categories. So this is the challenge. Come play with our products manager application and we're giving a link here. Problem does not require any brute force or scanning, we'll ban your team, etc. We have a download that I have actually went ahead and downloaded already and this is the website. It says welcome to products manager. We have some options here. We can view the top five products, add your own product and the view details of their own product. So if I hit view, it just brings me to this page so I'm assuming these are the products. Facebook, Messenger, Instagram, WhatsApp and Oculus Rift. We can add our own products, view, okay so we need to supply a secret to be able to view it and the only way to do that to supply one is actually create one when we add it. So let's create a please subscribe product with password, anything, blah, blah, blah. It looks like it needs to have 10 characters, small uppercase number, okay. Please subscribe, join discord, whatever. Just test functionality there. Product has been added so if we were to view it, view, please subscribe with our secret. It says please subscribe and join discord. Okay so it looks like that's the minimum function out of this website has but we only get to see the top five results. Let's go ahead and take a look at the source code here. I have downloaded this tar gz file so we can extract it with tar xf, I'm sorry xzvf, it doesn't really matter what order they're in. As long as they're all there, x to extract, v for verbose which you don't need, f for the file and z for gunzip or gzip file. So product manager that would have already extracted all it's in that dist directory. So we have some source code. Let's take a look at all of these things. Looks like, let's start off at index, require the database, looks like it's pretty common throughout all of these, then we get the top products, that's probably a function defined in there, require the header for each of these products that will display it html entity so we can't use any cross-site scripting stuff and we have a footer. Has nothing in it really, nothing dynamic. So the database, okay, created table products, that's the schema here. We have the name, secret, and description for each of the products. Looks like the Facebook row has the flag as its description but we don't know the secret of any of these and it looks like their store is a shot 256 hash. We have config which we were not given, that's probably the credentials of the database so that's fine, we don't need to see those. Get top products, list five, results, receive them all and return them. Get products, this is some SQL select statement so it's just going to grab the name of the description where the name is supplied as an argument. Insert product, inserts products by the name, secret description, that's got to be our add syntax and they're using some bind parameters. So it is not using just strings, concatenating SQL values, it is using some actual like prepared statements, it's not the right word but it's going to head and actually use parameters that will be passed into and bind into the SQL statement. So prepared statement might be the actual right terminology if anyone wants to spot check me I'm grateful. Check name, secret is a function that will take a name and a secret select where name is passed and secret is passed and if they are equal. Okay, if that's actually in the database it will seemingly return to us. Okay, easy enough. Header doesn't do anything, nothing dynamic, index, view, view will take in what we supply to it. If you have the correct secret, it will get products HTML entities. So again, no cross-site scripting. I'm just trying to cursory get an idea for this again and maybe again that will show you if you haven't already solved this. Just trying to showcase the discovery process, right? And then add will let us validate a secret. Okay, validate secret looks like it just is making sure that it is the correct criteria. Look, yeah, we ran into that earlier when we were testing and this function handle post looks like it will go ahead and get product name. If the product name already exists, please enter again. Insert product name hash blah, blah, blah. Okay, so if we were to add our own product, it's using get product and get product does name, select press equals name. How does that do that? If product does not equal null, product name already exists, please enter again. Because what I'm thinking is if we could enter something, if we could retrieve, there's no way we can find out the secret to the Facebook row or that product. So if we were to try and view Facebook, we just don't know what this thing actually is. If there was a way we could trick SQL, maybe we could. I don't know. The only thing that's surrounding these though, because they're parameterized, is not quotes or single quotes, no SQL injection is really an option, but maybe spaces because that's being bound in here. Maybe that's what we can latch on to. If we add handle post, if we were to supply something validated secret, we don't need to particularly care about, but if we get product, product name already exists, please enter again. Otherwise, we can insert a product. So get product, all that does is test where name is equal to something. Checkers, bind statement, so it adds the string in there. Checkers, again, after we execute it, get results, fetch associative. So if it returns something, name description, is that because the description isn't there, that it doesn't return anything? That must be it. So select name description from products where name is equal to something. If we were to add a little trick in there, like a space, either at the beginning or the end, this would not return something. It would think that it would be perfectly fine, but then the space, if we were to view something, would work, if we were to try to retrieve Facebook. So check name secret as the first function that runs actually has to verify by the name and the secret. Get name from products where name is equal to what we pass in, and secret is equal to what we pass in. However, after that happens, what they try and do is they try and run getProduct again, which only cares about the name and not the secret. So it doesn't matter if we have the correct name, it'll return the correct name because it'll be able to retrieve the description at that point because the Facebook, the real Facebook has a description, but the one that we add when we see getProduct ran the first time trying to add something, it won't have a description. So we'll be able to put in our fake Facebook entry, we'll be able to view it because of our secret, and check name secret cares about secret, but getProduct, which should run following, does not care about the secret. Theoretically, right? Let's try it. Let's add something, and I'll put like Facebook with a space in the front, see if that works, and I'll use whatever secret, and it doesn't matter what description we have, product has been added. Okay, cool, and that didn't trigger because if we were to use regular Facebook without a space or whatever, that would tell me product name already exists because the description is in that field, and that's how it's retrieved. So that's super, oh, that's good. It's a super minute bug, super kind of hard to detect thing. Now if we were to view space Facebook, let's enter our secret in here. Let's see if this gets us the flag. No, okay, so let's try it again. Let's try Facebook with a space at the very end, anything, blah, blah, blah, add. Now let's view this Facebook space with our secret, incorrect name or secret. Okay, maybe I had my typo. What? Okay, hang on, I think it would make sense for me to not include the space at the end when I'm trying to view it, but the secret that I pass in still needs to be what I supplied because that will validate and then with the check name secret and then the get product was to return. There we go, okay, so Facebook, and there's our flag. Sweet, blurb about Facebook, but there is our flag. So perfect, that's that, that's how to do it. Man, that was hard to detect, a little bit of agony, so obviously it took me a little bit longer to do that in the real end of things, and I still never entirely pieced it together, right? Even with my dramatics there, I'm trying to learn, but the spaces at the end apparently sequel won't process at the very, very end of a select statement or something. That's that, that flag is, let's say, attacking sequel without injection is amazing, so yeah, because of those parameterized bind statements, we couldn't use classic single quotes or double quotes in common sequel injection, but our spaces were a fine trick and that get product name, not caring about the secret, but the check name secret does, that I think was what put us over the edge and what actually allowed us to take advantage of this, so hey, if you guys did like this video, please do like, comment, and subscribe. I'd love to see you guys on the Discord server, there's a link in the description, it's an awesome community full of CTF players, programmers, hackers, and if you'd be willing to support the channel, I have Patreon, PayPal, and I'm just grateful and thankful for whatever you guys are wanting to help with, thank you so much. Hope you guys enjoyed this, I'll see you in the next video.