Honeypots and User-Mode-Linux (UML): Part 1

by jcannon on July 23, 2006 08:21pm

Honeypots and User-Mode-Linux (UML)
Part I: Setting up UML

(Special thanks to Dan Simonton for the testing and writing in support of this tech tip)

In technical terms, a honeypot performs a function very similar to that of a “honeypot” in the outside world: a sweet lure. A “honeypot” is a system designed with the purpose of attracting the attention of prospective attackers, to assess how they are attempting to infiltrate the machine and what they doing once they gain access. There are literally thousands of honeypot networks and systems setup by security professionals and hobbyists worldwide. These systems can provide a wealth of information into forensics and assessing trends in network intrusion.

This is Part One of a two part tech tip, which will address the setup of User Mode Linux (UML) for honeypot use. Part Two of the tech tip will cover the containment of intrusions and other security topics that arise while using UML as a honeypot. Also addressed in Part two will be the “forensics” i.e. identifying what exploits were tried on the honeypot.

One of the more popular methods for constructing honeypots in the Linux world is to set up a kernel to run in “user mode” on a host Linux machine. In function, this is very similar to running a “Virtual PC” on a Microsoft Windows or Apple Macintosh system. The primary difference is that “User Mode Linux”, or UML is open source and (depending on your personal depth of knowledge of the Linux kernel) you can really tweak any and every aspect of the host and UML kernel to your liking.

User Mode Linux is essentially an entire operating system running as a program in user space. It masquerades as an OS because for most purposes, it is one. The immediate benefit of running a honeypot this way is that with proper precautions taken, there is no significant threat to the host machine, or its operating system. When or if an attacker gains control of the UML instance, you can simply shut it down and restart at no cost to the hosting machine’s uptime or stability.     

The first step is to download a copy of the actual kernel source that you wish to compile on the designated host machine. This can be obtained from https://www.kernel.org/ or any associated mirror site. In this tech tip we will use the 2.6.16 kernel. The patches for the UML kernel can be obtained from:

https://www.user-mode-linux.org/~blaisorblade/patches/skas3-2.6/skas-2.6.16-v8.2/skas-2.6.16-v8.2.patch.bz2

You will also want to create a filesystem for the UML. In the interest of time and space, there are a number of filesystems that can be downloaded for various distributions from:

https://uml.nagafix.co.uk/

In this example we will be using Slackware-10.2

First of all, the standard commands are applied to unpack the source

$ tar –zvxf linux-2.6.16.tar.gz
$ bzip2 –d skas-2.6.16.-v8.2.patch
$ cp skas-2.6.16.-v8.2.patch linux/
$ cd linux-2.6.16/
$ patch –p1 < skas-2.6.16.-v8.2.patch

Note: In every step of the build process, it is crucial that the “ARCH=um” argument be passed along with the various kernel configuration and compilation commands.

Next we will clean out any .config files (if any are present) and generate a default configuration:

$ make mrproper && make mrproper ARCH=um
$ make defconfig ARCH=um

Now we manually check and edit the configuration:

            $ make menuconfig ARCH=um

At the very top of the list are UML-specific options. It is important to know what some of these are:

[ ] Tracing thread support
[*] Force a static link
[ ] Host processor type and features --->
[ ] Three-level pagetables (EXPERIMENTAL)
[ ] Memory model (Flat Memory) --->
[*] Networking support
[*] Kernel support for ELF binaries
<M> Kernel support for MISC binaries
< > Host filesystem
< > HoneyPot ProcFS (EXPERIMENTAL)
[*] Management console
[ ] Magic SysRq key
(0) Nesting level
[ ] Highmem support (EXPERIMENTAL)
(2) Kernel stack size order
[*] Real-time Clock

There are two options here in particular to take note of.

The first is the “Host Filesystem” option. This gives the UML Linux kernel access to the host filesystem. If you enable this, be careful how the access is applied. A safe course is to apply extended mount and read-write restrictions over filesystems on the host machine.

