代码审计基础之SQL注入漏洞

news2025/7/12 11:21:16

1.SQL注入原理

SQL注入就是攻击者通过把恶意的SQL语句插入到Web表单的输入页面中,且插入的恶意语句会导致原有的SQL语句发生改变,从而达到攻击者的目的去让它执行一些危险的数据操作,进一步欺骗服务器去执行一些非本意的操作。

简单来讲,所有可以涉及到数据库增删改查的系统功能点都有可能存在SQL注入漏洞

一个简单的攻击原理举例:
image.png

在SQL注入中,我们更应该关注的是业务逻辑,例如业务中可能设计到的增删改查操作,下面通过一个简单的代码小demo来进行SQL注入的演示:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>SQL注入小demo</title>
</head>
<body>
用户名:
<form method="GET">     //form表单通过get方式接收数据
   <input type="text" name="name" size="50" />   //通过name参数接收数据
   <br>
   <input type="submit" value="点击查询" style="margin-top:50px;">
   <?php
  $db = mysqli_connect("localhost","root","123456","demo"); //建立mysql连接
  if(!$db){
          echo "数据库链接失败!";
          exit();
  }

  $name = $_GET['name']; //通过前端设置的name参数将数据接收到后端进行处理
  $sql = "select * from user where name = '".$name."';";
  echo " 输出当前执行的SQL主句:".$sql."";
       $result = mysqli_query($db,$sql);  //执行SQL语句

   while($row=mysqli_fetch_array($result))   //取出一行数据的所有内容以数组的形式返回
  {
       echo "账号:".$row['user']."";      //输出一行数据的user字段值
       echo "密码:".$row['passwd']."";//输出一行数据的passwd字段值
  }
   mysqli_close($db);//关闭mysql连接
   ?>
</form>
</body>
</html>

【一一帮助安全学习,所有资源获取一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部教程

1.1 PHP MySQLi基本函数

PHP MySQLi 函数允许访问 MySQL 数据库服务器。通俗来说MySQLi 下的函数用来处理PHP中关于数据增删改查的操作。

mysqli_connect()

image.png

mysqli_query()

image.png

mysqli_fetch_array()

image.png

mysqli_close()

image.png

为了方便演示实际的业务流程,我们创建demo数据库,并且创建user表,在表中插入演示数据。
image.png

这里简单演示了一下通过查询来获取数据的操作原理。
image.png

1.2 问题引申:

我们知道某些业务功能会涉及到数据库交互,如上所示,我们是不是可以通过正常功能插入恶意SQL语句来实现我们想要达到的目的呢?

例如这样:

1' union select 1,2,user(),database();#

2.SQL注入分类

SQL注入大致分为以下五大类,下面我们通过实际的PHP代码进行分析。
image.png

2.1 报错注入

2.2.1 示例代码

通过传入id参数且传入的id参数未做过滤直接拼接到SQL语句中执行,直接使用mysqli_error()进行报错处理没有对报错进行良好的错误处理,所以导致报错注入的产生。

<?php
if(isset($_GET['id']))    //判断是否存在id参数传入
{
   header("Content-type:text/html;charset=utf-8");
   $db = mysqli_connect("localhost:3307","root","123456","demo"); //连接一个数据库
   if(!$db){
       echo "数据库链接失败!";
       exit();
  }
   $id=$_GET['id']; //获取id参数值
   $sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";  //将id参数值直接拼接到SQL语句
   $result=mysqli_query($db,$sql); //执行SQL语句
   $row = @mysqli_fetch_array($result);   //取出第一行查询到的值以数组形式返回

if($row)
{
   echo 'Your Login name:'. $row['user'];  //查询到id为xxx的user字段值并输出
   echo "<br>";
   echo 'Your Password:' .$row['passwd'];  //查询到id为xxx的passwd字段值并输出
}
else
{
   echo mysqli_error($db); //如果语句出现错误直接输出错误
}
   mysqli_close($db); //关闭mysql连接
}
?>

2.1.2 PHP函数介绍

mysqli_erro
image.png

2.1.3 测试

当正常查询id=1时输出user以及passwd字段的值php123456
image.png

当输入id=1',mysqli_error()捕获错误信息,并将SQL语句报错。
image.png

我们闭合SQL语句中的单引号即可执行我们想要的查询的内容

测试语句:

1' and (select extractvalue("anything",concat('~',( user()))))%20--%20dsddsa

