SQLString="SELECT FirstName,LastName, Title FROM Employees WHERE City='"&strcity&"'AND Country ='USA'"
假如我们注入的语句是UNION ALL SELECT OtherField FROM OtherTable WHERE 1=1 那么会得到如下的提交语句:
|
这样就会报错:[Microsoft][ODBC SQL Server Driver][SQL Server]无效的列名 'Country'。
其实问题就是因为你注入的语句后,系统没有在从数据库的表中找到一个叫'Country'的列名。我们这里可以简单的用“;--”注释符号将其注释掉(假如我们是SQL Server)。或者干脆继续猜其他的列名,然后构造合法请求就如我们上一节讲到的一样。
表名的枚举
我们已经开始把握如何来使用注入进行攻击,但是我们还要确定要从哪个表得到信息,换句话说就是我们要的到要害的表名才能获得我们想要的有用信息。如何获得表名呢?在SQL Server中,你可以很轻易得从数据库中得到全部的表名和列名。但是在Oracle和Access中,你就不一定能如此轻易的得到了,这要看WEB程序对数据库的访问权限了。要害在于是否能得到系统建立时自动生成的表中包含的表名和列名。如在SQL Server中,它们分别为'sysobjects'和'syscolumns',(在本文最后我们将给出其他数据库系统自建表和相应的列名)我们用以下的句子可以在这些表中列出数据库的所有列名和表名,(根据情况自行修改):
SELECT name FROM sysobjects WHERE xtype = 'U'
这句话会返回数据库中用户定义的所有表,假如我们看到我们感爱好的或者是想要看的表,那么我们就把他打开,这里以Orders为例构造语句:SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'Orders')得到结果如图。
3.2.10.单一纪录
上面我们构造的语句返回了大量的信息,假如你只想显示一条数据纪录也是可以的。你完全可以构造你的注入语句来得到你想要的唯一的信息。我们只要在WHERE子句中添加要害字来避免某些行的要害字被选中就可以了。我来举个列子:' UNION ALL SELECT name, FieldTwo, FieldThree FROM TableOne WHERE ''='
我们这样就可以得到FieldOne,FieldTwo和FieldThree的第一个值,假设我们的到的分别是"Alpha", "Beta"和"Delta"。注重,更有意思的来了,我们要得到第2行的值,怎么构造下面的语句呢?这样来:' UNION ALL SELECT FieldOne, FieldTwo, FieldThree FROM TableOne WHERE FieldOne NOT IN ('Alpha') AND FieldTwo NOT IN ('Beta') AND FieldThree NOT IN ('Delta') AND ''='
这里有一个子句“NOT IN VALUES”,它的作用是不再返回我们已经得到的信息,即不是alpha,不是beta,不是delta.既然都不是,数据库就会傻乎乎的告诉我们第二行的值。我们再假设我们得到第二行的值为"AlphaAlpha", "BetaBeta"和"DeltaDelta"。
评论加载中…
![]() |