Nebula level18
About
Analyse the C program, and look for vulnerabilities in the program. There is an easy way to solve this level, an intermediate way to solve it, and a more difficult/unreliable way to solve it.
To do this level, log in as the level18 account with the password level18 . Files for this level can be found in /home/flag18.
Source code
1#include <stdlib.h> 2#include <unistd.h> 3#include <string.h> 4#include <stdio.h> 5#include <sys/types.h> 6#include <fcntl.h> 7#include <getopt.h> 8 9struct { 10 FILE *debugfile; 11 int verbose; 12 int loggedin; 13} globals; 14 15#define dprintf(...) if(globals.debugfile) \ 16 fprintf(globals.debugfile, __VA_ARGS__) 17#define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \ 18 fprintf(globals.debugfile, __VA_ARGS__) 19 20#define PWFILE "/home/flag18/password" 21 22void login(char *pw) 23{ 24 FILE *fp; 25 26 fp = fopen(PWFILE, "r"); 27 if(fp) { 28 char file[64]; 29 30 if(fgets(file, sizeof(file) - 1, fp) == NULL) { 31 dprintf("Unable to read password file %s\n", PWFILE); 32 return; 33 } 34 fclose(fp); 35 if(strcmp(pw, file) != 0) return; 36 } 37 dprintf("logged in successfully (with%s password file)\n", 38 fp == NULL ? "out" : ""); 39 40 globals.loggedin = 1; 41 42} 43 44void notsupported(char *what) 45{ 46 char *buffer = NULL; 47 asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what); 48 dprintf(what); 49 free(buffer); 50} 51 52void setuser(char *user) 53{ 54 char msg[128]; 55 56 sprintf(msg, "unable to set user to '%s' -- not supported.\n", user); 57 printf("%s\n", msg); 58 59} 60 61int main(int argc, char **argv, char **envp) 62{ 63 char c; 64 65 while((c = getopt(argc, argv, "d:v")) != -1) { 66 switch(c) { 67 case 'd': 68 globals.debugfile = fopen(optarg, "w+"); 69 if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg); 70 setvbuf(globals.debugfile, NULL, _IONBF, 0); 71 break; 72 case 'v': 73 globals.verbose++; 74 break; 75 } 76 } 77 78 dprintf("Starting up. Verbose level = %d\n", globals.verbose); 79 80 setresgid(getegid(), getegid(), getegid()); 81 setresuid(geteuid(), geteuid(), geteuid()); 82 83 while(1) { 84 char line[256]; 85 char *p, *q; 86 87 q = fgets(line, sizeof(line)-1, stdin); 88 if(q == NULL) break; 89 p = strchr(line, '\n'); if(p) *p = 0; 90 p = strchr(line, '\r'); if(p) *p = 0; 91 92 dvprintf(2, "got [%s] as input\n", line); 93 94 if(strncmp(line, "login", 5) == 0) { 95 dvprintf(3, "attempting to login\n"); 96 login(line + 6); 97 } else if(strncmp(line, "logout", 6) == 0) { 98 globals.loggedin = 0; 99 } else if(strncmp(line, "shell", 5) == 0) { 100 dvprintf(3, "attempting to start shell\n"); 101 if(globals.loggedin) { 102 execve("/bin/sh", argv, envp); 103 err(1, "unable to execve"); 104 } 105 dprintf("Permission denied\n"); 106 } else if(strncmp(line, "logout", 4) == 0) { 107 globals.loggedin = 0; 108 } else if(strncmp(line, "closelog", 8) == 0) { 109 if(globals.debugfile) fclose(globals.debugfile); 110 globals.debugfile = NULL; 111 } else if(strncmp(line, "site exec", 9) == 0) { 112 notsupported(line + 10); 113 } else if(strncmp(line, "setuser", 7) == 0) { 114 setuser(line + 8); 115 } 116 } 117 118 return 0; 119}