网络攻防技术——SQL注入
实验8:Sql注入实验
SQL注入是一种代码注入技术,它利用web应用程序和数据库服务器之间接口中的漏洞。当用户的输入在发送到后端数据库服务器之前未在web应用程序中正确检查时,就会出现此漏洞。许多web应用程序从用户处获取输入,然后使用这些输入构造SQL查询,这样web应用程序就可以从数据库中获取信息。Web应用程序还使用SQL查询在数据库中存储信息。这些是web应用程序开发中的常见做法。如果未仔细构造SQL查询,则可能会出现SQL注入漏洞。SQL注入攻击是对web应用程序最常见的攻击之一。
在本实验室中,我们创建了一个易受SQL注入攻击的web应用程序。我们的web应用程序包含许多web开发人员所犯的常见错误。学生的目标是找到利用SQL注入漏洞的方法,演示攻击可能造成的损害,并掌握有助于抵御此类攻击的技术。
-
Task1
`mysql -u root -pdees` 这是mysql的登录命令,-u后加要登陆的用户,-p后加登录密码
`use`命令用于切换到希望操作的数据库,使用show tables命令可以查看数据库下有哪些表,发现credential表
我们可以使用select命令查询该表的内容
-
Task2
这条sql语句是根据用户名和密码匹配的规则挑选出对应的记录,用户登录的处理逻辑是根据下面的sql语句的查询结果(返回值),判断以哪个id登录,没有返回结果不允许登录,所以我们即使不知道正确的密码,只要让下面的sql语句有返回结果就可以绕开验证过程
在sql注入中常用的一种手法是构造1=1恒等式绕过,这样的条件会让select语句的条件失效
Mysql中使用单引号引用字段,针对这种格式,经常构造单引号提前结束条件判断
-
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'(被注释了)
成功登入
-
Task 2.2
curl是一个用于在网络上传输数据并支持多种协议的命令行工具
浏览器的url栏已经将特殊字符转义,我们只需再根据指导书的提示将单引号转义成27%即可
得到结果如下,发现成功获取到了应该被渲染在前端的数据。
-
Task 2.3
MySQL的query函数只允许一条语句执行,如果要同时执行多条语句需要使用multi_query函数,对配置文件进行修改,重启后生效
在注入语句的后面加上一条update语句,即:
admin';update credential set salary=8900 where Name="Boby";#
发现页面没有返回结果,可能是更改查询函数后,返回值发生了变化,前端解析不了,于是登录数据库查看
发现update语句成功执行
-
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的账号
-
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一下项目)
-
总结
SQL 注入攻击的方式多种多样,包括基于整数的注入、基于盲注的注入、基于字符的注入等多个方面。攻击者可以利用一些工具自动化地发现和利用 SQL 注入漏洞;除了预防和修复 SQL 注入漏洞外,还可以采用一些其他的安全措施,如加强访问控制、使用加密技术、
进行安全审计等,从而提高 Web 应用程序的安全性。
-
漏洞概念
SQL注入攻击指的是通过构建特殊的输入作为参数传入 Web 应用程序,而这些输入大都是 SQL 语法里的一些组合,通过执行 SQL 语句进而执行攻击者所要的操作。
-
(二) 漏洞原理
后端将前端提交的查询参数拼接到代码的 SQL 语句模板中进行查询,当攻击者提交带有非预期 sql 查询片段时,导致数据库被意外查询。
(三) 漏洞危害
1. 数据库信息泄露
2. 条件满足的情况下(能够通过数据库执行命令),导致服务器被接管
(四) 修复思路
1.使用参数化查询:使用参数化查询可以将用户输入的数据作为参数传递给 SQL 语句,从而避免了恶意 SQL 注入的风险。
2.输入验证:对用户输入的数据进行验证,确保其符合预期的格式和类型。
3.转义字符:将特殊字符进行转义,从而避免其被误解为 SQL 语句的一部分。
4.最小化权限:将数据库用户的权限限制到最小,只授予其必要的权限。
5.使用 ORM 框架:使用 ORM 框架可以将数据库操作抽象出来,从而避免手动编写 SQL语句的风险
本文来自博客园,作者:Leo1017,转载请注明原文链接:https://www.cnblogs.com/leo1017/p/17933195.html