网络攻防技术——SQL注入

实验8:Sql注入实验

实验内容:

SQL注入是一种代码注入技术,它利用web应用程序和数据库服务器之间接口中的漏洞。当用户的输入在发送到后端数据库服务器之前未在web应用程序中正确检查时,就会出现此漏洞。许多web应用程序从用户处获取输入,然后使用这些输入构造SQL查询,这样web应用程序就可以从数据库中获取信息。Web应用程序还使用SQL查询在数据库中存储信息。这些是web应用程序开发中的常见做法。如果未仔细构造SQL查询,则可能会出现SQL注入漏洞。SQL注入攻击是对web应用程序最常见的攻击之一。

 

在本实验室中,我们创建了一个易受SQL注入攻击的web应用程序。我们的web应用程序包含许多web开发人员所犯的常见错误。学生的目标是找到利用SQL注入漏洞的方法,演示攻击可能造成的损害,并掌握有助于抵御此类攻击的技术。

 

 

  1. Task1

    `mysql -u root -pdees` 这是mysql的登录命令,-u后加要登陆的用户,-p后加登录密码

`use`命令用于切换到希望操作的数据库,使用show tables命令可以查看数据库下有哪些表,发现credential表

我们可以使用select命令查询该表的内容

  1. Task2

    这条sql语句是根据用户名和密码匹配的规则挑选出对应的记录,用户登录的处理逻辑是根据下面的sql语句的查询结果(返回值),判断以哪个id登录,没有返回结果不允许登录,所以我们即使不知道正确的密码,只要让下面的sql语句有返回结果就可以绕开验证过程

    在sql注入中常用的一种手法是构造1=1恒等式绕过,这样的条件会让select语句的条件失效

    Mysql中使用单引号引用字段,针对这种格式,经常构造单引号提前结束条件判断

    1. Task 2.1

      根据上面的条件,我们对于用户名的输入,首先构造admin'结束后端对用户名的判断,然后在后面加上 or 1=1,使用恒等式绕过,但我们不知道密码,所以在最后加上mysql的注释符#,使后面对密码的判断失效,攻击效果如下

      此时的sql语句就变成了SELECT id, name, eid, salary, birth, ssn, address, email, nickname,Password FROM credential WHERE name= 'admin' or 1 = 1

# ' andPassword='$hashed_pwd'(被注释了)

成功登入

  1. Task 2.2

    curl是一个用于在网络上传输数据并支持多种协议的命令行工具

    浏览器的url栏已经将特殊字符转义,我们只需再根据指导书的提示将单引号转义成27%即可

    得到结果如下,发现成功获取到了应该被渲染在前端的数据。

  1. Task 2.3

    MySQL的query函数只允许一条语句执行,如果要同时执行多条语句需要使用multi_query函数,对配置文件进行修改,重启后生效

    在注入语句的后面加上一条update语句,即:

    admin';update credential set salary=8900 where Name="Boby";#

    发现页面没有返回结果,可能是更改查询函数后,返回值发生了变化,前端解析不了,于是登录数据库查看

    发现update语句成功执行

     

  1. Task3

    这部分的更新处理逻辑如下:我们可以借鉴上一问中加单引号提前结束加注释符#去除干扰语句的思想

1. Task 3.1

第一栏中填入Haoyichen',salary='114' where Name='Alice';#,相当于只进行了更新nickname和salary的部分

        

2. Task 3.2

我们只需要把上面的sql语句中的username从Alice改成Boby即可,即: pig',salary='1' where Name='Boby';#

3. Task 3.3

         观察后端代码发现,密码不是明文存储的,这里采用的哈希算法是sha-1算法,我们选择一个新密码"nopassword",得到sha-1加密的结果

得到的哈希值就是要修改的密码的值,于是注入语句为

pig',password=' d186e8dac48a24d0115b568d0ab2c9e8b82e6adb' where Name='Boby';#

        输入nopassword成功登录Boby的账号

  1. Task4

    SQL注入漏洞的根本问题是无法将代码与数据分离,SQL语句的边界在PHP程序中和被发送到数据库处理的边界不同,为了解决这个问题,提出了一种叫做"prepared statement"的方法,为了详细阐述这个方法,需要先了解SQL语句的执行原理

    SQL语句首先经过解析和规范化阶段,在该阶段根据语法和语义检查语句是否正确,下一个阶段是编译阶段,其中关键字(例如SELECT、FROM、UPDATE等)转换为机器可以理解的格式(二进制),在查询优化阶段,从可以执行该查询的所有计划方案中选择最佳计划,并存储在缓存中,当下一个查询出现时,都会根据缓存中的内容进行检查,如果它已经存在,将跳过解析、编译和查询优化阶段,最后将编译后的SQL查询语句拿去执行

    prepared statement出现在编译之后,执行步骤之前,编译后的语句只包含空的数据占位符(placeholder),而不包含实际的语句,将实际的数据直接插入占位符中即可明确代码和数据的边界

    实际数据被问号(?)所取代,使用bind_param()函数将数据填入占位符中,其中"is"表示参数的类型:"i"表示$id中是整数类型,"s"表示$pwd是字符串类型

尝试使用admin' or 1=1;#进行注入,注入成功

这时我们选择指导书提供的保护措施,成功抵抗了sql注入攻击

相同的注入语句,不再生效(记得重新build一下项目)

  1. 总结

    SQL 注入攻击的方式多种多样,包括基于整数的注入、基于盲注的注入、基于字符的注入等多个方面。攻击者可以利用一些工具自动化地发现和利用 SQL 注入漏洞;除了预防和修复 SQL 注入漏洞外,还可以采用一些其他的安全措施,如加强访问控制、使用加密技术、

    进行安全审计等,从而提高 Web 应用程序的安全性。

    1. 漏洞概念

      SQL注入攻击指的是通过构建特殊的输入作为参数传入 Web 应用程序,而这些输入大都是 SQL 语法里的一些组合,通过执行 SQL 语句进而执行攻击者所要的操作。

(二) 漏洞原理

后端将前端提交的查询参数拼接到代码的 SQL 语句模板中进行查询,当攻击者提交带有非预期 sql 查询片段时,导致数据库被意外查询。

(三) 漏洞危害

1. 数据库信息泄露

2. 条件满足的情况下(能够通过数据库执行命令),导致服务器被接管

(四) 修复思路

1.使用参数化查询:使用参数化查询可以将用户输入的数据作为参数传递给 SQL 语句,从而避免了恶意 SQL 注入的风险。

2.输入验证:对用户输入的数据进行验证,确保其符合预期的格式和类型。

3.转义字符:将特殊字符进行转义,从而避免其被误解为 SQL 语句的一部分。

4.最小化权限:将数据库用户的权限限制到最小,只授予其必要的权限。

5.使用 ORM 框架:使用 ORM 框架可以将数据库操作抽象出来,从而避免手动编写 SQL语句的风险

posted @ 2023-12-28 17:29  Leo1017  阅读(180)  评论(0编辑  收藏  举报