This document explains how to bypass the /sbin/dhclient
AppArmor profile installed in
Ubuntu by installing a kernel module. This is a simple task, but I didn't know how to
do it before today. Hopefully you find this useful.
Tested on 17.10.1 using the isc-dhcp 4.3.5-3ubuntu2.2 package.
In this advisory, Ubuntu says that the vulnerability
CVE-2018-5732
is mitigated by the dhclient
AppArmor profile. This is interesting because in this case
the bug is a remote RCE on
Ubuntu, and the claim this is mitigated might make people think the update can wait if
they use AppArmor (enabled by default in 17.10, and available since 7.04).
However, looking at the AppArmor profile installed by default in Ubuntu, a few things caught my eye:
- It allows unconfined execution of
/etc/dhcp/dhclient-script
and/sbin/dhclient-script
- It has
capability sys_module
.
I spent some time looking at the default /sbin/dhclient-script
and noticed it clears some environment variables, but I didn't see it clearing LD_PRELOAD
.
Turns out that Ux
actually cleans the environment from LD_PRELOAD
and LD_LIBRARY_PATH
,
but it doesn't clean PATH
, ENV
, etc.., so the script has to do it manually. This behavior
is described in Ubuntu's AppArmor security review
but I couldn't find any other obvious bypass using bash (read more).
Note that this does not mean this is safe. You can probably find a way to bypass it.
Then I started looking at capability sys_module
, and I wasn't sure why it was there, as
it seems like net_admin
should have been sufficient
to load any network modules. So, I decided to learn how to write kernel modules, and load
them, to see if I had misunderstood the AppArmor policy, but as expected, it let's you
load any module you want with root privileges.
In order to test this, just download this gist,
unzip it, and run make all
and then sudo make install
.
This will replace your local dhclient
with another version that just loads a kernel module. To
test this, you can try to re-connect your internet, or just run sudo dhclient
and wait (note
that it will fail to execute because our version of dhclient
doesn't actually do anything).
Once it's done, run sudo make uninstall
to make everything go back to normal.
If all worked as expected, you should be able to see /var/log/syslog
with the contents of the
first 100 characters of /etc/shadow
:
Mar 11 15:40:40 instance-2 kernel: [ 158.100667] [EVIL] loaded.
Mar 11 15:40:49 instance-2 kernel: [ 167.132990] [EVIL] /etc/shadow root:*:17593:0:99999:7:::
Mar 11 15:40:49 instance-2 kernel: [ 167.132990] daemon:*:17593:0:99999:7:::
Mar 11 15:40:49 instance-2 kernel: [ 167.132990] bin:*:17593:0:99999:7:::
Mar 11 15:40:49 instance-2 kernel: [ 167.132990] sys:*:17593:0:99999:
The reason you need sudo
to run these commands is because rather than exploiting the vulnerability,
we are just replacing the dhclient
binary with our own. A real exploit would obviously already be
running as root, and wouldn't need to write any files to /etc/dhcp
, and rather it would just put
the module directly in memory.
sudo apt-get install unzip build-essential linux-headers-$(uname -r)
wget https://gist.github.com/sirdarckcat/fe8ce94ef25de375d13b7681d851b7b4/archive/master.zip
unzip master.zip
cd fe8ce94ef25de375d13b7681d851b7b4-master
make all
sudo make install
sudo dhclient
sudo make uninstall
make clean
tail /var/log/syslog
Upgrade your isc-dhcp-client
package to the latest version, which fixes the vulnerability found
by Felix Wilhelm. You could also replace
the AppArmor profile with this one
(untested, use at your own risk!).
It might be because dhclient
tries to load a module.
Other policies
do not include it, so it seems fine to remove it. Note, however that there are
other ways to bypass the policy.
The AppArmor policy in the isc-dhcp-client package is not maintained by ISC, it is maintained by Ubuntu, so it was reported to them. Note that this is not the only way to bypass the policy.
The code to read files in evil.c runs as a kernel module, so it is not meant to make any syscalls, so it reads the filesystem directly.
Because you probably forgot to run sudo dhclient
after installing it. Make sure to run
sudo make uninstall
after or your computer will be left without internet for ever.
This is cool, thanks.