 Hello everybody you welcome back to another YouTube video. We're still looking at the hack the box cyber apocalypse CTF I won't bore you with the details. Let's go ahead and get right to it here So I am opened up on the interface with a little cyber apocalypse and JH party Let's take a look at that emoji voting challenge. So emoji voting looks like the challenge info here It says a place to vote your favorite and least favorite puny human emojis Looks like it can be started on a man and does have a downloadable part So let's go ahead and get the instance started and once that's spun up We'll go ahead and grab that URL open that up in a new tab so we can go ahead and poke at it Give it just a moment and let's see if it comes to life here Not seeing that one Okay Now that that has finally come to life We can go ahead and download The little parts here and I've got that downloaded. So let's go ahead and make a directory for emoji voting Hop over there and let's move that downloaded file from web Emoji voting dot zip over here and let's go ahead and unzip that so now we should have all the files and Before we dive into these actually let's let's just take a quick gander at the Docker file to see where that flag might be stored Not included as a file in The Docker file here. Let's check out the challenge files. Oh, we have a database maybe Yeah, oh There we go. Okay, so we are working node looks like we're looking in some JavaScript files So and web interface kind of defined out in JavaScript with node JS running server side We have a flag randomness table. Okay, so that's something we should take note of and Okay, there will be our flag, but there they have a placeholder. So we'll have to potentially Get that somehow Oh, okay, here's some functionality looks like we can vote With queries to the database where we are updating the number of votes on an emoji Okay, great and That uses a parameterized Kind of argument or parameter there So that we can actually really take advantage of reviews this next function get emojis has a tood I'm assuming that's meant to be to do but I like to do a little bit better I think we should I want to start using that from now on for comments on to do to Let's check what this is doing. It doesn't have parameterization seemingly yep Looks like it's just using the variable that would be passed in so that potentially has some sequel injection here But the query that it's using is from a select all from emojis order by Claws now that actually throws a wrench in the works because typically Just dumping stuff from the database would be very easy to do when you use explicit sequel injection in which case you can use maybe a union select to add more To the query and display something else with the results You may have expected originally order by might change the game for us a little bit because we can't do any of those quick and easy Or one equals one or union select things and add in other things We we might have to change this to some blind sequel injection technique rather than an explicit outright and direct sequel injection technique, so Good to see those functions here now. Let's kind of play with the website. So looks like I can vote and on an emoji Human looks like a the poop icon Okay, I can click on that and I can see the vote number going up here I'm just going to open up my network tab and kind of view the tools with with developer tools I hit f12 on my keyboard. So if I were to click on that human one I can see these results or these requests coming through looks like I am submitting a post request to api slash vote With the request headers. Oh and a request payload for the ID So putting that together If we get emojis, is that something that's going to end up happening? Our vote is this function that we can control with just the ID by clicking things. How does this? Oh There are other calls that are happening here List is just like popping up. It's adding another request. Oh Like every couple seconds. There's it now. There's a 16th request looks like oh that is using the order That list functionality looks like that maps to this get emojis and since this is kind of a little white box thing We could examine some of the other files here. Let's see what index.js is doing looks like this starts it up But What is calling that? Kind of votes function the emoji voting DB Is that something that's no are the these aren't going to be in routes. Are they going to be in views? Check out what that index up each does It loads in some other JavaScript. Maybe this JavaScript calls it. That's out of static So let's hop back to check out that static directory JavaScript main.js Okay. Yeah, this has this add emojis functionality to Get stuff from the database and display it out on the page But get emojis looks like a function that will reach out and fetch from With a little post request to this endpoint on the API. Okay Good to know What kind of sequel are we? Working with the oh, this is sequel light. I'm going back to the database.js So you can see we're using sequel light. So we need some sequel light syntax All against this potentially vulnerable list call so let's get started With maybe beating this thing up. I'm gonna go ahead and create a little Python script Where I can Import requests because I know I'm gonna be doing some web stuff so I can request out pages. I will go ahead and post to the URL for this Actually, we can define that as URL and then we'll go to that API list, right? Yes, that is what this calls Let's store that as a Variable so we can go ahead and print out what that returns. I use that print dot text here I'm just gonna go ahead and try to see what happens. Obviously, we aren't passing anything to it So it just tells me hey missing parameters good enough So let's add in some data or parameters that we could Supply I'm using sublime sub black or the Python black linter right now So when I save some of my some of my characters might fly around forgive me on that But we know that we need the order to be what did they use they use count as A field in the database here. Yeah count will be the integer of How many votes this has so Using that okay now it displays it all with that response But we need to do some injection here So because we're in order by we can't Sainly use like an or one equals one that that logic just kind of doesn't make sense I'm gonna use the comments here the dash dash or the hyphen hyphen to note a sequel like comment But yeah that sequel kind of just won't behave for us. Can we Have like some nested queries I'll add this DESC in here and we will order by I guess a string Selecting out count. So this kind of becomes evaluated to count DSE for descending That looks like it works If I order that in a different way does that behave what other things can we order by Or other fields in here Name I suppose Did that order properly? I'm not positive if I pipe that to jq to display it out kind of But the council a little wonky But that's the same kind of response we had previously isn't it let's order by ID Maybe that looks like the same kind of structure. How about name? same kind of structure Emoji not all that helpful. Okay. How about Ascending again No change to these quotes get in the way. Oh That looked better now name is Ascending it's a different order here What if I did count Descending so we have kind of the original Good good. Good. Good. This count looks much better because the count is going down in the results as I scroll up but we could totally change that to ID and Now it's in that reverse order of IDs. Okay, so we can use this nested thing That was a little bit of troubleshooting determined. Can I use some parentheses to note something else in here? Since we're using sequel light and if we're gonna get into some like blind injection techniques We might have to do some boolean stuff like figure things out if something is something else So I want to Google like a sequel light if statement sort of thing I think case is the syntax for that Case evaluates expressions and a list of conditions that returns based on the result of the evaluation Case expression is similar to if then else in other languages. So case something when Is when always necessary? How does this look give me an example? So return out count maybe when a condition is met let's Experiment with that so the syntax would be case count when One equals two Maybe like some logic that we know will fail then We want result one Else something else count is already kind of the singular thing that I'm checking though. That's that's weird to me ID How about that? So on a false condition ID should but be what we Descent something went wrong What's going on? case of a case expression Maybe that needs to be like what it's evaluating out to so case one equals two When that's true Like one being the evaluated true there then count is going to be what we descend by otherwise ID How about that? No, does that need to be? Here's some some stack overflow goodness. Let's see what we're doing Select all case when oh, they don't even use Like another condition in there. So when one that should always return true, right? No when one equals one Something went wrong. What's the issue there? Troubleshooting troubleshooting troubleshooting That's what we do That syntax is way broken Case when something equals some condition then this and oh, does it need an end at the end? Oh my gosh. Oh goodness Was that the problem all along? Oh Totally, okay So oh my goodness. I'm super sorry. I should learn to read So when one equals one then descend by ID if we were to use a false condition this else will evaluate right so Now we're descending by count, okay, so we have some logic that we can determine here now we kind of want to Determine if we can leak things out using this back-and-forth Threshold of some true statement versus some false statement So case when and let's try and grab some value. Well, let's do like a select one That should still return Ordered by ID Yeah, how can we kind of test on this? How can we kind of a I? Guess return whatever comes following this Can we select like a one No Hmm That order by still gonna just make it annoying. That's just gonna be weird. I guess we'll I guess we'll use count and ID as our threshold Something to verify we still have the logic in place so ID We'll be descending so we can just check if the first elements ID is 12 if it's not that we know that we're in something else so Now we need to try and determine some specific thing as part of something that might be in the database Because we're in sequel light I'm gonna go check out my own notes in My miscellaneous repository because I have kind of a little cheat sheet sequel injection syntax cheat sheet to leak out Stuff, but we do know Already a little bit of the structure because we have this database here So we know there's a flag random table, but we first need to know the full name of that flag table So let's close out of these and then let's try and get Maybe one column from a table, but we need to leak table names and Sequel light we can group concat name from sequel light table That Will this work for me now That syntax We'll have all the tables displayed out, but we can only kind of verify one character at a time Can I substring? there's something in sequel light looks like it Substring takes a string and a start and a length so let's do substring on Everything that might come from this I think And then one and one so start position can be one index can be one and we want to check if this is a Like the letter f maybe for flag which table will come first. I Guess emojis would come first and then flag Like alphabetically wouldn't it so Let's turn word wrap on Maybe E. So let's check if we get count. Oh, no, we broke something. What's the issue? We select from the substring with this whole thing as a string and Oh This select statement needs to be Wrapped right because this is our Yes I'm trying to understand my parentheses. This nested portion is The string that we pass into substring. This is the substring call and this is the select statement And we're checking if that value that's returned is equal to E No still failing Hmm. Do I need? That there let's use a single quotes again just to try it. Can I get a single character? Maybe? like a SQLite char No, no, I just want a character string composed of values in the ASCII table. So chr of What would eb That thing I need to use ord for that in python 101 How about that? select all of the names from the SQLite master where the type is equal to table and That string that's returned Will still die. I feel like I'm getting mixed up in some parentheses here case when select a substring of group concat is Table and those arguments get passed check if that when is equal to 101 That all seems fine maybe We don't need to concatenate things How about that when No, oh Okay, so now we're by ID so that had failed Can we specify Like F in that case Yeah, that went by count now Perfect. That's much better Let's Try She used this select maybe And let's specify that we want the name to be like the flag Table How about that? That's good. Now if I had the wrong letter for the start now we're decreasing by ID Cool Okay, so that's it. That's a decent proof of concept for our Boolean logic finally now Since we're just getting the name and checking it we can determine Maybe a the position and kind of leak out the full name So Let's try a while loop Let's get a list of Leap data I'm gonna find that as a list here and let's import String I suppose Because we want to be able to loop through like every single kind of character So let's do for character in string dot Printable Let's just do a proof of concept. Let's get this I'll take this here and We want to Get the position that we'll search at We want the position to be the length of the leak data so far So when we were checking the first Index the first position it would have been Empty so that I think should be plus one our position needs to have a little offset there So Let's add an f-string portion So that our position Can be filled in smartly based off the amount of leak data that we have And this character that we're trying Should be the value of the character that we're looking at character, right? let's Get the JSON data from that I suppose yeah, and then let's print J Zero to get the first item And just verify that this will kind of work for us. Maybe we don't need to pass that to JQ anymore Okay, so once we get to ideally a Different letter we should see a different response on one of these. Yeah, so this is Looks like the seemingly the first character that we would have leaked after that flag underscore prefix So eight I'm assuming so that will tell us that okay. This is a True statement and everything else will be false so we can check if This first index is equal to that response and If it is if that's a true response then we will do leak data dot append that Character that we're on and then we'll stop this loop of those characters, right? so leak data will now have a new position or new length so that the Position will be properly set and the character can iterate more so So while we're doing this, I suppose let's print out an F string Trying character Let's actually try to join together our leaked data With the character being added on to it. I Have nested double quotes inside it so that probably wouldn't behave So when we find eight then we get a two following it then we get an E and F Okay, I think this is carving it out for us Amazing We did it now How far will this go because we're looping forever? We might not I mean we're not gonna end right But because we've passed seemingly the hex values and we're gonna end up looping through the entire yeah Now we just died because we actually ended up sending an ampersand and that didn't like it So now we know our full flag table. Yeah So I'm going to say flag Or I guess like table name Can be that string so now we need to select out a Flag value we know that we are going to be selecting the flag Entry in the flag table so we can change this We can do flag as our substring from Table name as we've just determined and we don't need to use a where clause anymore or that and Because that's a specific one that we want to look at so Let's try that this might go for a while, but we can assume that a capital C is what we would like yeah Perfect, okay Chtb is kind of what we should end up getting Perfect. I am going to Add that start of that flag format in there and let's remove that print character here So at that point we can just let it go And let it try and leak out the flag, right? nice a Right, it's going Took a little bit of troubleshooting, but I think we got it everything set up. I Will pause this recording and now let us wait for this to leak everything out. Oh I got an error because of that ampersand in here, which I'm assuming might be doing some weirdness so Let's actually change up this loop printable Or that that pool of characters. Let's do String dot printable dot replace that ampersand with Nothing there we go. So that way we can remove that And everything that we had found thus far. I want to add into our leaked data So we know that we can start it where we just where we left off. I think that'd be much better Let's see if we get anything from that. I think we got a cruise through the whole alphabet, but we'll see how we do I'm stupid. I forgot to use this rather than the string printable one Let's try that again Okay, it also doesn't like percent signs, which is I suppose understandable Let's nerf that out just as well like we're kind of finding our own bad characters here Nothing wrong with that. We know that we still have the proof of concept. So we'll just let it go Also doesn't like dollar signs Part of me wonders how many of these will go ahead and run into If it's anything like any normal flag, it might just have underscores in here separated by kind of words. I Think that it has been there their flag format structure. So, yeah, we're gonna keep running into that issue So let's change this up. Let's use string Let's actually add in opening and curly braces and underscores actually that we should test for those at the end So let's use string dot ASCII lower case and string dot ASCII upper case Okay, so we need those and let's add in the ending curly brace portion there Now let's see how we do. Oh underscore right That makes complete sense order me nice order me this All right, I'll wait for this to go All right, it has leaked out order me this juicy info Didn't get the underscore and didn't get anything past lower case letters Looks like it did find that ending curly brace. So I'm thinking that's where we're at I think our final flag is going to be CHT be order me this juicy info and of course It'll keep trying stuff because of the while loop that we're in that while true, but that Looks like our flag ladies and gentlemen Let's uh, let's go try and submit this guy and there we go Alright, we did it that challenge is over that was a blind sequel injection with an Order by clause that kind of got in the way so we wouldn't be able to use stuff like a Union select like and or or or other kind of comparison things we kind of needed to use a nested query using these parentheses to add another Logic thing that we pulled down or select some data and because we have a little bit of know-how as to what a sequel light Database might look like and because we have this specific white box description here of the schema of the database that will allow us to kind of know better what we're looking for to find that flag table and then to get the actual flag value out of that table So we did it That's it. It took some Python scripting It took a little bit of troubleshooting took messing around took me getting the syntax for a case when statement, right? But we finally finished it up. So alright. Hey, thanks so much for watching everybody. I hope that was good I hope that was a fun one. I don't know I think I've showcased a couple videos with sequel injection like this or blind and boolean based sort of injection Where you just kind of toggle back and forth? But I think this was nice because the order by clause specifically I don't think we've seen before but you can still kind of use the same technique where you just logically search for something in a nested operation That's it. That's the end of the video That's all I'm able to showcase and cover for this one, but thank you so so much for watching everybody I hope you enjoyed this video. Hey, if you like these hack the box videos for the CTF Let me know hopefully I can get a few more recorded and put out But I'm having a good time with this and I hope you have just as well Thanks again to hack the box for letting me do some of these, but we'll keep it cruising. We'll keep them going I'll record something else real soon. Thanks again, everybody Please do those YouTube algorithm things would love if you could like the video leave a comment Love if you could subscribe. Thank you. Thank you. Thank you. Let's tune out of this thing. Bye everybody I love you. I'll see you in the next video