image.png

2.2 宽字节注入

2.2.1 代码示例

mysql中有一个特性,由于gbk是多字节编码,两个字节代表一个汉字,所以%df和后面的转义字符\也就是%5c会组成了一个汉字,而'就逃逸了出来造成SQL注入。

在审计SQL注入时,要着重注意MySQL中设置的字符编码,如果为gbk,那么很可能存在宽字节注入。

<?php
if(isset($_GET['id']))
{
   header("Content-type:text/html;charset=utf-8");
   $db = mysqli_connect("localhost:3307","root","123456","demo");
   mysqli_query($db,"SET NAMES 'gbk'");    //设置MySQL字符编码为gbk
   if(!$db){
       echo "数据库链接失败!";
       exit();
  }
   $id=addslashes($_GET['id']);    //通过addslashes()对特殊字符进行转义
   $sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";
   echo "输出SQL语句:".$sql."<br><br>";
   $result=mysqli_query($db,$sql);
   $row = @mysqli_fetch_array($result);

   if($row)     //
  {
       echo 'Your Login name:'. $row['user'];
       echo "<br>";
       echo 'Your Password:' .$row['passwd'];
  }
   else
  {
       echo mysqli_error($db);
  }
   mysqli_close($db);
}
?>

2.2.2 PHP函数介绍

addslashes()
image.png

2.2.3 测试

我们发现输入'时,'被addslashes()转义。
image.png

我们使用%df和前面的\闭合也就是%5c,然后我们的%27也就是'直接逃逸出来,这时我们就能构造自己想要执行的SQL语句,造成SQL注入。

测试语句:

1%df%27 and extractvalue(1,concat(0x7e,(select user()),0x7e)) -- qwe

image.png

2.3 盲注

在盲注中不管是布尔盲注还是时间型盲注,页面显示不会有明显的变化,代码审计中只能通过查看源代码闭合原有的SQL语句,然后利用MySQL中延时的方式来判断是否存在SQL注入。

2.3.1 代码示例

这里为了进行盲注的演示,在代码中特意加入了一条if判断,当mysqli_fetch_array()查询的结果集为NULL的时候,返回id=1的数据内容,这就让我们无法判断插入的SQL语句是否执行成功,只能通过延时来进行测试。

<?php
if(isset($_GET['id']))
{
   header("Content-type:text/html;charset=utf-8");
   $db = mysqli_connect("localhost:3307","root","123456","demo");
   if(!$db){
       echo "数据库链接失败!";
       exit();
  }
   $id=$_GET['id'];
   $sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";
   $result=mysqli_query($db,$sql);
   $row = @mysqli_fetch_array($result);
   if(!$row)  //如果查询的结果集为NULL的话,返回id=1的数据
  {
       $sql="SELECT * FROM user WHERE id='1' LIMIT 0,1";
       $result=mysqli_query($db,$sql);
       $row = @mysqli_fetch_array($result);
  }

   if($row)
  {
       echo 'Your Login name:'. $row['user'];
       echo "<br>";
       echo 'Your Password:' .$row['passwd'];
  }
   mysqli_close($db);
}
?>

2.3.2 测试

当我们查询数据库中存在的数据时返回指定字段的内容
image.png

当我们查询数据库中不存在的数据时,由于mysqli_fetch_array()查询结果为NULL,所以返回id=1的指定字段内容。
image.png

由于我们在代码审计时可以一目了然看到SQL语句的构造情况,所以我们只需闭合相应的特殊字符,通过sleep()函数使页面延时,从而判断此处是否存在注入点,进而进行下一步的注入。

测试语句:

2312'%20or%20sleep(5)%20--%20qwe

2.4 二次注入

2.4.1 代码示例

二次注入的逻辑是在第一次insertupdate操作时代码存在转义而无法造成注入,但数据在被插入数据库时转义会消失,正常的SQL语句将会被存储到数据库中,在第二次调用插入的数据时被还原的SQL语句将被拼接到正常的SQL语句中造成二次注入。
image.png

<?php
if(isset($_GET['user']))
{
    header("Content-type:text/html;charset=utf-8");
    $db = mysqli_connect("localhost:3307","root","123456","demo");
    if(!$db){
        echo "数据库链接失败!";
        exit();
    }
    //第一次更新操作
    $user=addslashes($_GET['user']);
    $sql="update user set user='$user' where id=1";  //修改id=1的用户名
    echo "输出第一次的SQL语句:".$sql."<br><br>";
    $result=mysqli_query($db,$sql);
	//第二次查询操作
    $sql = "select * from user where id=1";
    $result=mysqli_query($db,$sql);
    $row = @mysqli_fetch_array($result);
    $sql = "select * from user where user = '$row[2]'";  //查询结果集中下标为2(name)的一行数据
    echo "输出第二次查询的SQL语句:".$sql."<br><br>";
    $result=mysqli_query($db,$sql);
    var_dump(mysqli_fetch_row($result));  //取出查询到的结果集并以数组的形式返回

    mysqli_close($db);
}
?>

2.4.2 PHP函数介绍

mysqli_fetch_row()
image.png

2.4.3 测试

输入'时,'addslashes()转义,这里无法造成注入
image.png

但在数据库中存储时转义\被清除
image.png

但在第二次调用时转义后的SQL语句被拼接在正常的SQL语句中,造成二次注入。
测试语句:

' union select 1,2,database(),3 -- qwe

image.png

3.SQL注入代码审计总结

在审计SQL注入的时候,我们首先要找到对应的传参点,更要多关注代码中正常SQL语句的规则和过滤情况,最重要的是要闭合正常的SQL语句来,最终执行我们想要执行的SQL语句。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python BeautifulSoup4 入门使用

一、简介 BeautifulSoup4 与 lxml 一样&#xff0c;是一个 html 解析器&#xff0c;主要功能也是解析和提取数据。 BeautifulSoup4 是 爬虫 必学的技能。BeautifulSoup 最主要的功能是从网页抓取数据&#xff0c;Beautiful Soup 自动将输入文档转换为 Unicode 编码&#xff0c…

Verilog语言中case、casex、casez的用法和区别

casez与casex语句是case语句的两种变体, 在写testbench时用到。case 语句是一种多路条件分支的形式&#xff0c;可以解决 if 语句中有多个条件选项时使用不方便的问题。 一、case、casex、casez的区别 下表给出case、casex、casez的真值表&#xff1a; 1&#xff09;在case语…

【计算机网络实验】防火墙访问控制列表实验

实验内容 防火墙访问控制列表实验 实验目的 理解访问控制列表的工作原理&#xff1b;了解访问控制列表的类型&#xff1b;学习标准访问控制列表的配置。 实验要求 1 实验拓扑图 本实验所用的网络拓扑如图1所示。 图1 ACL实验拓扑结构 2 实验步骤 Router0配置&#xff1b;&…

解决 npm install express 遇到的问题总结

方法1&#xff1a;权限 以管理员身份运行cmd执行npm install express --save命令 方法2&#xff1a;切换镜像源 查看镜像源 npm config get registry 如果要直接更换淘宝&#xff1a;npm config set registry https://registry.npmmirror.com/ 使用nrm切换 1.安装nrm npm i …

106362-34-9,(D-Ala1)-Peptide T amide

肽t的有效类似物DAPTA (aSTTTNYT-amide)在单核/巨噬细胞中显示出很强的抗hiv - 1活性&#xff0c;该肽抑制病毒的进入。 编号: 110545中文名称: 肽T、(D-Ala1)-Peptide T amide英文名: (D-Ala1)-Peptide T amideCAS号: 106362-34-9单字母: H2N-DAla-STTTNYT-NH2三字母: H2N-DAl…

设计模式 — 抽象工厂模式

抽象工厂模式女娲的失误实例 一实例 二抽象工厂模式的应用抽象工厂模式的优点抽象工厂模式的缺点抽象工厂模式的使用场景抽象工厂模式的注意事项女娲的失误 女娲造人的故事。人是造出来了&#xff0c;世界也热闹了&#xff0c;可是低头一看&#xff0c;都是清一色的类型&#…

Spark框架概述

Spark 框架概述 1.1. Spark是什么 定义&#xff1a;Apache Spark是用于大规模数据处理的统一分析引擎。 弹性分布式数据集RDD是一种分布式内存抽象&#xff0c;其使得程序员能够在大规模集群中做内存运算&#xff0c;并且有一定的容错方式。而这也是整个Spark的核心数据结构…

体验静态代码块

