Nik has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,
Iam trying to create an if statement to distinguish Traversal Atatcks from Null Byte Injection.
Problem is that i cannot seem to telle perl about "%00| at the end of string. it cannot detect it even if i specify it. How can i show perl what is a null char?
if ( param('select') ) { unless (grep { $_ eq param('select') } @display_files) { if ( param('select') =~ /%/ ) { $passage = "*Null Byte Injection* attempted & logged!"; print br() x 2, h1( {class=>'big'}, $passage ); } else { $passage = "*Backwards Directory Traversal* attempted & lo +gged!"; print br() x 2, h1( {class=>'big'}, $passage ); } $select = $dbh->prepare( "UPDATE guestlog SET passage=?, date=?, +counter=counter+1 WHERE host=?" ); $select->execute( $passage, $date, $host ); exit; } open(FILE, "<../data/text/$passage.txt") or die $!;

2006-10-11 Retitled by ysth, as per Monastery guidelines
Original title: 'How to specify a Null chat in a match operation'

Replies are listed 'Best First'.
Re: How to specify a Null char in a match operation
by GrandFather (Saint) on Oct 11, 2006 at 08:19 UTC

    It's not so much that you aren't able to generate a string or detect the null, it is more likely that things go awry in subsequent processing. Consider:

    use strict; use warnings; my @strs = ("filename1.txt\0", "filename2\0.txt", "filename3.txt"); /\0/ && ((print "Null char detected in >$_<"), print "\n") for @strs;

    Prints:

    Null char detected in >filename1.txt Null char detected in >filename2

    Note that print has truncated the strings at the null character. A sign that C is at work under the hood.


    DWIM is Perl's answer to Gödel
      No, print doesn't truncate at \0 chars. I guess that's platform specific (you're on Windows?). Try
      use strict; use warnings; binmode STDOUT; my @strs = ("filename1.txt\0", "filename2\0.txt", "filename3.txt"); /\0/ && ((print "Null char detected in >$_<"), print "\n") for @strs;

      If you still see truncated strings, it might be the terminal's fault. On linux, piping the output to a pager, I see

      Null char detected in >filename1.txt^@< Null char detected in >filename2^@.txt<

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        With shmem's code, I get this output in a Windows command shell:

        Null char detected in >filename1.txt < Null char detected in >filename2 .txt<

        and replicate shmem's output when going through emacs.

        emc

        At that time [1909] the chief engineer was almost always the chief test pilot as well. That had the fortunate result of eliminating poor engineering early in aviation.

        —Igor Sikorsky, reported in AOPA Pilot magazine February 2003.

      What Perl and OS are you using? With ActivePerl 5.6.1, 5.8.0 and 5.8.8 all print the following in WinXP.

      Null char detected in >filename1.txt < Null char detected in >filename2 .txt<

      I even confirmed the "space" is a NUL.

        Turns out it is a problem with Komodo's output window. My appologies for any time wasted with chasing this!


        DWIM is Perl's answer to Gödel
      Thank you iam trying to understand it but i cant, especially the part tha the .txt will not be showed and why the '<' isnt showed also. Can you plz clarify some more?
        Like he said, it uses C under the hood. Now C doesn't store the length of a string anywhere. Instead, each time, it scans the string (which is just an array of characters, of unspecified length) looking for a special "end of string" character. And that character is chr(0). So when C is processing the string, it just stops when it sees a chr(0). And the way it does that, is hideously simple: the value of the character, which in C is pretty much a small integer, when taken as a boolean value(= true or false), is false — as an integer it's 0. All other characters are nonzero, thus true.

        This character is not special in Perl, because Perl does store the length of each string somewhere.

        And yes, IMnshO this is a serious shortcoming in C.

Re: How to specify a Null char in a match operation
by shmem (Chancellor) on Oct 11, 2006 at 09:37 UTC
    Your CGI-params get html_unescaped when retrieving the value, i.e. the string %00 is converted to a _real_ ASCII NUL ("\0" in perl). Match that.
    #!/usr/bin/perl -w use CGI; use strict; my $q = new CGI; print $q->header; print $q->start_html; my $p = $q->param('foo'); print $p =~ s/\0/&#0;/g ? "$p - null char detected\n" : "$p fine.\n"; print $q->end_html; __END__ call e.g. with http://localhost/cgi-bin/foo.pl?foo=foo%00bar

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: How to specify a Null char in a match operation
by Anonymous Monk on Oct 11, 2006 at 08:05 UTC
    Hi, you need to stop and read an introduction to CGI.
    my $null_byte = chr 0;