2006-01-16
Introduction
It has become increasingly important for security professionals to deploy new detection mechanisms to track and capture an attacker's activities. Third Generation (GenIII) Honeynets provide all the components and tools required to gather this information at the deepest level. Sebek is the primary data capture tool for GenIII Honeynets.The first of this two-part series will discuss what Sebek is and what makes it so interesting. We'll start by looking at the latest Sebek release, version 3, its new capabilities, the Sebek protocol specification and how it integrates with GenIII Honeynet infrastructures. The second article will briefly address how to install and use Sebek on Linux and Windows. It will then focus on a Sebek patch developed by this article's author that makes possible not only to watch what the attacker types but also the response received.
Sebek, a kernel based data capture tool
In May 2005, honeynet technologies notably improved their functionality with the newly released third generation. This last generation is based on a new Honeywall version called Roo [ref 1] and on the new Sebek release, version 3.Sebek [ref 2] is the most advanced and complex honeynet data capture tool. It is an open-source tool whose purpose is to capture from a honeypot as much information as possible of the attackers activities by intercepting specific system calls (syscalls) at the kernel level.
Sebek is based on a client-server architecture. The client is installed on the honeypots and the server is typically deployed on the Honeywall, that is, the honeynet gateway all the traffic entering and leaving the honeynet passes through. The Sebek client component uses techniques similar to those used by kernel-based rootkits. [ref 3] Sebek is implemented in the form of a Linux Kernel Module (LKM) on Linux, as an OS kernel driver on Windows, and as a kernel patch on the various *BSD operating systems. The server module contains user-level tools that allow to gather and display the information captured and exported by the Sebek clients.
The first Sebek version 3 client (v3.0.3) was released for Linux 2.4 kernels in May 2005. This version also included the Linux Sebek server (v3.0.3). Then in October 2005, new client versions were released for other operating systems, such as Windows (v3.0.3), Linux 2.6 kernels (v.3.1.2b) and *BSD (v3.0).
The purpose of this paper is to discuss the new Sebek version, version 3, which will be referred as Sebek from now on. Sebek version 2, its purpose, architecture, features, tools and protocol specification are extensively covered on the original Sebek KYE paper. [ref 4]
Sebek's new capabilities
Sniffing network traffic has long been the traditional way of inspecting the actions performed by an attacker remotely accessing a compromised resource. However, this is not possible if the attacker is protecting his communication channel through encryption and the key used is unknown.The first Sebek version intercepted all "read" kernel syscalls with a length of one byte, which is what allows one to get the keystrokes typed by the honeypot intruder before they are encrypted, including the commands executed or the passwords used. This initial Sebek data capture functionality was later improved in version 2 to capture all "read" data. This second version also allows to recover entire files copied with SCP or complete IRC and mail messages.
Sebek version 3 extends this functionality by intercepting a new set of system calls. Additionally, it retrieves the parent process id (PPID) and the inode associated with any file-related event. These two fields will be added for each Sebek record. Apart from intercepting the standard "read" syscall, the new version hijacks additional "read" syscalls, the "socket" syscall, the "open" syscall, and the "fork" and "clone" syscalls. The following descriptions use the Linux version as a reference. The same ideas also apply to the Windows version.
The previous Sebek version simply intercepted the standard "NR_read" syscall. The current Sebek version also intercepts the "NR_readv" and "NR_pread" syscalls, which allows one to capture all "read" activities in the system and counteract evasion performed by tools like "sebekill". [ref 5] This tool is a library that maps every "read" syscall to the "readv" syscall, thus avoiding previous Sebek versions' "read" data capture.
The "socket" syscall (NR_socketcall) maps network activities to process activities. Therefore, Sebek is able to collect information about any communication and to establish its relationship with the specific process running on the honeypot. This information will also help to correlate Sebek data with network traffic data captured by the Honeywall using a sniffer. Additionally, if a network connection is associated with an intrusion attempt, it is possible to directly identify the compromised process.
The "open" syscall (NR_open) maps any read action to a filename and its inode in the honeypot filesystems. This allows one to identify all files accessed during an intrusion. The recording of inodes is needed to avoid the "dup2" based obfuscation techniques implemented in sepabek. [ref 6] In this technique, a modified version of the "read" library function is invoked. The modified function duplicates the "read" file descriptor and reads random data from the same descriptor but from a different inode. Using inode tracking capabilities, Sebek is able to screen the invalid data read.
The "fork" ("NR_fork" and "NR_vfork") and "clone" ("NR_clone") syscalls track the process (PID) and parent process identifiers (PPID). Monitoring the process creation makes it possible to identify the system processes relationships and rebuild the whole execution processes tree.
In response to the NoSEBrEaK tool techniques [ref 7], the new Sebek version tries to avoid the extraction of its internal state by initializing its block structures with random values. Additionally, in order not to be removed from the system, Sebek disables the cleanup function when it is not running in testing mode.
The Windows version of Sebek implements similar techniques to the Linux client. The new version hides itself from the list of running modules, filesystem and registry queries. It avoids some of the detection methods used by KprocCheck [ref 8], such as the technique based on the traversal of the PsLoadedModuleList and implemented by the "-d" option.
The Windows module also logs all socket connections, including multiple network-based syscalls such as open, accept and bind. This version records the PPID and PID of each process, required to generate Sebek version 3 protocol packets. Finally, the previous Sebek Windows version only captured command line activities from the "cmd.exe" command prompt. The current version logs all console application input and output, even those that specify a socket for stdin, stdout or stderr. One of the main benefits of the Windows version versus the Linux one is that it does survive system reboots.
Sebek challenges
Although the latest Sebek version has notably improved its functionality and counterhacking capabilities, there are still challenges in both fields. From a functionality perspective, it would be very interesting to be able to capture the response received by the attacker. Therefore, this improvement will be covered in the second part of this article. From a protection perspective, Sebek should defend itself against common techniques that detect and defeat kernel-based rootkits. Ongoing Sebek development should address issues such as:
- The presence of the Sebek module on Linux can be detected. The hiding method currently used by Sebek simply unlinks the module from the linked list of kernel modules. [ref 3] Figure 1, below, illustrates the "module_hunter" tool detecting the Sebek module running with the "sebek" name. [ref 9]
# insmod ./module_hunter.o # cat /proc/showmodules address module 0xc880d000 scsi_mod size: 0x1a278 0xc8827000 * size: 0x12 0xc8829000 sd_mod size: 0x348c 0xc882e000 BusLogic size: 0x189bc 0xc8848000 jbd size: 0xcab4 0xc8856000 ext3 size: 0x11480 0xc888a000 cdrom size: 0x83c0 0xc8894000 ide-cd size: 0x8b7c 0xc889e000 ide-scsi size: 0x2fb0 0xc88a2000 sr_mod size: 0x46d8 0xc88a6000 net size: 0x219 0xc88a8000 sg size: 0x8eac 0xc88b2000 ip_tables size: 0x3af8 0xc88b7000 iptable_filter size: 0x96c 0xc88bb000 mii size: 0xf88 0xc88bd000 module_hunter size: 0x5ec 0xc88bf000 ipt_REJECT size: 0xf58 0xc88c1000 pcnet32 size: 0x4740 0xc88c7000 autofs size: 0x33d4 0xc88cc000 sebek size: 0x5e50 #
Figure 1. Sebek Linux 3.0.3 detection - module_hunter. - Sebek can also be identified on Windows looking at the hooked native APIs Sebek on the SDT (Service Descriptor Table). [ref 8] This technique is implemented by the "KprocCheck -t" option. Figure 2 illustrates the hooked SDT entries identified and owned by an unknown module, in this case, Sebek.
C:\>KProcCheck.exe -t KProcCheck Version 0.2-beta2 Proof-of-Concept by SIG^2 (www.security.org.sg) Checks SDT for Hooked Native APIs KeServiceDescriptorTable 80559B80 KeServiceDescriptorTable.ServiceTable 804E2D20 KeServiceDescriptorTable.ServiceLimit 284 Entry 19 - [hooked by unknown at FA881498] Entry 25 - [hooked by unknown at FA881E16] Entry 29 - [hooked by unknown at FA882266] Entry 35 - [hooked by unknown at FA880F8E] Entry 47 - [hooked by unknown at FA882360] Entry 49 - [hooked by unknown at FA881EDE] Entry 74 - [hooked by unknown at FA881D6C] Entry 77 - [hooked by unknown at FA8822E2] Entry 91 - [hooked by unknown at FA881924] Entry AD - [hooked by unknown at FA881A4A] Entry B7 - [hooked by unknown at FA8810EE] Entry C8 - [hooked by unknown at FA881310] Entry D2 - [hooked by unknown at FA8813EA] Entry 112 - [hooked by unknown at FA881146] Number of Service Table entries hooked = 14 C:\>
Figure 2. Sebek Windows 3.0.3 detection - KProcCheck. - Other methods use the knowledge of the default Windows driver name, sebek.sys, to detect Sebek's presence. [ref 8] This can be avoided changing the default name. The Sebek Windows installer can be run with the "/N=NAME" command line argument, where NAME is the name of the driver you want to use without the ".sys" extension appended.
- The Sebek Linux syscall table modifications can be discovered. Additionally, the Sebek syscall pointers could be overwritten, disabling Sebek. [ref 7] [ref 3]
- The Sebek Windows version can also be disabled following a similar procedure based on restoring the ServiceTable entries on the SDT. [ref 10] This method is implemented by the SDTrestore tool and is illustrated below in Figure 3.
C:\>SDTrestore.exe SDTrestore Version 0.2 Proof-of-Concept by SIG^2 G-TEC (www.security.org.sg) KeServiceDescriptorTable 80559B80 KeServiceDecriptorTable.ServiceTable 804E2D20 KeServiceDescriptorTable.ServiceLimit 284 ZwClose 19 --[hooked by unknown at FA881498]-- ZwCreateFile 25 --[hooked by unknown at FA881E16]-- ZwCreateKey 29 --[hooked by unknown at FA882266]-- ZwCreateThread 35 --[hooked by unknown at FA880F8E]-- ZwEnumerateKey 47 --[hooked by unknown at FA882360]-- ZwEnumerateValueKey 49 --[hooked by unknown at FA881EDE]-- ZwOpenFile 74 --[hooked by unknown at FA881D6C]-- ZwOpenKey 77 --[hooked by unknown at FA8822E2]-- ZwQueryDirectoryFile 91 --[hooked by unknown at FA881924]-- ZwQuerySystemInformation AD --[hooked by unknown at FA881A4A]-- ZwReadFile B7 --[hooked by unknown at FA8810EE]-- ZwRequestWaitReplyPort C8 --[hooked by unknown at FA881310]-- ZwSecureConnectPort D2 --[hooked by unknown at FA8813EA]-- ZwWriteFile 112 --[hooked by unknown at FA881146]-- Number of Service Table entries hooked = 14 WARNING: THIS IS EXPERIMENTAL CODE. FIXING THE SDT MAY HAVE GRAVE CONSEQUENCES, SUCH AS SYSTEM CRASH, DATA LOSS OR SYSTEM CORRUPTION. PROCEED AT YOUR OWN RISK. YOU HAVE BEEN WARNED. Fix SDT Entries (Y/N)? : Y [+] Patched SDT entry 19 to 805675D9 [+] Patched SDT entry 25 to 8057164C [+] Patched SDT entry 29 to 8056F063 [+] Patched SDT entry 35 to 8057F262 [+] Patched SDT entry 47 to 8056F76A [+] Patched SDT entry 49 to 805801FE [+] Patched SDT entry 74 to 805715E7 [+] Patched SDT entry 77 to 805684D5 [+] Patched SDT entry 91 to 80574DAD [+] Patched SDT entry AD to 8057CC27 [+] Patched SDT entry B7 to 80571B30 [+] Patched SDT entry C8 to 8057860F [+] Patched SDT entry D2 to 80585D7D [+] Patched SDT entry 112 to 8057A125 C:\>
Figure 3. Disabling Sebek Windows 3.0.3- SDTrestore. - The data that is accessed through the "mmap" syscall cannot be recorded by Sebek.[ref 7]
- The Sebek Linux version does not survive system reboots. [ref 3]
Some of the above issues, such as survival after reboot or Sebek syscall disabling, could be solved by implementing Sebek as a kernel patch. However, the selection of an LKM versus a kernel patch is really more of a usability question. A LKM (or driver) is much easier to install, more flexible and best suited for incident response where you have to enable monitoring after an intrusion. For honeypots, it would be very interesting to have a reliable kernel patch implementation.
Sebek is an open-source tool, so it is strongly recommended that one modify it to meet his needs. A customized Sebek version will decrease the likelihood of detection because it is different from the publicly available one.
Sebek's protocol specification
Apart from the Sebek data capture capabilities offered, Sebek also implements advanced logging mechanisms. The data captured by the kernel is sent to the Sebek server using a UDP covert channel. Sebek uses its own kernel-based implementation of the Raw Socket interface.
