SQL注入 - 手工注入sqli-labs
  Q68mX1P3tSGz 2024年03月05日 11 0

SQL注入(SQL Injection)是指Web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在Web应用程序中事先定义好的查询语句的结尾后添加额外的SQL语句,在管理员不知情的情况下实现非法操作。以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

简单来讲就是:攻击者通过构造恶意的SQL语句来实现对数据库的操作。

两个条件

  • 参数用户可控 —— 用户能够控制数据的输入
  • 构造的参数可带入数据库并且被执行 —— 原本要执行的sql语句拼接了用户的输入

SQL注入的核心:将输入语句拼接到代码中,并被当成SQL语句执行。


SQL注入可能发生在哪些地方

以下是一些常见的SQL注入发生地点:

  1. 用户输入:这是最常见的SQL注入来源,包括但不限于表单字段如登录表单、搜索框、注册表单等。
  2. URL参数:通过修改URL的查询字符串参数,攻击者可以尝试对数据库进行注入攻击。
  3. Cookie:Web应用程序会使用Cookie来存储用户会话信息,就可能被用来执行SQL注入。
  4. HTTP头部:有些Web应用程序可能会根据HTTP请求头部字段(如User-Agent、Referer等)中的信息来构建SQL查询。
  5. XML输入:有些Web应用程序会使用XML或其他进行数据交换,如果未正确处理输入数据,就可能被用来执行SQL注入。

SQL注入点如何探测

在输入字段中尝试输入特殊的SQL字符,如果应用程序返回了数据库错误信息,或者异常,可能就意味着存在SQL注入漏洞。

只要是带有参数的动态网页并且该网页访问了数据库,那么就有可能存在 SQL 注入:

  • 先加单引号'或双引号"等看是否报错,如果报错就可能存在SQL注入漏洞。

  • 另外在URL后面加and 1=1and 1=2看页面是否显示一致,显示不一样的话,肯定存在SQL注入漏洞。

  • 还有就是利用盲注,通过观察数据库响应时间或者不同响应来推断查询的真假。


SQL注入的类型有哪些

按照注入点的数据类型来分类

  1. 数字型注入点

类似结构http://xxx.com/xxx.php?id=1这种形式,注入点id类型为数字。

这一类的 SQL 语句原型大概为select * from table_name where id=1,若存在注入,可以构造出类似与如下的sql注入语句进行注入:

select * from table_name where id=1 and 1=1
  1. 字符型注入点

类似结构http://xxx.com/xxx.php?name=admin这种形式,注入点name类型为字符类型。

这一类的 SQL 语句原型大概为 select * from table_name where name='admin' 这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。可以构造出类似与如下的sql注入语句进行注入:将后引号闭合

select * from table_name where name='admin' and 1=1'

按照数据提交的方式来分类:

  1. GET 注入

提交数据的方式是 GET , 注入点的位置在 GET 参数部分。

  1. POST 注入

使用 POST 方式提交数据,注入点位置在 POST 数据部分。

  1. Cookie 注入

HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。

  1. HTTP 头部注入

注入点在 HTTP 请求头部的某个字段中。(严格讲的话,Cookie 其实应该也是算头部注入的一种形式)

按照执行效果来分类:

  1. 基于布尔的盲注

即可以根据返回页面判断条件真假的注入。

  1. 基于时间的盲注

即用条件语句查看时间延迟语句是否执行(即页面返回时间是否延长)来判断。

  1. 基于报错注入

即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。

  1. 联合查询注入

可以使用 union 的情况下的注入。

  1. 堆查询注入

可以同时执行多条语句的执行时的注入。

  1. 宽字节注入

数据库编码与 php 编码设置为不同的两个编码,这样就可能会产生宽字节注入。


SQL注入的一般步骤

1. 注入点探测

​ 手工注入:

  • 可控参数的改变是否可以影响页面的显示的结果
  • 输入的sql语句是否能报错:通过数据库的报错,看到数据库的一些语句痕迹
  • 输入的sql语句是否不报错:语句能够成功闭合

​ 工具注入:

  • sqlmap

2.信息获取

  • 环境信息:数据库类型、数据库版本、操作性系统版本、用户信息等
  • 数据库信息:数据库名、数据库表、字段、字段内容

3.权限获取

  • 编写webshell,上传木马,获取操作系统权限

MySQL数据库注入常用的函数

version():查看数据库版本

database():查看使用的数据库

user():查看当前用户

limit:limit子句分批来获取所有数据

group_concat():一次性获取所有的数据库信息

concat_ws(':','str1','str2','str3'):按 str1:str2:str3 格式拼接字符串

length():返回指定对象的长度

left(str,num):对字符串str从左开始数起,返回num个字符(与函数right()相反)

ascii():返回字符串str的最左字符的数值,ASCII()返回数值是从0到255

updatexml(1,concat(0x7e,(),0x7e),1):一共可以接收三个参数,报错位置在第二个参数(报错注入)

extractvalue(1,concat(0x7e,())):一共可以接收两个参数,报错位置在第二个参数(报错注入)

其他

information_schema.tables:包含了数据库里所有的表

table_name:表名

table_schema:数据库名

column_name:字段名

SQL注入的防御

  1. 采用预编译技术

例如:INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?);

使用预编译的SQL语句,SQL语句的语义不会是不会发生改变的。攻击者无法改变SQL语句的结构,只是把值赋给?,然后将?这个变量传给SQL语句。

  1. 严格控制数据类型

强类型语言中一般是不存在数字型注入的,因为在接受到用户输入id时,代码会做数据类型转换。但是没有强调处理数据类型的语言,一接收id的代码是如下这样:

$id = $_GET['id'];
$SQL = "select * from '某字段' where id = $id;";

加入一个检查数字类型函数is_numeric()就可以防止数字型注入。

  1. 对特殊的字符进行转义

在MySQL中对" ' "进行转义,这样可以防止一些恶意攻击者来闭合语句。也可以通过一些安全函数来转义特殊字符,如addslashes()等。

  1. 使用存储过程

使用存储过程的效果和使用预编译语句类似,其区别就是存储过程需要先将sql语句定义在数据库中。(尽量避免在存储过程内使用动态的sql语句)

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月05日 0

暂无评论

推荐阅读
  5NWiQFAVeqgX   2天前   4   0   0 网络安全
  OKgNPeBk991j   12小时前   7   0   0 网络安全
Q68mX1P3tSGz