Just Went Out for Bread, or the Story of One Hack

A freelancer hired to configure an email server stumbles upon an active intruder's screen session, discovers replaced SSH binaries, a Linux rootkit, and has to rescue the system from cascading segmentation faults.

It all started when someone approached me (as a freelancer) for help and asked me to configure exim4 so that their email newsletter wouldn't end up in spam. They even thoughtfully sent me a link to an excellent article.

A couple hours of work including DNS updates, but things didn't go as planned. After logging in as root, I launched my beloved screen out of habit with the command screen -x and witnessed a most curious spectacle in everyone's favorite /dev/shm directory. The attacker hadn't bothered to close the screen session, or was perhaps still working in it. And so the quest begins:

The first thing I did was review what the attacker had been up to:

wget http://ravenul.zzl.org/it/noi/up/8.txt
mv 8.txt list.txt
php lol.php
php lol.php
netstat -an | grep :22
w
rm -rf list.txt
w
rm -rf .x
netstat -an | grep :22

Apparently they were sending spam and running some file ".x" (or was it a directory?), and also checking SSH connections. There was also an archive with a PHP script lol.php, which I unfortunately forgot to save.

The output of last and who commands showed nothing supernatural — no root sessions for a month, which the server owner confirmed. However...

$ lsof -ni | grep ssh

...showed an established connection with IP 172.190.125.14, which I immediately killed.

I noticed something about /usr/sbin/sshd:

$ ls -la /usr/sbin/sshd
-rwxr-xr-x 1 root root 320724 Oct 11 23:29 /usr/sbin/sshd

Next to sshd sat sshd0:

$ ls -la /usr/sbin/sshd0
-rwxr-xr-x 1 root root 757356 Jul 31  2010 /usr/sbin/sshd0

Deleting the file didn't work:

$ rm -f /usr/sbin/sshd
rm: cannot remove '/usr/sbin/sshd': Operation not permitted

Let's dig deeper:

$ lsattr /usr/sbin/sshd
-u--ia------------- /usr/sbin/sshd
$ chattr -aui /usr/sbin/sshd
$ rm /usr/sbin/sshd
$ lsattr /usr/bin/* | grep -v -- '-------------------'
-u--ia------------- /usr/bin/ssh
$ chattr -aui /usr/bin/ssh
$ rm /usr/bin/ssh

I reinstalled openssh-server and openssh-client. Everything seemed fine, no more threats, nothing else suspicious found. I decided to also update the system, and the tzdata was old (hello, Medvedev and the timezone reform!). I checked /etc/apt/sources.list and /etc/apt/sources.d. All files were in order, no suspicious entries, dates unchanged for a year. After apt-get update, I applied all security updates to Debian Lenny, including a new kernel. Well then. Time to reboot. Just in case, I requested KVM access (which turned out to be a wise decision) and started waiting.

The next day, KVM access was provided. I typed "reboot" and then — bam: dozens of segmentation faults. Hair turning grey, hands shaking. I think many can imagine my situation. As they say, "if it works — don't TOUCH it!" but after discovering the intrusion, I had to apply updates and reboot.

In short, I pulled myself together, began investigating what was wrong, and booted into single user mode. The mount command caused a segmentation fault every time it was called, even without parameters. The filesystem was read-only, nothing could be done. /etc/fstab was fine, df also worked. The date command also segfaulted for some reason. I ran a disk check (software raid1) fsck.ext3 /dev/md0 — everything was fine, no anomalies. What was going on? I started thinking that I had crashed the system myself, since I had updated the tzdata package, which is directly related to time. And then the DSL connection with my ISP dropped... I rebooted the modem — connection came back up, great!

The server owner was furious, as the server had been down for several hours, and decided to submit a ticket to "Infobox" support. Meanwhile, I'm stressed out, continuing to dig through the system. The most sensible solution seemed to be to reboot the machine and boot from a liveusb so the disk would be RW, then figure it out from there. I started debugging mount with whatever methods were available at the moment. gdb wasn't installed, only ldd was available, which showed nothing serious, and export LD_DEBUG=all, which also revealed nothing supernatural. The segfault simply started after initialization of all libraries. Then KVM told me it was disconnected. Right, support arrived. I walked away from the laptop and continued thinking...

While standing outside and breathing fresh air, a very educated cockroach ran into my head and said, "What if the files causing the segfault are replaced?" Said and done. I waited to hear what the client would say about the support ticket. A few minutes later, he forwarded me the support response:

The partition table is damaged, and it cannot be restored by express methods.

If you wish, we can engage our system administrators (the cost of work is 870 rubles per hour) for restoration.

Alternatively, you can do it yourself. In that case, we recommend using Gpart (http://packages.debian.org/ru/sid/gpart)

Holy cow, I thought... I told the client that this couldn't be, since fsck had checked the disk and found no filesystem violations. The client wrote a response to support, and meanwhile KVM access returned, where I saw the same futile attempts to call mount, hdparm (which wasn't installed), and work with fdisk.

The latter displayed nothing other than:

$ fdisk -l

Disk /dev/sda: 160.0 GB, 160041885696 bytes
255 heads, 63 sectors/track, 19457 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000f0571

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1       18480   148440568+  fd  Linux raid autodetect
/dev/sda2           18481       19457     7847752+  fd  Linux raid autodetect

Disk /dev/sdb: 160.0 GB, 160041885696 bytes
255 heads, 63 sectors/track, 19457 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1       18480   148440568+  fd  Linux raid autodetect
/dev/sdb2           18481       19457     7847752+  fd  Linux raid autodetect

Disk /dev/md0: 152.0 GB, 152003018752 bytes
2 heads, 4 sectors/track, 37110112 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Disk identifier: 0x00000000

Disk /dev/md0 doesn't contain a valid partition table

Disk /dev/md1: 8036 MB, 8036024320 bytes
2 heads, 4 sectors/track, 1961920 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Disk identifier: 0x00000000

Disk /dev/md1 doesn't contain a valid partition table

Based on those last lines "Disk /dev/md0 doesn't contain a valid partition table," support concluded that the problem was with the partition table. Indeed, how didn't I think of that earlier! After all, fdisk has never shown partition tables for software RAID. I relayed all my thoughts to the client and began developing the cockroach's devious plan. I can only imagine how the support saga would have ended and how long it would have taken had the client agreed to their help. And the cost is easy to calculate.

I looked at the modification date of /bin/mount — it showed the time of the last server boot. I rebooted, checked the date again — time of the last server boot. Strange. So something was modifying this file during boot, and that "something" needed to be dealt with.

/tmp was read-only. To upload a file to the server, I needed a writable filesystem. I remembered /dev/shm. I brought up the network interface, assigned an IP, and downloaded the mount deb package for Lenny. Unpacked it, ran it — voila! It works! I remounted the filesystem, now it's RW. Things are moving!

I checked the files in /bin/ and saw the following picture:

$ ls -latr /bin
-rwxr-xr-x  1 root root  96408 Nov 15 18:11 vdir
-rwxr-xr-x  1 root root  30896 Nov 15 18:11 pwd
-rwxr-xr-x  1 root root  30712 Nov 15 18:11 ping6
-rwxr-xr-x  1 root root  24252 Nov 15 18:11 nc.traditional
-rwxr-xr-x  1 root root   8612 Nov 15 18:11 mountpoint
-rwxr-xr-x  1 root root  68208 Nov 15 18:11 mount
-rwxr-xr-x  1 root root  32244 Nov 15 18:11 mknod
-rwxr-xr-x  1 root root  39144 Nov 15 18:11 loadkeys
-rwxr-xr-x  1 root root  17244 Nov 15 18:11 kill
-rwxr-xr-x  1 root root   9764 Nov 15 18:11 fgconsole
-rwxr-xr-x  1 root root  26216 Nov 15 18:11 false
-rwxr-xr-x  1 root root   8524 Nov 15 18:11 dmesg
-rwxr-xr-x  1 root root  96408 Nov 15 18:11 dir
-rwxr-xr-x  1 root root  51988 Nov 15 18:11 dd
-rwxr-xr-x  1 root root  59148 Nov 15 18:11 date
-rwxr-xr-x  1 root root  49440 Nov 15 18:11 chgrp
-rwxr-xr-x  1 root root  30956 Nov 15 18:11 cat
-rwxr-xr-x  1 root root  12252 Nov 15 18:11 bzip2recover

The modification dates of these files changed every 3 minutes and 10 seconds. I started examining crontabs, found nothing. Catching which process was modifying files with lsof didn't work. I ran ps auxww and saw a certain process cat /sys/class/net/lo/operstate hanging around.

I downloaded a package with the kill utility, renamed /bin/cat to /bin/cat_ and killed the process. The files stopped being modified. Victory. Now all that remained was to replace all modified files with originals. I downloaded the necessary packages and installed them via dpkg -i *.deb, having first checked the creation date of dpkg itself. After all the replacements, with fingers crossed, I typed reboot and watched the KVM window. Boot was successful, the site was working. Then I scanned the infected files I had copied using ClamAV and discovered Linux.RST.B-1 FOUND. Who said there are no Linux viruses? By the way, it's a virus from 2001...

Scanning sshd and ssh yielded nothing definitive. Apparently they were simply modified ssh and sshd binaries. The first most likely sent the login and password upon successful server connection, the second most likely let anyone into the server with a specific password. I don't have the energy to dig into these files right now, but those interested can download them and investigate: zalil.ru/32063611

P.S. If anything in the commands is off, I apologize — many of them were written from memory. The desire to configure exim4 also faded. I haven't asked for payment yet. And for what? I didn't even complete the main task =)

P.P.S. Hello to Infobox!