 Hello everyone. My name is John Hammond and welcome back to the YouTube video. Today I'm looking at a little bit more of the Google CTF that went on this past weekend and I want to showcase a challenge that is kind of similar to the stuff that we've seen just before. It's going to be looking at another web challenge but let me pull that up and we'll hop over to my screen here so I can showcase the LogMeIn challenge. So Google CTF was using dynamic scoring and this is a web challenge that got pulled down to about 87 points so it's not in the 50 point like easy baby beginner category although that was still really tough for Google CTF because this is a hard legitimate crazy cool capture the flag competition but this challenge prompt just says log in to get the flag we have an attachment to download so I'll go ahead and click on that looks like it's just a zip file that got pulled down and we have a web page to go explore. First of all this website is hilarious I cannot stop laughing at it like life like you've never seen it before for half the price this product and company reverse that is revolutionary a major step in the right direction our consultants are to help you to get the right result if we can't help you then we can't help anyone I love this is hilarious absolutely boilerplate website that you see in a cheesy capture the flag competition copy paste 2020 the about page I can't stop laughing at meet the team this is our lead tech support person Mike listen to these amazing testimonials from our premium customer I've been a customer for a while thanks Michelle all right there is a flag location that we can go access but oh we must be logged in to access that okay so I see a profile page but I obviously can't access that either unless I'm logged in so there's a login page I can go ahead and try like admin admin just as a simple default thing and that actually logged me in which is funny and Google will tell me hey change your password data breach on the site approved admin admin yeah that's been exposed already okay thanks appreciate that I don't need that last pass get out of here thanks I can go to the flag page but only Michelle's account has the flag so that doesn't help me somehow I need to be able to log in as Michelle even though I've logged in as admin quote unquote if I could log out I could try to log in as Michelle but I don't know her password so that will tell me nope invalid username or password okay so that's me poking around on the webpage let me actually go look at the source code and we've downloaded that already so I'll hop on over to my terminal I'll move that in the downloads folder it started with like a seven and it was a big big hash thing so let me move that to log me in dot zip and oh sorry I need to actually include that big hash there I'll go ahead and unzip that and now I have an app.js file let me open that up and looks like we have the source code to this webpage so it's seemingly written in node this is javascript here node allowing javascript to run server side and it looks like we're using the express engine to go ahead and actually serve these pages we have a mysql database kind of being used here so we require that library and we use cookie session cookie parser and body parser and we have defined the flag value but that's probably redacted that's why they're just using this ellipsis here and the target user okay we saw that already has to be michelle looks like michelle is the only one that can actually see or read the flag we're getting uuid okay so we can have some identification numbers we start up the express engine let that run and we're using cookie parser with a session v value and okay okay that's also redacted seemingly and we use body parser with extended set to true that's peculiar actually um I noticed and we've had some conversations about it over in the comments for the pasteurized video or the pasteurized video the first thing that I did with google ctf and the gimmick that we're able to go ahead and send those http parameters or the variables that we pass along on the web page the reason we can pass those as an object is because this extended value for body parser is set to true let me uh let me see if I can find any documentation on that body parser extended true or false looks like there's a thing url encoded extended equals true does the same for url encoded requests the extended true value precisely that request body will contain values of any type instead of just strings and there are some articles about this so let me zoom in on this real quick looks like that is the exact same knowledge and segment sentence that I just read okay chrome I zoomed in a little bit too much that can parse data like text and json what do these other pages say extended body parser url encoded my face is kind of in the way and this page is doing weird things the extended option allows choosing between the parsing url encoded data with query string library when false or the qs library when true the extended syntax allows for rich objects and arrays to be encoded in the url encoded format allowing for json like experience with url encoding gotcha gotcha okay same thing here okay sorry I wanted to go down that rabbit hole just to kind of offer some background and more understanding as to what that is and what it's doing and why that's peculiar and we will also be using that sort of thing in this video so app.use looks like that's going to end up requiring the session username and flag oh it's just pulling out okay what it's what it's grabbing from the session response and request here and some forwarding protocol with hgtps yeah is it running with hgtps it is funky middleware csrf tokens oh did we actually have a csrf token like if i view the source of this web page i just hit control you on my keyboard i actually noticed kind of tinkering with this there is a hidden element or an input type that is a csrf or a cross-site request forgery token but it doesn't have a value set like if i were to go ahead and open up my network tab if i send in like hey please subscribe cool cool cool i get this login post request that i just sent along with my please sub and please sub username and password but csrf is actually nothing i thought that was interesting it didn't have a value for the cross-site request forgery token whatever no cache off middleware authorization okay okay that's just making sure that we're logged in when we need to be we have some routes for log out about me etc there's the flag it's just going to render whatever template is there log in we'll retrieve these and oh okay this is it interacting with the database so maybe this will be interesting select all from users where username equals question mark and question mark and we're filling that in with the username and password objects that are sent these look like parameterized sentences or excuse me parameterized queries parameterized statements where we can actually just fill in these values and hopefully avoid sequel injection because it's kind of parameterized and prepared after the fact good good good if username lowercase is equal to target user then it sets the flag to the flag value otherwise it says okay only michelle's account has the flag and that's what we saw when we logged in as admin so that is interesting that logic there because this is javascript i just recently showcased one of the previous videos on prototype pollution maybe that could be an alternative because this username object could be something oh that's pulled from the database maybe that's a thing we would just need to be able to log in which we are but then we would need to overwrite or change the prototype of this to lowercase value and set that to michelle then we could try and do that flag value that's an option and that's a thing um but i want to kind of pivot back to our body parser url encoded trick and gimmick because maybe we could try and bypass a login if we actually sent an object through right so let me see if i can do that with curl this will kind of be a kind of a guess we're like shooting from the hip here let's use the post method so curl tack x and i'll specify data of username to equal like john and i'll specify another argument for a password equal password whatever that will return for me it says invalid username or password that's totally fine we expected that but if i were to change this and use that htp object or pass them like an array or thing here will that give me any extra results error invalid username or password no that's not right alert times okay um how about password anything whatever we'll just fill in a value for that see if that will actually do something different oh unknown error error error bad field error unknown column anything in the where clause that's peculiar how is that happening we can take a look back at the source code here where's that login function select all from users where username is equal to this thing and password is equal to this thing so password we've just passed in but now it's an object and we pulled it out of that is it reading that like a column password is equal to anything where is it is it huh that'll like parameterize out like password is equal to anything is equal to that or does that just take the place of that column username is equal to anything and password is equal to what if i use something where i know a column actually exists like username password username is equal to that how does that look no invalid username or password can i use that sorry i'm just fumbling around on my keyboard what if i set that for anything no i want to use a real thing username username of username that still prompts me to log in do i need to use like admin still invalid username or password okay how about password username can still gets me a login admin admin that still does weird stuff okay what does that need to be username is equal to admin username equals or user earn oh wait a second if we set username to michelle michelle is that the right spelling yeah it is username username equals michelle that also fails we still have our login prompt password of username is equal admin can i set that to like nothing password still requires a login what about username password of password is equal to that no okay there's got to be something that does this username is equal to michelle and password of username oh wait what just happened there we set going back to our code we set username to michelle and use and we're using this object here to denote a column what and username is equal to and username is equal to password how did that work did i actually log in if i use that curl tack l will that send me along there nope i can't post that so that post method is going to keep with it let me just do a simple python script here so classic shebang line user bin environment python and then let's import requests because we're going to be doing some request things let's grab this url from that web page i just copy and pasted that i'm actually going to remove that login suffix there so i can do requests actually let me create a session because if we're going to log in requests dot session and then for good practice let's go ahead and close that we'll set that our like response variable to equal to s dot post of the url with the login page and data can equal username set to i guess michelle in that case and password can be like literally anything i think let's go ahead and print out that r.txt see if that gets us anywhere that still requires me to log in because i didn't do any funky object passing there in that syntax let me set that to html so it's a little bit easier for you to read there we go um so password as an object needs to have something set username can be set to anything there we go okay but and that doesn't matter what it is so password is equally i'm still a little confused as to how that's working but i guess whatever and an auth bypass as an auth bypass so let's now because we're logged in just go ahead and s dot get url over to that flag location that we know is there we can see that so let's go to flag and move that r.txt there we go ctf a premium effort deserves a premium flag that's nice that's cute okay cool we can submit that and get some points i want to learn a little bit more as to how and why that's working so again i always offer like transparency and truthfulness and hopefully honesty and hopefully that jives well with you guys i don't want this to be a boring stupid thing we're like john you're just showcasing someone else's write up yeah maybe that's boring but we're all trying to learn i'm trying to learn especially so that i mean that whole tidbit of knowing that that body parser extended equals true thing like allows this kind of gimmick to happen where we can pass an object along through but how does that look when it's going to be taking the place of this original parameterize like sequel query here u and p are the objects that we pass through are they also just being set to something like i want to see if some write-ups cover that so if you wanted to see the solution to the ctf challenge i mean like this is it you could do any other field that will pass through and that should and that should still work um maybe did that did that not work spit that guy out does they have to be password and username yeah so that fails password of username because we set that to a value that already exists maybe that's why maybe it has to be something that's valid so if i were to log in with admin that doesn't work why password password to be anything still doesn't work but when i use michelle and i set the username to anything that works so i want to figure out how that is happening okay enough tangent sorry for for those of you that wanted to see the solution to the challenge it's that syntax it's using username to that target user and then passing in kind of a key for this object because we're passing in password as an object value no longer just a regular string because that body parser has extended set to true we can use that syntax where we're specifying a different column and you saw that when i just ran a test of like anything we got that funky error bad field error unknown column anything in the where clause so because this is taking place in the where clause i wonder if it's doing like if it's changing this let's look at some of the write-ups and explore this a little bit more but if you wanted to stop watching because okay cool we got the flag you can totally do that let's go to ctftime let's take a look at the google caps the flag event and i'll click on these event tasks and write-ups here and i want to look for log me in so i have no shame and let's open up literally all of these write-ups see what this guy does see what this guy does that opens it in a new window and i don't want it to i'll just remove all those okay log me in let's kind of learn a little bit from the pros this is the web page that we saw we logged in with admin admin but only michelle's account can get this so we observed the session cookie oh the cookie actually oh yeah that's that's what it sets and you could see that in the source code here when it pulled that out with the locals and things it's grabbing the session and that's apparently just something that's actually set in the cookie the app.js attached in the description contains the same flaw as the pasteurized challenge where we're using that body parser extended equals true so you could specify actual objects and set values in there or set keys where you could be using an actual column name from the database the administrator user is different from admin that work this allows us to log in as michelle without providing a password and retrieving the flag from the cookie okay so they did the exact same thing where they're setting michelle as a username and the password is going to be a valid password value set there will be an actual valid column name well that do the exact same thing id that logs in just fine how about password that doesn't log in just fine i want to understand why that's happening the username does so anything that's not the column already it's already being queried okay this challenge exploits the fact that we send an array which when parsed makes a sql server execute a similar query to this select all from users where username is equal to michelle and password single like back tick password is equal to one how does that work what are these back ticks and that's that okay so i guess i understand that that syntax happens but like my sql pass object that is just inserting into the database with the names that are being set there but if they aren't using names what happens that i guess is the closest thing that we've seen though thus far to an actual answer but all right i know this is becoming a long video and me wandering around the internet probably isn't all that entertaining so we can stop this pretty soon but i'm just kind of exploring everyone else's write-ups to see what's going on here hello is set to a if we're using that body parser object you can see that objects are converted into a comma separated attributes we know that username is supposed to be michelle but we do not know the password so what we can do is try and pass an object in the place of a password with the known attribute that would make sense i think that's the most logical thing where we're using okay username is going to be michelle and password comma username is going to equal michelle so and password will probably evaluate the true because that's just existing as a column and the username is going to equal that thing maybe that's how it should be parameterized out does that how it is that how it looks like in the syntax so going back to it we would have username set to michelle and password username equals michelle or that's so funky and password okay that's enough that's enough of me musing at that i know this video got super boring and stupid at the end that's my process of learning and exploring and walking through and trying to see and learn a little bit about this but i really really do recommend going to check out these write-ups especially after a capture the flag competition i'm really excited to go look through some of the stuff for the f word ctf that went on this past weekend so okay thanks for watching everybody i hope you didn't mind me falling down the rabbit hole there at the end that's me shooting from the hip and just trying to explore and learn and tinker with this but i i think the real takeaway is that with that body parser extended set to true there might be some interesting things you can do and and gimmicks and wrenches you can throw with passing in an http like object or array there or something different than a regular string so that's enough thanks so much for watching everybody i hope you enjoyed this video if you did please do press that like button do the youtube algorithm things maybe leave a comment maybe subscribe super duper grateful if you do thanks so much for watching everybody i'll see you in the next video take care