 Welcome back everybody to another YouTube video. We're still looking at the cyber apocalypse, hack the box, capture the flag. I don't know what order to kind of say those words and they all kind of come together. So let's get to it. I'll hop over to my computer screen here and we'll get to the good stuff. So I'm here at the interface and I wanna take a look at this alien complaint form challenge. I can take a look at the challenge information, the details here. The aliens found a cool new security feature called CSP. Ooh, some content security policy, right? And have since implemented it into their HR complaint form. There are reports that any issues reported by humans are not taken into account and instead deleted. The human resistance has left a back door and the website that can be used to acquire sensitive information from the aliens. Can you find it? All right, so let's start up this instance here. It will go ahead and create an IP address and port for me and I'll go ahead and download these files just as well. I'll go ahead and open up a new tab where I can go visit that instance and here we are at the HR complaint form. It says, if you're human, we don't care. So we can specify a complaint seemingly. I will type in the obvious complaint, submit that and it says the Galactic Federation has processed your feedback, okay? So I see a link, kind of a navigation up here, a complaint list. If I click on that, does it take me there, please? Maybe? Is that actually a link? Yes, slash list. Oh, it is disabled. Okay, I guess because I'm human and it doesn't care. Only local host is allowed. Roger. Could I do like some stupid cheeky like X forwarded for thing? Let's apply a header X forwarded for, let's do local host, local hoist classic. Only local host is allowed. What about a little one, two, seven, zero, zero, one. Only local host is allowed. Am I X forwarded for, X forwarded from? Are those different things? Let's try a little X forwarded from. No, still not having it. Okay, well, you know what? Let's go ahead and get started looking at this source code here. If they are gonna give me a download, maybe they got something worthwhile in there. So that is alien complaint form. We'll move into this directory. I'll go ahead and extract all that. And let's see what we got. We have the Docker file again, I will take a look at. Of course we're using node, that seems to be the trend so far with these challenges. Installing libraries and things that it needs, app, et cetera, et cetera. Good enough. What else is in here? Let's check out that challenge directory. Oh, we have a bot.js file. Oh, it's gonna use puppeteer, okay. Puppeteer is kind of like a little headless browser that can go ahead and connect to some web pages that wherever you'd like. Typically often used for like cross-site scripting style capture the flag challenges or having some automated thing go check a web page. So I'm gonna assume, yeah, okay. So this bot will go ahead and go look at the list of complaints it looks like it goes to it. And it has cookies. So the bot cookies are kind of what I need or the admin or whatever that checks this. And their flag is stored in a cookie. Their cookie has a flag that includes the value. Right now it's just a placeholder but I'm sure it'll be the real flag once we get to the actual remote target. But it totally ignores human entries, whatever. Does it actually do this? I'm sure it like has to still read them, doesn't it? If it's going to that page it'll kind of load whatever's on there. What else we got? Database, this just stores the feedback. Okay, someone ate my intergalactic donut. Man, that's rough. I know the feeling. You can add a feedback if you are seemingly human. It inserts it into the database and then the list will get feedback. I'm gonna assume it selects it all out. Okay, nice and easy with SQLite. What about this index.json file or js file, sorry. SQLite database feedback.db Gonna listen on localhost at 1337. I think we saw that here actually in the bot. It will try to navigate to localhost 1337. And that's where the cookies are set. So that's super important. If we are gonna try and access these cookies with some cross-site scripting then it's forcing us to kind of visit through localhost. And I mean, our bot is gonna do that. So what else does this index.js do? Nothing, what else do we have? Routes, that's just the route for itself, isn't it? Oh no, this is new. We get the bot, we have the database. If a request is made to that list endpoint where we were going, if the request IP address is not localhost, ah, then it will send a 401 only localhost is allowed. So that's what we were running into earlier. Otherwise it would list it. Okay. So if we were to post to submit a request, we get the complaint object from our request and then we add it with the database as we've just done and then the bot will try and go access it. So it will say, okay, the Galactic Federation has processed your feedback. Good enough. And then it send a message whether it, oh, if it errors, it will tell us it crashed. I see. Otherwise we don't have any parameters in there. What is this? What is this called a JSONP? This does this after, right? Get JSONP checks our query, checks our requests with the variable callback. Is that order display or concatenating on display? And then it will return JavaScript feedback equals, ah, and it will send out the string of our callback executing, including the feedback. I'm a little confused as to how that works. I might be Dumbo reading this code the wrong way, but that is API JSONP, right? Yeah, okay. So that will return our feedback. Oh, the callback looks like it's a function call. Oh, and display is the value if it's not supplied. So if callback is not supplied or display, then display is what's going to run here based off of the feedback. Feedback is gonna come from us getting the feedback and it will return that, right? So callback can equal, it's gonna run JavaScript, is it not? Display is gonna do something. Can I do like alert that alerts? What if I add a one there? But then I need to display alert one. Can I like, am I viewing the source here? This is still genuine content, but it'll render that out, right? I can just use a script. Can I not? I am weirded out right now. Script alert one, display. Let me check the source code one more time on that. Content type application JS, let feedback, oh wait, feedback, then we retrieve the feedback. So stringify feedback, that's always gonna return from this database, seemingly. But the callback is something that I can supply. So can I do that on like list? Only local host is allowed. I'll never be able to do that unless I were to run this like locally, right? If I run it locally, will it work better? This list thing doesn't have any notion of it though. Like list doesn't know what to do with that callback. Maybe I'm kind of getting like two in the weeds on this. Can I, can I like run this? Can I do this? We'll challenge NPM. Can I run this thing? Can I like do this locally? NPM run, NPM start, I think? Start. I need to install the packages. It looks like NPM install. Oh gosh. I'm not a node guy by any means. I don't know what this'll do. Getting puppeteer, kind of downloading the headless Chrome that it might need. Yeah. Okay. How about NPM start? Okay. It's running on local host. One, three, three, seven. Yeah. Now, can I get to list? Yeah. Okay. But if I were accessing lists from local host like the bot would be, what can I do? Is there public? Yeah. List.html. Oh, this calls more JavaScript. That's in public static JS, list.js. This will display out with the table format all the complaints and the feedback and there's JSONP again. Oh, it does JavaScript with the callback URL like with the callback query and it adds it to this page. Is that something that I can do? Like callback equals alert. Oh, those are the objects though, right? Alert one, one. Cool. I mean, this isn't all that helpful. It's cross-site scripting on myself. How do I, does that do that for every complaint though? Like if I were to actually add an alert one, I won't see this happen because the bot will go ahead and do this, right? Now that would be accessible at list but it's already pruned and removed it. So can I like, let's do a 9,000 or something. Let's go back and add a image source equals this thing on error equals window.location, I guess, can be HTTP localhost 9,000 and that. So if the bot were to see this, they would be carried hopefully to localhost 9,000. Maybe, would that work? Let me try that back on that list style thing. So callback equals alert, me triggering it automatically. That doesn't do anything. Is it supposed to do anything? Oh no, no, no, no. This is just gonna automatically run JavaScript in this setup, right? JSONP, that is not a function. Yeah. Can you do the display? Yes. Oh, okay. So that called back. I am, now it triggered. So if I were to listen one more time and if the bot were to go ahead and do this kind of on its own, this would be back at the home page. Let's add a JavaScript syntax there and then add alert, no, display. If I do that, does it go ahead and do that? No. How is it gonna end up triggering that cross-site scripting? If I do a script, oh, wait a second. Could I use an iframe to trigger it? Like if I had an iframe that would reach back out to localhost on itself, that's whack. And then go to list and add callback to equal that JavaScript. Oh gosh, window.location. That needs to be URL encoded. Let's URL encode that real quick. I'm going to import urlib, urlib.parse.quote equals HTTP localhost 9000. All right, so we got that magic string do it. Oh, but it's in an iframe. If it's in an iframe, happens. Can I do it for like the above, the object above it? No. Do I need to like specifically tell it the link there? If we were to supply a complaint that would use an iframe to callback out to itself, accessing list with the callback object in there, how is that wrong? Wait a second, do I have a stinking crap? No, I didn't even encode this with quotes. How about that? I just added a single quote surrounding it. So the 3D should now still have single quotes. Are we already inside? We're not inside single quotes, are we? How about back ticks? Oh, but hang on, maybe I need to do the parent again because I'm stuck inside the iframe. Back to URL encoded single quotes, maybe? Please? Nothing. Oh, wait, we need the display to like run it. Yeah, I completely forgot about the stinking, the stupid function that we needed to call. It's like, oh, that's not a function. Yeah, I know it's not a function. So, now that gets a callback. Can I add in a cookie? C is going to equal ending quote, add document.cookie? Shoot, shoot, I wasn't listening. I wasn't ready. I wasn't ready, send it again. I muffed stuff up. What did I do wrong? HTTP colon slash slash H local host 9000 ending single quote adding document.cookie. That sends it to C equals. But can I have like JavaScript evaluate something inside that string? I wanted a dollar sign in there. Did I not put a dollar sign? Oh gosh, this is getting hard to read and see. So let's try the dollar sign to specify like a variable to be included in the string. So if I submit that document cookie. No, why did it not add it in? Why did that not work when we would add it in? Oh, the plus sign need to be stupid and, ah, does the plus sign need to be quoted? That makes sense. No, quote plus is a thing. No, why doesn't that evaluate when we use it in the dollar sign? Cause the dollar sign syntax is supposed to allow me to dollar sign document.cookie. Unless should it be like window.cookie? Is that a thing? I don't think that's a thing. No. And it's still not actually evaluating it. What if we tried to like base 64 encode it? I should probably set this on like tech K so that it can keep receiving requests. That doesn't, does that need to be URL encoded? Maybe that does. Document.cookie. It's still the same stinking thing. Is that JavaScript variable inside of string? How to interpolate variables? Temple literals. I'm literally doing that. Oh, no. They have to be in the back ticks. Are you serious? That's how that works? Oh my. Okay. I'm truly sorry. So, will this payload work remotely? Let me take note of this. Let me take note of this payload here. What's the name of this challenge? Alien complete forum. Let's make a stupid like notes.md. And then this payload is kind of what we need, but we'll have to call back to ourselves on Ngrok. So let's listen on 9,000 again. And then let's do an Ngrok HTTP. Okay, so now that Ngrok is cruising, we can modify the payload, not going to Port 9,000 and going to localhost, but going to that IP address. And then we wanna give that to the actual target. So let's start listening, which we are. Slap in this payload, which uses an iframe to call out to localhost list, invoke cross-site scripting with the callback function or little query there, use window.parent to escape out of the iframe and drive the original browser over to our Ngrok with the dollar sign syntax with templating apparently in the back tick string and the display to do it. So if I hit go here, we get the callback. And there is our flaggy-waggy. All right, this one took a lot out of me. I'm not gonna lie. What? What? Nice. So does that make sense to you? Like it makes sense to me, but it's not like intuitive. We saw that list was the field that we could access locally. And the reason that we were able to track it down was because we were able to like spin this thing up locally and just test that. And it's cross-site scripting, just a little like nested. So there's that. And the display function, I guess, was something that we genuinely call it. Is that legitimately a JavaScript thing? No? Is that just defined? Oh yeah, it's a function call. Now I understand. Display was the function that would just like run that out on the page. Holy goodness. Holy cow. That's our payload though. That's it. That's enough. That's enough of me yapping. I didn't mean to kind of carry on with that anymore than I needed to because I know that was painful to watch. It was painful to do, guys. So, hey, let's go ahead and grab that flag. Let's go ahead and submit that thing. And let's call it a day, you think? Let's alien complaint form? Dude, dunzo. Okay. Nice. That was rough. But hey, maybe a learning thing. I will never forget now that you absolutely have to use the back ticks for that kind of string if you are going to do that like little template interpolation thing with variables. I'll never get that out of my mind anymore. I say that now, but I'm sure in the future when I do a video on something like this, I'll fail again. Thank you so, so much for watching everybody. Thanks for tuning in this video. I hope you had some fun. I didn't mean to be struggling as much as I did, but hopefully that still makes it an entertaining video and maybe you get to learn something new out of it just as well. So, I think that's it. We've been going for a while, but I hope that there was some quality content in that. Thank you so, so much for watching. Again, as always, thank you to Hack the Box for letting me crank on some of these and get some content and video out for you. But hey, thanks. Please do those YouTube algorithm things. Like the video, comment, subscribe, hit the bell, other numbers and statements. Thank you again and again, everybody. I love you. I'll see you in the next video. Bye now.