靶场通关教程 | SQL注入篇(一)

在之前的文章中牛牛给大家大致介绍了Yakit中的靶场Vulinbox安装教程(插入安装靶场文的链接),实验环境安装就位后,接下来就是上手实操。接下来的日子里,牛牛将按照不同类型的漏洞为大家呈上通关教程,今天我们先来唠唠:SQL注入漏洞

网安圈中,你或许之前听过某某通过攻击数据库修改自己考试成绩的案例,(苏姐画坏牛牛修改成绩图)修改途径一般用的就是SQL注入方法。SQL注入漏洞作为网络安全最普遍的漏洞之一,在OWASP发布的top10排行榜中危害排名极高,数据库注入一直是web中一个令人头疼的问题。什么是SQL注入?简单来说就是数据「越俎代庖」做了代码才能干的事情,恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。至于更详细官方的解释,大家可以自行查询资料。

SQL注入存在于许多Web应用程序中。SQL注入攻击利用了应用程序对用户输入的不当处理,允许攻击者在数据库查询中注入恶意的SQL代码。这种攻击可能导致数据库中的数据泄露、数据篡改、绕过身份验证、执行任意代码等严重后果,对应用程序的安全性和稳定性造成严重威胁。

SQL注入漏洞的出现通常是由于应用程序未对用户输入进行充分验证和过滤,或者在构建数据库查询时没有使用预编译语句或参数化查询。攻击者利用这个漏洞可以通过构造特定的恶意输入,改变原始查询的意图,从而绕过应用程序的验证,执行非授权的数据库操作。

案例分享及教学

不存在SQL注入的情况(数字严格校验)

这个示例演示了如何通过对用户输入的参数进行数字严格校验,从而防止SQL注入攻击。数字严格校验确保只有有效的数字被用作SQL查询的参数,而不允许插入恶意的SQL代码。

示例代码:

{
DefaultQuery: "id=1",
Path:         "/user/by-id-safe",
Title:        "不存在SQL注入的情况(数字严格校验)",
Handler: func(writer http.ResponseWriter, request *http.Request) {
var a = request.URL.Query().Get("id")
i, err := strconv.ParseInt(a, 10, 64)
if err != nil {
writer.Write([]byte(err.Error()))
writer.WriteHeader(500)
return
}
u, err := s.database.GetUserById(int(i))
if err != nil {
writer.Write([]byte(err.Error()))
writer.WriteHeader(500)
return
}
sqliWriter(writer, request, []*VulinUser{u})
return
},
RiskDetected:   false,
ExpectedResult: map[string]int{"参数:id未检测到闭合边界": 1},
}

代码分析:

  • 这个示例接收一个名为 id 的查询参数,该参数预期是一个整数。
  • 通过使用 ParseInt 函数,将用户提供的 id 参数解析为一个64位整数。如果解析失败,将返回一个错误。
  • 使用解析后的整数值来执行数据库查询,这个值不包含恶意的SQL注入代码。
  • 最后,将查询结果返回给客户端。

注意:

数字严格校验是一种有效的防御措施,但在实际应用中,还需要考虑其他安全性方面的因素,例如权限控制和输入验证,以维护应用程序的安全性。

ID 为数字型的简单边界 SQL 注入

ID为数字型的简单边界SQL注入是一种常见的SQL注入漏洞,通常出现在Web应用程序中。这种漏洞的攻击目标是应用程序中处理ID参数的代码,由于没有对输入进行充分验证和过滤,导致攻击者可以在ID参数中注入恶意的SQL代码。

在这种情况下,攻击者通常会尝试构造特定的输入,以绕过应用程序的验证和过滤机制,注入恶意的SQL语句。

示例代码:

SELECT * FROM users WHERE id = 输入的ID值;

攻击示例:

1 OR 1=1

这样构造的SQL语句变成:

/*构造后的SQL*/
SELECT * FROM users WHERE id = 1 OR 1=1

由于1=1这个条件始终为真,整个查询语句将返回所有用户的数据,而不仅仅是匹配到的特定ID的用户数据。这就是SQL注入攻击的原理,攻击者可以通过注入恶意的SQL代码来绕过应用程序的身份验证,获取未授权的数据或执行恶意操作。

防御措施:

  • 使用参数化查询或预编译语句,确保用户输入的ID值不直接拼接到SQL查询中。

  • 对输入的ID值进行验证,确保它是合法的数字,并限制ID值的范围在合理的边界内。

  • 对输入的ID值进行过滤,确保它不包含任何恶意代码或特殊字符。

  • 最小化数据库的权限,确保应用程序只能访问必要的数据,并限制对数据库的敏感操作。

  • 定期进行安全审计和渗透测试,以发现和修复潜在的SQL注入漏洞。