The second is the “HoneyPot Procfs” option. This essentially overwrites entries in the /proc filesystem of the UML kernel with that of the host. This is useful in that it removes fingerprints which might otherwise indicate the host is a honeypot. It could also be a potential troublespot for someone could map out the architecture of the hosting machine using this information. This is less of a threat than it is something to keep in mind.

NOTE: Be sure to include general kernel support for ext2, ext3 and reiserfs.

Looking further down from the kernel configuration tree, see the options for UML network devices. If you want to get to the outside world from the user mode kernel, be sure to enable ethertap and tun/tap support. This will allow the user mode kernel to communicate with the host tun/tap device.

Be sure to check any other “non-uml” options for your kernel that might be relevant to your machine. There is one last step before you can build the kernel. Due to a macro called by the patch that is now deprecated, one of the kernel source files must be manually edited. In whatever text editor you prefer, open up the file: (within the source tree) arch/um/os-Linux/sys-i386/registers.c and add the following to the preprocessor directive:  

#ifndef JB_PC
#define JB_PC 5
#define JB_SP 4
#define JB_BP 3
#endif

Once all this is done, build the kernel with:

            $ make ARCH=um

At this point, we have our hard drive image (with distribution) and a UMLLinux kernel. We have a few more things to set up on the host before we are ready to boot our UMLinstance. First, we need to make /dev/net/tun writable (by the user the UML kernel will be running as). The quick and dirty way to achieve this is to make it world writable (NOTE: not a “best practice”, just a quick way to get from a to b).

Alternatively you could create a separate group with write access to /dev/net/tun. Tun0 which is a tunneled interface to eth0, is used to negotiate traffic between the user mode kernel and the primary physical interface of the host machine. To configure the 1st interface (tun0)

                        tunctl –u umluser umldev

This command invokes tunctl, specifies the creation of a device, assigns ownership to user (via –u) to “umluser” and name its “umldev”. The IP side is configured the same way as a standard Ethernet interface via ifconfig:

            ifconfig umldev (ip address)

We’re ready to start our instance. We’ll want to specify the Ethernet device on start.

linux ubd0=Slackware-10.2-root_fs mem=256M eth0=tuntap,umldev

Once you are asked for a login, simply enter “root” and it should drop you right to a shell.

                       
dhcpcd: MAC address = fe:fd:00:00:00:00
Starting OpenSSH SSH daemon: /usr/sbin/sshd
Updating shared library links: /sbin/ldconfig

    Welcome to Linux 2.6.16-skas3-v8.2 (tty0)

yadda-yadda login: root
Linux 2.6.16-skas3-v8.2.
Last login: Thu Jul 20 00:53:38 +0000 2006 on tty0.
You have mail.
<root@yadda-yadda>:~#

On the UMLside, use ifconfig to give an ip address to eth0. This needs to be something routable by the umldev IP of the host machine. The route then must be set to the outside world (via the host umldev interface).

                        route add default gw (umldev ip)

On the host, packet forwarding and proxy_arp must be enabled:

Host# echo 1 >/proc/sys/net/ipv4/ip_forward
Host# echo 1>/proc/sys/net/ipv4/conf/umldev/proxy_arp

Now you should be able to reach the outside world from UML:

[uml@yadda-yadda]$ ping www
PING www.yadda-yadda..com (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=127 time=12.1 ms

root@yadda-yadda:~# ssh www.yadda-yadda.com
root@www.yadda-yadda.com’s password:
Last login: Thu Jul 20 11:00:50 2006 from yadda-yadda.com
[root@www ~]#

You should have a functional UML kernel running in its most basic form. You may kick it around, experiment with distributions (see links provided below), or otherwise abuse it as you see fit without consequence to your hosting system. This entry barely scratches the surface of one use of a usermode kernel, but if you have not considered running one before or are new to the idea, we hope this provides some useful information. Below are some links to some other resources, as well as the user-mode-linux project homepage.

https://user-mode-linux.sourceforge.net/ - UML Project homepage
https://www.honeynet.org/misc/project.html - The honeynet project
https://uml.nagafix.co.uk/ - A repository of disk images to use with your kernel