Kernel modules
Kernel modules are dynamic extensions to the kernel that can be added without requiring a kernel rebuild or even a reboot. Kernel modules allow for the following:
- The dynamic extension of kernel capabilities after the detection of new hardware-When a Personal Computer Memory Card International Association (PCMCIA) card is inserted into a UNIX laptop, the operating system can load the appropriate kernel modules. Adding a Universal Serial Bus (USB) device invokes a similar response.
- The rapid testing and modification of kernel capabilities under development-The system call developer does not have to go through timeconsuming rebuilds and reboots just to test a new version.
- The size of the kernel loaded at boot time can be kept smaller-Many capabilities are designated as loadable modules, so the boot time size of the kernel is kept small and manageable.
A UNIX administrator must know how to check for root kits that have been loaded as a kernel module. The lsmod command will list kernel modules that have been loaded. The following is a subset of typical modules loaded in a Linux 2.4 kernel:
Module Size Used by Tainted: PF i810_audio 27720 1 (autoclean) ac97_codec 13640 0 (autoclean) [i810_audio] soundcore 6404 2 (autoclean) [i810_audio] agpgart 47776 3 (autoclean) nvidia 2126120 6 (autoclean) parport_pc 19076 1 (autoclean) lp 8996 0 (autoclean) parport 37056 1 (autoclean) [parport_pc lp] ipt_state 1048 3 (autoclean) iptable_nat 21720 0 (autoclean) (unused) ip_conntrack 26976 2 (autoclean) [ipt_state iptable_nat] iptable_filter 2412 1 (autoclean) ip_tables 15096 5 [ipt_state iptable_nat iptable_filter] sg 36524 0 (autoclean) sr_mod 18136 0 (autoclean) ide-scsi 12208 0 scsi_mod 107160 3 [sg sr_mod ide-scsi] ide-cd 35708 0 cdrom 33728 0 [sr_mod ide-cd] keybdev 2944 0 (unused) mousedev 5492 1 hid 22148 0 (unused) input 5856 0 [keybdev mousedev hid] usb-uhci 26348 0 (unused) usbcore 78784 1 [hid usb-uhci] ext3 70784 7 jbd 51892 7 [ext3]
System calls
A system call is a request to the operating system kernel for access to critical resources. System calls are accomplished using special instructions that allow a switch to the supervisor mode. These calls are the services provided by the kernel to application programs. In other words, a system call is a routine that performs a system-level function on behalf of a process. All system operations are allocated, initiated, monitored, manipulated, and terminated through system calls.
System calls can assist an administrator in evaluating an application's security. By examining calls that an application makes to the kernel, an administrator can determine if a security risk is involved. By viewing the system calls made by a process, it can be determined if the hard drive is being accessed when it should not be. Also, the system calls will reveal network access in a process that has no business on the network.
On a Linux system, the strace command is a system call tracer tool that prints out a trace of all the system calls made by a process or application. The ltrace command will similarly print out all library calls made. On FreeBSD you can use ktrace, and on Solaris truss.
The following example is a session that shows the use of strace on a simple Hello World program. First the program source is listed:
# cat helloworld.c /* * helloworld - simple hello world program */ #include <stdio.h> int main(int argc, char **argv) { printf("Hello World\n"); }
Now the program is executed normally:
# ./a.out Hello World
Finally, the program is executed with strace:
# strace ./a.out execve("./a.out", ["./a.out"], [/* 35 vars */]) = 0 uname({sys="Linux", node="localhost.localdomain", ...}) = 0 brk(0) = 0x8049510 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40016000 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=81158, ...}) = 0 old_mmap(NULL, 81158, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000 close(3) = 0 open("/lib/tls/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`V\1B4\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1531064, ...}) = 0 old_mmap(0x42000000, 1257224, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x42000000 old_mmap(0x4212e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12e000) = 0x4212e000 old_mmap(0x42131000, 7944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x42131000 close(3) = 0 set_thread_area({entry_number:-1 -> 6, base_addr:0x400169e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 munmap(0x40017000, 81158) = 0 fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 3), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000 write(1, "Hello World\n", 12Hello World) = 12 munmap(0x40017000, 4096) = 0 exit_group(12) = ?
When strace is run on a program that accesses the network, you see certain calls that belie that access:
# strace ping -c 1 192.168.131.131 execve("/bin/ping", ["ping", "-c", "1", "192.168.131.131"], [/* 35 vars */]) = 0 <lines deleted> socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3 getuid32() = 0 setuid32(0) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("192.168.131.131")}, 16) = 0 getsockname(4, {sa_family=AF_INET, sin_port=htons(32796), sin_addr=inet_addr("192.168.123.10")}, [16]) = 0 close(4) = 0 setsockopt(3, SOL_RAW, ICMP_FILTER, ~(ICMP_ECHOREPLY|ICMP_DEST_UNREACH|ICMP_SOURCE_QUENCH|ICMP_REDIRECT|ICMP_T IME_EXCEEDED|ICMP_PARAMETERPROB), 4) = 0 setsockopt(3, SOL_IP, IP_RECVERR, [1], 4) = 0 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [324], 4) = 0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0 getsockopt(3, SOL_SOCKET, SO_RCVBUF, [131072], [4]) = 0 brk(0) = 0x8062c80 brk(0x8063c80) = 0x8063c80 brk(0) = 0x8063c80 brk(0x8064000) = 0x8064000 fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 6), ...}) = 0 <lines deleted> exit_group(0) = ?
In this tutorial:
- UNIX and Linux Security
- Network and development tools
- UNIX/Linux as a poor target
- Open source issues
- Detecting hardware changes
- Disk partitioning
- Prepare for the eventual attack
- Controlling the Configuration
- Kernel configurations
- Kernel modules
- proc file system
- Operating UNIX Safely
- Uncommon services
- Processes controlling processes
- The chkconfig command
- Controlling users
- Chroot
- Encryption and certificates
- Hardening UNIX
- Packet filtering with iptables