通过采取这些安全措施,可以有效地防止ID为数字型的简单边界SQL注入漏洞,并提高Web应用程序的安全性。

靶场演示视频:查看视频

GET 参数是JSONJSON中字段存在SQL注入

有时,开发人员可能会使用JSON格式作为GET参数来传递更复杂的数据结构。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,因此在Web开发中广泛使用。JSON由键值对组成,使用花括号{}表示,例如:http://example.com/api?data={"name":"John","age":30}。

然而,如果在处理GET参数时,应用程序没有正确地验证和过滤输入的JSON数据,就可能导致JSON中的字段存在SQL注入漏洞。

示例代码:

/*URL地址*/
http://127.0.0.1:8787/user/id-json?id={"uid":1,"id":"1"}
/*原SQL语句*/
select * from vulin_users where id = 1;

攻击示例:

id={"uid":1,"id":"1 OR 1=1"}

这样SQL语句就变成如下:

/*构造后的SQL语句*/
SELECT * FROM users WHERE id = 1 OR 1=1

此时1=1 总是为真,将返回所有的用户信息。

防御措施:

  • 应该检查JSON对象中的每个字段和值,确保它们符合预期的数据类型和格式。

  • 不应该直接将JSON数据作为SQL查询的一部分,而应该使用参数化查询或预编译语句,以确保输入数据不会被误解为可执行的SQL代码。

只有这样,才能有效地防止JSON中字段存在SQL注入的风险。

靶场演示视频:查看视频

GET参数是被编码的JSONJSON中字段存在SQL注入

这种漏洞是由于在处理GET参数时,服务器端接收到经过Base64编码的JSON数据,但在解码JSON数据后未对其中的字段进行适当的输入验证和处理,直接将其用于构建SQL查询语句,导致SQL注入漏洞的产生。

攻击者可以通过恶意构造经过Base64编码的JSON数据,利用JSON中存在的SQL注入漏洞来修改查询语句,执行恶意的数据库操作,甚至获取、修改或删除数据库中的数据。这种漏洞可能导致严重的安全问题,泄露用户隐私信息、破坏数据完整性等。

示例代码:

http://127.0.0.1:8787/user/id-b64-json?id=eyJ1aWQiOjEsImlkIjoiMSJ9 (解码为{"uid":1,"id":"1"})
/*后端的查询如下*/
select * from vulin_users where id = 1;

该SQL语句为查询id值为1的用户。

攻击示例:

http://127.0.0.1:8787/user/id-b64-json?id=eyJ1aWQiOjEsImlkIjoiMSBPUiAxPTEifQ==
/*解码为*/
{"uid":1,"id":"1 OR 1=1"}
/*构造后的查询如下*/
select * from vulin_users where id = 1 OR 1=1

构造简单的测试用例,并经过base64编码后发送,这将返回所有用户的数据,而不仅仅是匹配到的特定ID的用户数据。

防御措施:

  • 避免直接拼接SQL查询: 绝不要直接将用户提供的数据直接拼接到SQL查询中,无论数据是否经过Base64编码。直接拼接会导致SQL注入漏洞,攻击者可以通过恶意构造的数据修改查询语句,从而访问、修改或删除数据库中的数据。

  • 解码Base64数据: 首先,在服务器端接收到GET参数后,先进行Base64解码得到原始的JSON数据。

  • 使用参数化查询或ORM: 使用参数化查询或对象关系映射(ORM)库来与数据库进行交互。参数化查询将参数与查询语句分开,从而防止SQL注入攻击。

靶场演示视频:查看视频

ID 为数字型的简单边界SQL报错检测

边界SQL报错检测是一种测试方法,用于探测应用程序在处理数字型ID参数时是否存在SQL注入漏洞。在此测试中,我们会尝试构造一些特殊的输入,以观察应用程序的反应。这里给出了一些示例:

示例代码:

SELECT * FROM users WHERE id = {user_input};

现在有一个查询,用于从数据库中获取用户信息,其中,{user_input}是应用程序接收的用户输入。

攻击示例:

  • 正常输入: 首先,我们使用正常的数字型输入来检查查询是否按预期工作

user_input = 123
SELECT * FROM users WHERE id = 123;

如果查询正常执行并返回预期结果,说明应用程序对于正常输入的处理是正确的。

  • 边界值测试: 接下来,我们可以测试边界值,包括最小值、最大值和边界附近的值。例如:

