Care and feeding of RPM

Kurt Seifried, [email protected], Copyright Kurt Seifried 2001


 

I'm always amazed at the lack of articles on topics like RPM and PAM. Basic systems components and tools that people use every day but generally speaking are poorly understood if at all. Prepare to be educated. RPM is "Red Hat Package Manager" and is currently the most widely used package format for Linux (yes, I know about dpkg and tar packages) with most vendors utilizing it. RPM allows you to easily install, uninstall and query packages and the RPM database for information. Generally speaking RPM's must be installed as root, basically RPM's can do anything on your system, install new files, overwriting files, reconfiguring system settings, add new users, etc. Why is this important? Because many people download RPM's from semi-trusted or untrusted sources and blindly install them.

Making sure RPM's are legit

The first step would be to download RPM's that were created by a trusted party (i.e. your vendor, your corporate LAN admin, etc.) and check the GnuPG signature on them. Unfortunately there are problems with this approach, detailed in the following security advisory:

http://seifried.org/security/advisories/kssa-001.html

If you want to use an RPM that comes from an untrusted source (i.e. you found it on the web, in the contrib directory, etc.) then you shouldn't use the binary RPM. No matter how much verification you do of the package to make sure it won't overwrite critical files it is always possible that an attacker may have trojaned one or more of the binary programs contained in the RPM. So what's the answer? Source RPM's. Simply download the source RPM and "install" it (I use the term loosely since installing a source RPM simply unpacks various files into /usr/src/vendorname/). The spec file (located at /usr/src/vendorname/packagename.spec) should list the official URL to download the source tarballs (i.e. Apache 1.3.19), you can go get signatures of the files and check them, or download the actual files and overwrite them. To be extra careful you should also sit down and read any patch files included with the source rpm as it is possible for an attacker to use patch files to introduce back doors and so forth. Lastly you should check the spec file, this is actually one of the best vectors for an attacker to introduce backdoors or take control of your system.

RPM spec files

If you haven't read an RPM spec file yet I suggest you grab a source RPM and read along as it were. The top of the spec file is typically informational in nature, package name, vendor, version and so on. Then comes the interesting stuff. For many software packages you need to do just more then lay down various files, typically things like adding users, restarting services and modifying global configurations needs to be done. This is achieved by pre-install, post-install, pre-uninstall and post-uninstall scripts. These scripts are usually written as shell scripts but you can also use Perl, obviously since they run as root you can do pretty much anything. In the spec file these sections are preceded by "%pre", "%post", "%preun" and "%postun". Another cool thing you can do with RPM's are triggers. Like a database trigger that waits for an event (such as a record having the first name John) RPM triggers can "watch" for a package to be installed or uninstalled. Thus an attacker can place a logic bomb of sorts, the next time you upgrade ssh for example it would add an account with UID 0, and send out an email saying it did so. Of course there are many other places an attacker can place malicious instructions, such as the "%pre", "%build", "%install" and "%clean".

Querying RPMs

The pre-uninstall and post-install scripts are difficult to find, one quick way to get the post install script for every package install on your system you can simply:

rpm -qa | xargs rpm -q --queryformat 'name: %{NAME}\n%{PREUN}\n\n'

Which should give you something like:

name: libtermcap
(none)

name: sed
if [ $1 = 0 ]; then
   /sbin/install-info --delete /usr/share/info/sed.info.gz /usr/share/info/dir
fi

name: slocate
if [ "$1" = "0" ]; then 
  /usr/sbin/groupdel slocate
  rm -f /var/lib/slocate/slocate.db
fi

name: ntp
if [ $1 = 0 ]; then
    service ntpd stop > /dev/null 2>&1
    /sbin/chkconfig --del ntpd
fi

Other things you can query are PREIN, POSTIN, PREUN and POSTUN. These are stored in /var/lib/rpm/Packages which is unfortunately a Berkely DB file, however you can use text utilities like grep or strings to find things (such as "grep -i rewt Packages"). There are several dozen things you can query for (name, packager, provides, requires, etc.) and these are covered in the RPM book and online documentation.

Installing RPMs

Before you install an RPM you should verify that it came from how it claims to be (i.e. check the GnuPG signature), then you should query it to make sure there are not spurious triggers, post-install instructions and so forth. If you are worried about triggers you can use "--triggeredby" to see what a package will trigger, if you do not want a package to trigger anything simply use "--notriggers". If you have customized your system extensively or simply do not to run the scripts included with an rpm you can use "--noscripts", during install it will ignore pre-install and post-install scripts, during uninstall it will ignore pre-uninstall and post-uninstall scripts.

Building RPMs

If possibly you should not build RPM's using the root account, either chown the /usr/src/vendorname/ directory so that a non root user or group can use it, or setup your .rpmmacros file so that a different buildroot and tmp directory are used during the actual build process. Personally I find it easier to have a user like "buildrpm" that owns /usr/src/vendorname rather then creating a complete set of directories for building RPM's and so on. Another concern is the use of tmp directories by RPM, to specify a specific tmp directory place the following in ~/.rpmmacros:

%_tmppath /home/user/tmp

One thing to note is that RPM strips the leading "/"'s from files when unpacking tar archives so you need not worry about an attacker creating a tarball with "/etc/passwd" for example. When possible you should have a system dedicated to building rpm's that is heavily secured, just imagine if an attacker managed to break into a machine used be a vendor to build RPM's, or onto the one you use for building updated RPM's for your company's servers.

Summary

RPM is a very complex and powerful tool for building software packages. Blindly downloading and installing RPM's is of course very dangerous (this goes for installing software on any operating system). If you choose to build foreign RPM's on your machine then you should inspect the SPEC file for malicious commands and also verify the source code used and any patches. The good news however is that verifying the origin of RPM's is relatively easy, and as the majority of your RPM's will likely come from trusted sources then you should not have too many problems. Lastly with the use of scripts and triggers you can easily build RPM's that will notify you when installed (i.e. put a command to send mail out so you know when someone has upgraded a machine), or properly clean up after themselves. Used properly RPM is a very powerful tool.

 

Reference links:

http://seifried.org/security/advisories/kssa-001.html

http://www.rpm.org/

 

 

 


Back