Follow us on twitter

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}

Discussion