Bugtraq mailing list archives

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


From: barclay () PAPERBOY WEBSOCIETYINC COM (Barclay Osborn)
Date: Fri, 4 Feb 2000 12:29:36 -0800


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                   barclay () websocietyinc com
Lead Programmer / Site Security Officer


Current thread: