zyNo.23

SQL注入漏洞

1.SQL语句基础知识

一个数据库由多个表空间组成,sql注入关系到关系型数据库,常见的关系型数据库有MySQL,Postgres,SQLServer,Oracle等

以Mysql为例,输入    mysql-u用户名-p密码   即可登录到MySQL交互式命令行界面。

既然是数据的集合,我们要想操作这些数据就需要有一定的媒介和手段。比如,可以选择用图形化的工具(如Datagrip、Navicat等),也可以直接使用数据库管理工具自带的命令行(如MySQL自带了一个命令行的界面,Postgres亦然)。我们要与这些界面进行交互,去管理数据的话,就需要一种语言或者说一种规范去定义,这就是sql语句

sql语句的基本操作:

#创建表users,其中包含两个字段id、name
create table users (id int (11),name varchar(256));


#查看当前数据库下的所有表名
show tables;


#向 users表中插入数据
insert into users values (1,'admin'), (2,'test');


#查询users 表中的所有数据
select * from users;


#查询id为1的数据
select * from users where id=1;


#修改数据(将name为admin的数据改为name为abc)
update users set name='abc' where name='admin';

详细解释看我另一篇文章SQL 语句的详细解释-CSDN博客【代码】SQL 语句的详细解释。 https://blog.csdn.net/2401_88743143/article/details/145594691?sharetype=blogdetail&sharerId=145594691&sharerefer=PC&sharesource=2401_88743143&sharefrom=mp_from_link

2.SQL注入漏洞的基础概念

代码解释

  • include "db.php";:使用 include 语句引入名为 db.php 的文件。通常 db.php 会包含数据库连接、操作相关的函数或配置信息,这里引入它是为了后续能使用其中定义的数据库操作功能(如代码中的 select 函数)。
  • $id = $_GET['id'];:通过 $_GET 超全局变量获取 URL 中传递的名为 id 的参数值,并将其赋值给变量 $id$_GET 用于获取通过 GET 方法提交的数据,例如在 URL 中形如 example.php?id=1 的形式,1 就会被获取到赋值给 $id
  • $result = select("select title, content from contents where id=$id;");:调用名为 select 的函数(此函数应在 db.php 中定义),传入一个 SQL 查询语句 select title, content from contents where id=$id; 。该 SQL 语句的作用是从名为 contents 的数据库表中,查询 id 字段值等于 $id 的记录的 titlecontent 字段内容。查询结果会被存储在 $result 变量中。
  • echo(json_encode(isset($result[0])? $result[0] : []));:首先使用 isset 函数判断 $result 数组的第一个元素(索引为 0 )是否存在。如果存在,就将其作为参数传递给 json_encode 函数,将其转换为 JSON 格式的字符串;如果不存在,就将一个空数组 [] 转换为 JSON 格式字符串。最后使用 echo 函数输出转换后的 JSON 字符串。

这段代码存在 SQL 注入风险,因为 $id 直接拼接进 SQL 语句中,如果用户可控的 $id 传入恶意内容(如 1; DROP TABLE contents; ),可能导致数据库被恶意操作。

注意,如果输入“id =- 1 or1=1;#”,则查询语句为“select title,content from contents where id =- 1 or 1=1;#;”,语句中的where判断子句部分可以分成两个条件“或”来看,满足其一即可。首先来看id =- 1,id字段显然不会存在为负数的记录,则前半部分不成立;后半部分为1=1,永远成立,此条件可以把所有记录匹配查询出来。“;#”是为了将语句后面可能出现的多余查询条件给注释掉,避免造成利用失败。

3.手工注入方法

数据库

先用union(因为SQL语句union要求联合起来的前后请求列数必须相等,这样才能正确查询出结果。)探测sql查询语句有几行,利用“-1 union select 1;#"“-1 union select 1,2;#”等进行探测(

只要有形如title为1,content为2等返回不为空的结果,就说明成功探测到了列数。),

控制联合查询中1,2任意一个位置为回显位,即可回带数据。例如:

获取数据库当前的版本,传入“id =- 1 unionselect 1,version();#",

获取当前连接所在的数据库的名称,传入“id =- 1 unionselect 1,database();#”,

获取当前连接的用户,传入“id =- 1 union select1,user();#。

如果想获取数据库系统中所有数据库的名称列表,显然此处不能使用“show databases;”,需要想办法从MySQL之前自带的数据库中获取信息,如information_schema,这个数据库储存了数据库的信息,我们来尝试获取其中的schema_name字段的数据。

为什莫不用show databases;

在正常的MySQL客户端环境中,“show databases”能直接展示所有数据库名称,这是客户端工具和MySQL服务端交互的正常流程。但在SQL注入时,我们注入的语句通常是要嵌在其他SQL语句里执行的,而且可能受到各种限制和上下文环境的影响。很多时候,单纯使用“show databases”并不能按预期那样获取到所有数据库名称列表,并且它的输出格式等也不一定适合注入场景下我们对数据提取和处理的需求。

information_schema

MySQL自带的数据库,其中有一个很重要的数据库叫“information_schema”。这个数据库里存储了很多关于MySQL系统的元数据信息,包括所有数据库的结构、表结构、字段信息等等。如果我们想在SQL注入时获取所有数据库名称,就可以从“information_schema”数据库里的特定表(比如“schemata_names”表)中去查询。这个表中记录了所有数据库的名称,我们通过合适的查询语句,比如

“select schema_name from information_schema.schemata_names;”,就能获取到所有数据库的名称列表。

如果我们想要获取其他数据库的名字,一种办法是用limit子句。传入“id =- 1 union select 1,schema_name from

information_schema.schemata limit 1, 1;#",格式为limit<起始位置>,<查询条数>从0开始,则1就是第二条数据。

(id=-1 UNION SELECT 1, schema_name FROM  information_schema.schemata_names LIMIT 1, 1;#)

但这样就意味着我们需要依次修改起始位置来获取数据,非常麻烦。这时我们就需要使用到另外一种语法,传入“id=-1 union select 1,group_concat (schema_name) from information_schema. schemata;#”,使用group_concat把这个字段所有的查询结果用逗号拼接到一起

数据表

例如查看ctf-training 这个库里的表有什么内容,需要从information_schema这个库里的表tables去查找相应的信息

(1)先找表名。传入“id =- 1 union select1,group_concat(table_name)   from information_schema.tables  where  table_schema='ctftraining';#",查询ctftraining这个库中所有表的名称并拼接返回,

(2)接着union select需要知道表里字段的名称才能做单字段的查询,如果直接输入 ,很大概率会因为union select前后列数不一致导致查询出错。所以我们还得获取表里的字段名,这里我们就从information_schema的columns表进行查询。比如想查询FLAG_TABLE这个表的字段名,就传入“id =- 1 union select 1 , group_concat( column_name ) from information_schema.columns where table_schema='ctftraining'and table_name='flag';#"

(3)拿到了字段名flag,我们就可以来尝试拉取数据了,传入“id =- 1 union select 1, flag from ctftraining.flag;#",

4.注入利用方式分类——布尔盲注利用

数据库有记录,就返回res=1,否则就返回res=0,所以需要利用好仅存的这一点1和0的结果,获取数据库里的数据,尝试利用username参数,传入username=1' or 1=1;#,后端查询的语句就相当于变成了:select password from admin where username =' 1 ' or 1=1; #

or 1=1永远为真,则永远会查询到记录,所以请求会返回1,对此进行利用,如果我们能在此处进行一个判断,比如判断某个数据字段第几位上的字符是否为'1',如果成立则为真,不成立为假。写成语句如下:select password from admin where username='1'or if((substring(version (),1,1)='1'),1,0);#

代码解释

  • if 函数if 是 SQL 中的条件判断函数,其语法为 if(condition, value_if_true, value_if_false)。意思是如果 condition 条件为真,则返回 value_if_true;如果为假,则返回 value_if_false。在这条语句里,if((substring(version (),1,1)='1'),1,0) 就是判断 substring(version (),1,1)='1' 这个条件是否成立,如果成立就返回 1,不成立则返回 0
  • substring(version (),1,1)
    • version() 是 SQL 中的一个函数,用于返回当前数据库的版本信息,例如 5.7.33 等。
    • substring(str, start, length) 是字符串截取函数,用于从字符串 str 中截取从 start 位置开始、长度为 length 的子字符串。所以 substring(version (),1,1) 就是截取数据库版本信息的第一个字符。
  • 总的说就是:就是判断version()从第一位开始的一位字符是否为'1',是则返回1,否则返回0,得出version()的值

5.SQL注入利用方式分类——时间盲注利用

没有回显就利用返回时间快慢确定字符,用MySQL中sleep函数。例如:

传入“username=1' or if((substring (version(),1,1)='1'),sleep (10),0);#”,也就是当version()第一位为1时,就会进入到第二个参数里,会触发sleep(10),如果不符合就会返回0。sleep(10)则会让语句等待10s后再返回

补充资料

我在之前的文章zyNo.18-CSDN博客  有一些关于布尔和时间盲注的相关知识

经典例题:[CISCN2019]Hack World-CSDN博客

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

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

相关文章

LeapMotion第2代 Unity示范代码(桌面开发)

一、官方地址&#xff1a; 官网&#xff1a;https://www.ultraleap.com/ 驱动下载&#xff1a;https://leap2.ultraleap.com/downloads/leap-motion-controller-2/ docs地址&#xff1a;https://docs.ultraleap.com/xr-and-tabletop/tabletop/unity/getting-started/index.html…

深入剖析推理模型:从DeepSeek R1看LLM推理能力构建与优化

著名 AI 研究者和博主 Sebastian Raschka 又更新博客了。原文地址&#xff1a;https://sebastianraschka.com/blog/2025/understanding-reasoning-llms.html。这一次&#xff0c;他将立足于 DeepSeek 技术报告&#xff0c;介绍用于构建推理模型的四种主要方法&#xff0c;也就是…

使用Cocos Creator制作“打砖块”小游戏:从零开始的详细教程

Cocos Creator是一款强大的游戏开发工具,特别适合2D游戏的开发。本文将以经典的“打砖块”小游戏为例,逐步讲解如何使用Cocos Creator实现这个游戏。我们将从项目创建、场景搭建、脚本编写到最终的游戏发布,详细讲解每一步的实现过程。 1. 环境准备 首先,确保你已经安装了…

vue3常见面试题

当然&#xff0c;以下是关于 Vue 3 的一些常见面试题及其答案&#xff1a; 1. Vue 3 相比 Vue 2 有哪些主要改进&#xff1f; 性能提升&#xff1a;Vue 3 在编译时做了更多的优化&#xff0c;比如静态提升&#xff08;hoisting static nodes&#xff09;、事件监听缓存等。更…

Ubuntu 22.04 LTS 安装MinerU

1. 检测是否已安装nvidia驱动 nvidia-smi 如果看到类似如下的信息&#xff0c;说明已经安装了nvidia驱动&#xff0c;可以跳过步骤2 Note CUDA Version 显示的版本号应 > 12.1&#xff0c;如显示的版本号小于12.1&#xff0c;请升级驱动 2. 安装驱动 如没有驱动&#…

DeepSeek 指导手册(入门到精通)

第⼀章&#xff1a;准备篇&#xff08;三分钟上手&#xff09;1.1 三分钟创建你的 AI 伙伴1.2 认识你的 AI 控制台 第二章&#xff1a;基础对话篇&#xff08;像交朋友⼀样学交流&#xff09;2.1 有效提问的五个黄金法则2.2 新手必学魔法指令 第三章&#xff1a;效率飞跃篇&…

MacOS使用PhpWebStudy搭建PHP开发环境

mac上的PHP开发环境搭建方式有很多, brew, docker, mamp等, 这里使用最近新出的工具PhpWebStudy来搭建mac上的php开发环境 安装 使用brew安装 brew install phpwebstudy 无法使用brew的话, 可以去官网下载最新版本安装 FlyEnv | Powerful Web Server and Environment Mana…

布隆过滤器的原理和应用场景,解决缓存穿透

一、布隆过滤器BloomFilter是什么 布隆过滤器BloomFilter是一种专门用来解决去重问题的高级数据结果。 实质就是一个大型位数组和几个不同的无偏hash函数&#xff0c;无偏表示分布均匀。由一个初值为零的bit数组和多个哈希函数组成&#xff0c;用来判断某个数据是否存在&…

macOs安装nvm

首先确定本机上没有安装nvm 如果之前安装过先卸载 1. 删除 nvm 目录 首先&#xff0c;删除 nvm 所安装的文件目录。默认情况下&#xff0c;nvm 会安装到 ~/.nvm 目录。 运行以下命令删除 nvm 目录&#xff1a; rm -rf ~/.nvm2. 移除 .zshrc 或 .bash_profile 中的 nvm 配置…

uniapp + vite + 使用多个 ui 库

样式冲突 新建了个项目 安装多个 ui 库 发现 uview-plus 和 Ant Design Vue 3.2.20 的 按钮样式 冲突uvuew-plus 的按钮样式 会被 ant 的样式给覆盖解决方式 找到圆满 ant.css 注释 button, html [type"button"], [type"reset"], [type"submit&quo…

【大语言模型】在大语言模型中,user、assistant、system 三种角色的定位和功能有何不同。

在大语言模型&#xff08;如GPT系列&#xff09;中&#xff0c;user、assistant、system 是三种核心角色&#xff0c;它们的定位和功能不同&#xff0c;共同构成对话的上下文结构。以下是具体区别和用途&#xff1a; 1. System&#xff08;系统角色&#xff09; 定位&#xff…

react中如何获取真实的dom

在 React 中&#xff0c;获取真实的 DOM 元素通常通过 ref 来实现。ref 是一个特殊的属性&#xff0c;用于引用组件或 DOM 元素的实例。你可以通过 ref 获取到组件的真实 DOM 元素或组件实例。 1. 函数组件中的 useRef 在函数组件中&#xff0c;获取 DOM 元素的引用需要使用 …

关于“前端已死”的命题

翻阅知乎论坛&#xff0c;看了各位大佬的解析&#xff0c;从技术发展、市场环境、岗位需求三个维度综合理解这个命题&#xff1a; 1. 技术层面 前端技术生态并未停滞&#xff0c;反而持续迭代升级。HTML/CSS/JavaScript 核心基础未变&#xff0c;但框架&#xff08;如 Vue、R…

Docker Compose:编排多容器应用

1. 什么是 Docker Compose? Docker Compose 是一个用于定义和管理多容器 Docker 应用的工具。它通过一个简单的配置文件(docker-compose.yml),让你能够在一个命令下启动、停止和管理多个容器。这使得在开发、测试和生产环境中,管理复杂的应用变得更加简单。 Docker Comp…

(2025)深度分析DeepSeek-R1开源的6种蒸馏模型之间的逻辑处理和编写代码能力区别以及配置要求,并与ChatGPT进行对比(附本地部署教程)

(2025)通过Ollama光速部署本地DeepSeek-R1模型(支持Windows10/11)_deepseek猫娘咒语-CSDN博客文章浏览阅读1k次&#xff0c;点赞19次&#xff0c;收藏9次。通过Ollama光速部署本地DeepSeek-R1(支持Windows10/11)_deepseek猫娘咒语https://blog.csdn.net/m0_70478643/article/de…

Ubuntu安装geteck/jetlinks实战:源码启动

这个还是很复杂的&#xff0c;建议使用docker即可。 参考 使用源码启动JetLinks | JetLinks 物联网基础平台 安装Ubuntu虚拟机&#xff08;略&#xff09;安装JDK8编译Redis安装mysql ubuntu安装MySqL server-CSDN博客 初次使用&#xff0c;不要安装ElasticSearch下载源码…

【docker知识】快速找出服务器中占用内存较高的容器

本文由Markdown语法编辑器编辑完成。 1.背景&#xff1a; 近期在处理现场问题&#xff0c;观察服务器时&#xff0c;会遇到某些进程占用较高内存的情况。由于我们的服务&#xff0c;基本上都是以容器的方式在运行&#xff0c;因此就需要找到&#xff0c;到底是哪个容器&#…

Jenkins 安装插件 二

Jenkins 安装插件 二 一. 打开 Dashboard 打开 Jenkins 界面&#xff0c;不管在任何界面&#xff0c;只需要点击左上角 Dashboard 按钮即可 二. 打开 Manage Jenkins 找到 Manage Jenkins -> System Configuration -> Plugins 点击 Plugins 打开界面如下 Updates&a…

OpenCV机器学习(1)人工神经网络 - 多层感知器类cv::ml::ANN_MLP

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::ml::ANN_MLP 是 OpenCV 库中的一部分&#xff0c;用于实现人工神经网络 - 多层感知器&#xff08;Artificial Neural Network - Multi-Layer…

Qt中的事件

写一个 可以拖动的按钮 DraggablePushButton.h 头文件 #ifndef DRAGGABLEPUSHBUTTON_H #define DRAGGABLEPUSHBUTTON_H#include <QPushButton> #include <QMouseEvent>class DraggablePushButton : public QPushButton {Q_OBJECTpublic:explicit DraggablePushBu…