定义 public class Game {// 静态代码块static {System.out.println("static...run...");}// 构造方法public Game() {System.out.println("game...construct...");} }使用 结论 静态代码块在类被首次加载的时候触发启动

效能优化实践:C/C++单元测试万能插桩工具

研发效能是一个涉及面很广的话题&#xff0c;它涵盖了软件交付的整个生命周期&#xff0c;涉及产品、架构、开发、测试、运维&#xff0c;每个环节都可能影响顺畅、高质量地持续有效交付。在腾讯安全平台部实际研发与测试工作中我们发现&#xff0c;代码插桩隔离是单元测试工作…

theos tweak导入自定义类

有时&#xff0c;我们使用tweak的时候需要用到自定义的类&#xff0c;那么怎么引用呢&#xff1f; 假设我们有一个自定义类&#xff0c;people.h/people.m 那么分两种情况&#xff1a; 情况一&#xff0c;直接使用官方的tweak工程&#xff1a; 目录结构一般如下&#xff1a; …

[第九篇]——Docker 镜像使用

Docker 镜像使用 当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 下面我们来学习&#xff1a; 1、管理和使用本地 Docker 主机镜像2、创建镜像列出镜像列表 …

蛋白纯化-实验设计

小 M 不怕纯化“难”&#xff0c;IP、WB 只等闲。泡了两年实验室的小 M&#xff0c;理论与实操经验共有&#xff0c;且看我如何闯过蛋白纯化的几道“关”。 第一关 产品选择 小 M 敲黑板&#xff1a;此关最基础也最重要&#xff0c;谨防“一步错&#xff0c;步步错”。 亲和层析…

jenkins+junit4+allure+selenium实现自动化测试与结果可视化

安装包 jenkins.war jdk-8u332-linux-x64.tar.gz https://repo1.maven.org/maven2/io/qameta/allure/allure-commandline/2.17.2/ allure-commandline-2.17.2.zip https://chromedriver.storage.googleapis.com/index.html chromedriver 安装JDK 解压 tar xvf…

优盘数据恢复如何操作?恢复U盘数据的三个简单方法

对于我们用户来说&#xff0c;经常使用U盘来存储一些重要的文件是很常见的事。很多用户在使用的时候&#xff0c;经常因为操作不规范&#xff0c;而造成一些数据丢失。那么我们该如何做呢&#xff1f;优盘数据恢复如何操作&#xff1f;今天小编就来为大家分享一下关于如何将U盘…

基于梯度的图像边缘检测

参考视频&#xff1a;https://www.bing.com/videos/search?qacomputationalapproachtoedgedetection&docid608014236869751913&mid8C04384FFDD6A47533238C04384FFDD6A4753323&viewdetail&FORMVIRE 参考文献&#xff1a;A Computational Approach to Edge Dete…

【图像去噪】基于空间光谱总变化减少高光谱图像的混合噪声(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

线程的“打断”

【打断线程的三个方法】&#xff1a; //Thread.java public void interrupt() //t.interrupt() 打断t线程&#xff08;设置t线程某给标志位ftrue&#xff0c;并不是打断线程的运行&#xff09; public boolean isInterrupted() //t.isInterrupted() 查询打…

线程池源码解析 1.前导_FutureTask源码解析

线程池—FutureTask源码解析 简介 在学习线程池之前&#xff0c;需要先学习一下 FutureTask&#xff0c;因为线程池 submit 的结果就是 FutureTask。 那么什么是 FutureTask&#xff0c;其表示一个未来的任务。也就是说这个任务比较耗时&#xff0c;当前调用线程会阻塞拿到这…

某程序员发现 CSDN官方“漏洞”,立省¥10000+,抓紧薅吧

是一个省钱的组织&#xff01;&#xff01;&#xff01;它叫做勤学会&#xff0c;CSDN 官方背书。 打开这篇博客&#xff0c;你首先就要面对一个问题。 勤学会到底是什么&#xff1f;活动&#xff1f;社区&#xff1f;还是一个名词。 今天这篇博客就从解释【勤学会】这三个字开…

【Wins+VSCode】配置C++开发环境

目录1、安装vscode2、安装中文包和c扩展包3、安装c编译工具&#xff1a;g4、运行代码测试5、lauch.json6、tasks.json7、问题7.1、找不到gcc任务Reference1、安装vscode 官网下载就可以了&#xff0c;免费的&#xff1a; https://code.visualstudio.com/ 2、安装中文包和c扩展…