I was once reading my Twitter stream and came across a link to a systems monitoring service I had never heard about before. I went to their website, liked what I saw in their list of features and their pricing, and signed up for an account.
Then it was time to get a test system into their monitoring dashboard. As is quite common in this domain, they offer an agent to be installed on my host. Agent software was conveniently packaged as a DEB file (I was targeting Ubuntu as a test system) - one bonus point to the vendor!
Like with all new DEB packages that don’t come straight from Ubuntu mirrors, I like to download the file and inspect it before installing it.
If you have a DEB file, you can get to its contents without installing the package by running the following commands in a temporary directory:
$ mkdir /tmp/deb_analysis $ cd /tmp/deb_analysis $ cp /path/to/file.deb . $ ar xf file.deb
You will end up with 2 files that you care about - data.tar.gz and control.tar.gz. Once you untar control.tar.gz, you will see the main control file of the package as well as various trigger scripts around various phases of package installation and removal (what commands to run before package is installed, after package is installed, etc).
In control I usually pay attention only to dependencies to make sure the list is not insane - I don’t like installing unneeded things and I look for things I intentionally don’t want on my system for one reason or the other. (To give a hypothetical example - if a package depends on a specific version of kernel or if a package depends on something that I installed locally from source).
Having not found anything bad in control, I moved on to postinst. It’s usually a shell script so it’s not very difficult to figure out what they are trying to do here.
In this particular case, I noticed that they wanted to add their library to /etc/ld.so.preload - thus ensuring that their library gets loaded into every single program that runs on my system. man ld.so
I immediately lost interest in contunuing to evaluate this solution, because this level of integration for a monitoring system was beyond what I am comfortable with. But it raised and interesting question - what can one do to protect against such changes without one’s explicit knowledge and consent?
There could be many things that can help here but recall that a package installation requires root powers - so postinst script is going to run as root. Things like apparmor won’t necessarily be effective - root can edit and reload apparmor to allow itself to do what it needs.
I like a very simple trick in this situation - chattr +i. This command turns on an immutable flag on a given file. From man chattr:
A file with the `i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
In my case, creating an empty /etc/ld.so.preload and setting its ‘i’ attribute will usually be sufficient to make sure this file is not modified without my knowledge.
That is until people start putting chattr -i calls into their postinst scripts - which would clearly indicate evil intent. Don’t do it!