Re: RFP2K01 - "How I hacked Packetstorm" (wwwthreads advisory)

From: Barclay Osborn (barclayat_private)
Date: Fri Feb 04 2000 - 12:29:36 PST

  • Next message: Joachim Feise: "Re: Evil Cookies."

    On Thu, 3 Feb 2000, rain forest puppy wrote:
    > 	SELECT B_Main,B_Last_Post FROM general; DROP TABLE general;
    > 		SELECT * FROM general WHERE B_Number=$Number
     ... <snip> ...
    >
    > But in reality, it doesn't work.  Not because the theory is wrong, but
    > because the database user we're using doesn't have DROP privileges.  And
    
    Maybe I'm reading this wrong, but I've never been able to piggyback
    commands through mysql/DBI execute()'s, regardless of newlines, and even
    when I have privs:
    
    This works:
       my $dbh = DBI->connect("dbi:mysql:sec_test:localhost","foo","bar");
       my @row = $dbh->selectrow_array("select foo_col from bar_table");
       print STDERR "row = (@row)\n";
    
    But this doesn't:
       my @row = $dbh->selectrow_array("select foo_col from bar_table; select
    foo_col from bar_table");
    
    > the format of field='data', a numeric field doesn't use the '' (i.e.
    > numeric_field='2' is invalid).  The correct syntax for numeric fields in
    > numeric_field=2.  Ah ha!  There's no quotes to deal with, and you can't
    
    I can't verify this.  I can quote numbers, and they work fine (Msql
    modules 1.2.017, msyql 3.22.30, DBI 1.13).  And pushing them through quote
    yields the same results with strings (although I haven't looked at the
    DBI/Msql source yet...):
    
    (foo_col is an unsigned tinyint here)
    
    $ cat ./mysql-test.pl
    use DBI;
    my $dbh = DBI->connect("dbi:mysql:sec_test:localhost","foo","bar");
    my $number = int(2);
    my $str = $dbh->quote($number);
    print STDERR "string = ($str)\n";
    my $num = $dbh->do("insert into bar_table (foo_col) values ($str)");
    print STDERR "num inserted = ($num)\n";
    $dbh->disconnect;
    $ ./mysql-test.pl
    string = ('2')
    num inserted = (1)
    
    (same goes for selects, updates, etc)
    
    > Another area that needs to be verified is the table name.  In our very
    
    _definitely_
    
    > sub scrubtable {
    >         ($data=shift)=~tr/a-zA-Z0-9.//cd;
    >         return $data;}
    
    That's good, but you need to also make sure that your grant tables are set
    up correctly and you only accept from a predefined list of tables, as I've
    seen vulnerable statements like the following, that a simple scrub won't
    take care of:
    
    select t.*, p.foo, from $table t, another_table p where p.col = ?
    
    The problem here is a combination of the * and that $table is based on
    user-input, while an entire table may be viewed that shouldn't be.
    
    > EXCEPTIONS!  Passing user data straight into a SQL query is asking for
    > someone to tamper with your database.
    
    agreed.
    
    -B
    
    Barclay Osborn                   barclayat_private
    Lead Programmer / Site Security Officer
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:33:26 PDT