Recovering a Root Password on a Sun box is kind of simple and well documented, using a
Solaris installation CD or a network installation server. Now, suppose you do not have a CD handy... in a cold dark lab... late at night, deadline
big time overdue (this of course is pure fiction)... hungry and tired (not this)... junk food machine empty... why not use kadb and get out of here... This requires some knowledge of
Solaris Internals (
vnode architecture a plus), and of course
kadb kernel debugger... The idea here is that as init spawns login, we should be able to substitute its execution with a shell... We know that
exece is the kernel entry point for executing a binary, now, because input parameters are still in user land memory space at the time exece is called... that is not the exact place to look for... but sooner or later anyway, kernel will have to map the target binary name to an inode... Path name traversal is done by the
lookuppn routine (lookup path name), called by
lookupname (thanks
dtrace for that information), that should do it... Of course no security hole has been exploited here, people that care about security would setup the box the way... well people that care about security setup machines... I do not know, but I bet at least no kadb module in /platform and
Stop-A desactivated (and tape on CD drive)...
Ok, so we first "boot kadb", and wait for the login prompt, then enter kadb (control-A "send break" from telnet session or STOP-A on keyboard), setup a first breakpoint in exece, and continue (use dummy login)..:
console login:
telnet> send brk
stopped at:
edd000d8: ta %icc,%g0 + 125
kadb[0]: exece:b
kadb[0]: :c
console login:
console login:
console login: foo
breakpoint at:
exece: save %sp, -0xb0, %sp
Now from what we said earlier, we are supposed to put the next breakpoint at lookupname, but in
order to see (and modify) the binary path name, we need to wait for the next "save" instruction, witch
does not occur in lookupname, nor in lookuppn (called by lookupname), but in lookuppnat (called by lookuppn).
So now we know (you might wanna step through all whose calls to double check), lets directly break in lookuppnat (and step "]" to the next "save" instruction (even better we could break at lookuppnat+4, but well...)).
kadb[0]: lookuppnat:b
kadb[0]: :c
breakpoint at:
lookuppnat: save %sp, -0xc0, %sp
kadb[0]: ]
Here we are, the path name is in the structure "pathname" passed as first parameter (see /usr/include/sys/pathname.h). Lets check that we intercept the right binary execution request (register i0):
stopped at:
lookuppnat+4: ldx [%i0 + 0x10], %g2
kadb[0]:
kadb[0]: *‹i0/S
3000b057a90: /usr/bin/login
This is it, we are now going to replace "/usr/bin/login" (2f7573722f62696e) with "/sbin/sh" (2f7362696e2f7368), put \0 at the end of the string and update the length of the string (fourth parameter (offset 10 of struct "pathname") set to 8).
kadb[0]: *‹i0/K
3000b057a90: 2f7573722f62696e
kadb[0]: ./Z 2f7362696e2f7368
3000b057a90: 2f7573722f62696e= 2f7362696e2f7368
kadb[0]: .+8/Z 0
3000b057a98: 2f6c6f67696e0064= 0
kadb[0]: ‹i0+10/Z 8
2a1004bda20: e = 8
Check everything's ok now and resume the execution now (will delete breakpoint when encountered)...
kadb[0]: *‹i0/S
3000b057a90: /sbin/sh
kadb[0]: :c
breakpoint at:
lookuppnat: save %sp, -0xc0, %sp
kadb[0]: :d
kadb[0]: :c
#
Here we go ! we have a prompt, lets try to do some stuffs...
(Oups, forgot to remove the exece breakpoint...)
#
# ls
breakpoint at:
exece: save %sp, -0xb0, %sp
kadb[0]: :d
kadb[0]: :c
bin export lost+found pos shared ws
db global mc_metadb proc src xfn
design home mnt proj tmp
dev import net sac tools
devices java nse sbin usr
doe kernel opt scde var
etc lib platform share vol
# id
uid=0(root) gid=1(other)
Done, you just have now to repair your box (edit /etc/passwd and /etc/shadow).