user_input = 0  # 最小值
SELECT * FROM users WHERE id = 0;

user_input = 2147483647  # INT类型最大值
SELECT * FROM users WHERE id = 2147483647;

user_input = 1  # 边界附近的值
SELECT * FROM users WHERE id = 1;

通过测试边界值,我们可以确保应用程序在处理边界输入时没有出现错误或异常情况。

  • 非数字输入: 接下来,我们可以尝试输入非数字型数据,例如字符串或特殊字符,来观察应用程序的反应。

user_input = "abc"
SELECT * FROM users WHERE id = "abc";

通以上测试来查看程序是否出现异常错误,从而判断是否存在SQL注入漏洞。

防御措施:

防止ID为数字型的简单边界SQL注入,可以采取以下预防措施:

  • 使用参数化查询: 使用参数化查询(Prepared Statements)来执行SQL语句,确保用户输入的ID不会直接拼接到SQL查询语句中。参数化查询会将输入和查询逻辑分离,有效地防止SQL注入攻击。

  • 输入验证: 在接收用户输入的ID之前,进行输入验证,确保它是一个合法的数字。可以使用正则表达式或内置的类型转换函数进行验证。如果输入不是数字类型,应拒绝执行查询。

  • 转义或过滤特殊字符: 对于ID参数,可以在执行查询之前,对其进行转义或过滤,以确保不会解释为SQL代码。对于数字类型的ID,这一步通常是不必要的,因为数字不包含特殊字符。

靶场演示视频:查看视频

Cookie-ID SQL注入

Cookie-ID SQL注入是一种特定类型的SQL注入漏洞,它涉及到在处理包含在Cookie中的ID时,未对输入进行适当的验证和处理,从而导致攻击者能够注入恶意的SQL代码,执行非授权的数据库操作。

当应用程序使用Cookie来存储用户会话信息,并在后续的请求中使用Cookie中的ID来执行数据库查询时,如果对Cookie中的ID参数没有进行充分的验证和过滤,攻击者可以构造恶意的Cookie,注入SQL代码,并在查询中执行恶意操作。

示例代码:

GET /user/cookie-id HTTP/1.1
Host: 127.0.0.1:8787
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Cookie: ID=1
#后端查询
select * from vulin_users where id = 1

此案例的注入点存在于Cookie中,后端查询利用cookie传输的值进行拼接查询。

攻击示例:

GET /user/cookie-id HTTP/1.1
Host: 127.0.0.1:8787
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Cookie: ID=1 OR 1=1
#后端查询
select * from vulin_users where id = 1 OR 1=1

防御措施:

为了防止Cookie-ID SQL注入,以下是一些建议的预防措施:

  • 参数化查询: 无论从Cookie还是其他来源获取ID参数,都应使用参数化查询(Prepared Statements)来执行数据库查询。确保不直接将Cookie值拼接到SQL查询语句中,而是通过绑定参数的方式传递给数据库引擎。

  • 验证和过滤Cookie数据: 在应用程序接收Cookie数据之前,进行验证和过滤,确保它是预期的格式和类型。例如,如果ID是一个整数,验证其是否为合法的整数值。

  • 限制Cookie访问范围: 在设置Cookie时,将其限制在仅在必要的路径和域名下可见。避免在敏感操作之外的路径或域名下访问敏感的Cookie信息。

  • 不要在Cookie中存储敏感信息: 尽量避免在Cookie中存储敏感信息,特别是与用户身份认证相关的敏感数据。可以将敏感信息存储在服务器端的会话中,而在Cookie中只存储会话标识符。

  • 加密Cookie数据: 对于敏感的Cookie信息,可以进行加密处理,以增加攻击者解析Cookie的难度。

靶场演示视频:查看视频

结尾

以上就是本次教学的SQL注入案例,大家可以根据示例代码以及教学视频进行靶场训练,在训练中能够更直观的感受到SQL注入的强大攻击性,牛牛在这里给出一个小tip(画牛牛给tips图):在Yakit靶场练习过程中可以同步学习sql语言,这样可以有助于深度理解语句,提升学习速度。

SQL注入不止这些类型,在下次的文章中,牛牛会继续讲解更多,请大家持续关注Yak project公众号~

......

字符串为注入点的 SQL 注入

字符串注入点模糊查询

字符串注入点模糊查询(括号边界)

参数编码字符串注入点模糊查询(括号边界)

Base64参数(JSON)嵌套字符串注入点模糊查询(括号边界)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值