home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / CAP.c next >
Encoding:
C/C++ Source or Header  |  1999-06-07  |  6.3 KB  |  226 lines

  1. /* CAP - Console Access Protection                                  */
  2. /* This provides security from phsyical access to your conoles.     */
  3. /* When you run this program, it will clear the screen and prompt   */
  4. /* for a password. After so many failed attempts it will lock the   */
  5. /* tty and not allow them to try anymore. While this program is     */
  6. /* running, they can't abort this program, and they can not switch  */ 
  7. /* consoles either. The only only way around this is to reboot the  */
  8. /* computer, in which case it will be obvious that someone tried to */
  9. /* access your server's consoles. This will log the date and time   */
  10. /* the person tried to get access into your console.                */
  11. /*                                    */
  12. /* Compile: [g]cc -o CAP CAP.c -ltermcap                            */
  13. /* If you have shadow passwords compile with -DUSESHADOW.           */
  14. /* To compile in debug (or testing) mode, compile with -DDEBUG.     */
  15. /*                                    */
  16. /*           Shok (Matt Conover), shok@dataforce.net                */
  17.  
  18. #include <pwd.h>
  19. #include <term.h>
  20. #include <stdio.h>
  21. #include <fcntl.h>
  22. #include <errno.h>
  23. #include <unistd.h>
  24. #include <stdlib.h>
  25. #include <signal.h>
  26. #include <syslog.h>
  27. #include <shadow.h>
  28. #include <linux/vt.h>
  29. #include <sys/stat.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/types.h>
  32.  
  33. #define ERROR -1
  34. #define SAME   0
  35. #define LOCKOUT 3 /* How long in minutes to lock out of the console.     */
  36. #define MAXFAIL 3 /* Number of times they can enter an invalid password. */
  37.                   /* before being locked out for LOCKOUT minutes.        */
  38.  
  39. /* Used to disable switching consoles. */
  40. #define LOCKVT(x)     if ((ioctl(fd, VT_LOCKSWITCH, 1)) == ERROR) {    \
  41.                          perror("locking console (/dev/tty/)");        \
  42.                          exit(ERROR);                                  \
  43.                       }
  44.  
  45. /* Used to reenable ability to switch consoles. */
  46. #define UNLOCKVT(x)   if ((ioctl(fd, VT_UNLOCKSWITCH, 1)) == ERROR) {  \
  47.                          perror("locking console (/dev/tty/)");        \
  48.                          exit(ERROR);                                  \
  49.                       }
  50.  
  51.  
  52. int fd; /* Console fd. */
  53.  
  54. char *strip(char *str); /* Used to strip newlines from ctime().          */
  55. #ifdef DEBUG
  56. void sighandler(int signum);
  57. #endif DEBUG
  58.  
  59. void main()
  60. {
  61.   int uid;
  62.   int failed    = 0; /* Number of failed attempts out of MAXFAIL.      */
  63.   int totfailed = 0; /* Number of total failed attempts (not reseted). */
  64.   
  65.   time_t tm;
  66.  
  67.   char curtime[64];
  68.  
  69.   /* Don't change passwd or realpasswd's length. This is the maximum */
  70.   /* password length allow from getpass(). Any smaller can overflow. */
  71.   char *pass, passwd[128], realpasswd[128]; 
  72.  
  73.   struct passwd *pwd;
  74. #ifdef USESHADOW
  75.   struct spwd   *spwd;
  76. #endif
  77.  
  78.   if ((fd = open("/dev/tty", O_RDWR)) == ERROR) {
  79.     perror("opening console (/dev/tty)");
  80.     exit(ERROR);
  81.   }
  82.   
  83.   /* Disable signals (so attackers can't abort program). */
  84.  
  85. #ifndef DEBUG
  86.    signal(SIGHUP,  SIG_IGN);
  87.    signal(SIGINT,  SIG_IGN);
  88.    signal(SIGTERM, SIG_IGN);
  89.    signal(SIGQUIT, SIG_IGN);
  90.    signal(SIGTSTP, SIG_IGN);
  91. #else
  92.    signal(SIGINT, sighandler);
  93.    signal(SIGTERM, sighandler);
  94.    signal(SIGQUIT, sighandler);
  95.    signal(SIGTSTP, sighandler);
  96.    signal(SIGSEGV, sighandler);
  97. #endif
  98.  
  99.   LOCKVT(fd); /* Lock the VT. It can no longer switch. */
  100.  
  101.   uid = getuid();
  102.   pwd = getpwuid(uid);
  103. #ifdef USESHADOW
  104.   if ((spwd = getspnam(pwd->pw_name)) == NULL) {
  105.      perror("getspnam");
  106.      exit(ERROR);
  107.   }
  108.  
  109.   strncpy(realpasswd, spwd->sp_pwdp, sizeof(realpasswd));  
  110. #else
  111.   strncpy(realpasswd, pwd->pw_passwd, sizeof(realpasswd)); 
  112. #endif  
  113.  
  114.   clr();
  115.   printf("w00w00!\n");
  116.   printf("Console is now locked.\n");
  117.   getchar();
  118.  
  119.   /* Used to log invalid password attempts. */
  120.   openlog("CAP/conprot", LOG_CONS, LOG_AUTHPRIV); 
  121.  
  122.   while (1) {
  123.      /* Get the password from the user. */
  124.  
  125.      /* For some reason I get warnings without the typecast (broken
  126.         prototype?). */
  127.      pass = getpass("Enter password: ");
  128.  
  129.      
  130.      /* Encrypt the password from getpass(). 
  131.      /* Note, we are using realpasswd for our salt. This is to allow a */
  132.      /* salt of any size. This also saving us the trouble of getting   */
  133.      /* the salt ourselves.                           */
  134.      strncpy(passwd, crypt(pass, realpasswd), sizeof(passwd));
  135.  
  136.      passwd[128] = '\0'; /* NULL terminate passwd just to be safe.     */
  137.  
  138. #ifdef DEBUG
  139.      printf("Encrypted password from user: %s\n", passwd);
  140.      printf("The real encrypted password: %s\n", realpasswd);
  141. #endif
  142.  
  143.      if ((strcmp(passwd, realpasswd)) == SAME) {
  144.         /* Unlock the console, to allow it to switch. */
  145.         UNLOCKVT(fd);
  146.  
  147.         closelog(); /* Close logging. */
  148.  
  149.     clr();
  150.  
  151.         printf("Everything is now restored.\n");
  152.  
  153.         if (totfailed == 0) printf("No one tried to access the console.\n");
  154.         else printf("Total number of failed attempts to unlock console: %d\n",
  155.                 totfailed);
  156.  
  157.         exit(0);
  158.      } else {
  159.     failed++, totfailed++; /* Increase number of failed attempts. */
  160.  
  161.         /* Log bad attempts to syslog. */
  162.         tm = time(NULL);
  163.  
  164.         snprintf(curtime, sizeof(curtime), (char *)ctime(&tm));
  165.         strip(curtime); /* Strip new lines out of the time. */
  166.         syslog(LOG_WARNING, "Failed access attempt on: %s", curtime);
  167.  
  168.         printf("Invalid password.\n");
  169.  
  170.     if (failed >= MAXFAIL) {
  171.        printf("Maximum number of failed attempts.\n"
  172.                   "Now locking for %d minutes.\n", LOCKOUT);
  173.  
  174.        sleep(LOCKOUT * 60); /* Convert the minutes to seconds. */
  175.        failed = 0; /* Reset the number of failed attempts.     */
  176.         }
  177.      }
  178.   }
  179. }
  180.  
  181. char *strip(char *str)
  182. {
  183.   register int i;
  184.  
  185.   for (i = 0; str[i]; i++) 
  186.       /* Strip newline out of string. */
  187.       /* We do this because syslog appends the newline itself. */
  188.       if (str[i] == '\n') str[i] = '\0'; 
  189.  
  190.   return str;
  191. }
  192.  
  193. #ifdef DEBUG
  194. void sighandler(int signum)
  195. {
  196.   if (signum == 11) printf("Received SIGSEGV.\n");
  197.   printf("\nAborting and unlocking console.\n");
  198.  
  199.   UNLOCKVT(fd);
  200.  
  201.   if (signum == 11) kill(getpid(), 11);
  202.   exit(0);
  203. }
  204. #endif
  205.  
  206. clr()
  207. {
  208.   char *clear;
  209.   char clbuf[1024], *clbp = clbuf;
  210.  
  211.   if (tgetent(clbuf, getenv("TERM")) == ERROR) {
  212.      perror("tgetent");
  213.      system("clear");
  214.      return;
  215.   }
  216.  
  217.   if ((clear = tgetstr("cl", &clbp)) == NULL) {
  218.      perror("tgetent");
  219.      system("clear");
  220.      return;
  221.   }
  222.  
  223.   if (clear)
  224.      tputs(clear, tgetnum("li"), putchar);
  225. }
  226.