前言
话接上回,上周牛牛已经给大家进行了部分SQL注入漏洞类型的教学Yakit靶场通关教程|SQL注入篇(一)。一个严重的SQL注入漏洞,可能会直接导致企业一夜破产!
这并不是玩笑话。SQL注入漏洞不仅普遍并且危害也极高,类型繁杂,作为网安从业者,应该能认识到SQL注入对于安全测试的重要性。
那么本周我们将开启进阶之旅,了解更高难度的SQL注入类型。在SQL注入中,可以简单分为数字型、字符型两种类型。如何判定呢?看\斜杠后面跟着的字符,是什么字符,它的闭合字符就是什么,若是没有,就为数字型。上周我们谈到了数字型,这周牛牛将着重讲解字符型注入。
案例分享及教学
字符串为注入点的 SQL 注入
字符串为注入点的SQL注入是一种常见的安全漏洞,它发生在应用程序在处理用户提供的字符串数据时,未正确验证、转义或过滤这些输入,导致攻击者可以通过恶意构造的字符串来执行非授权的数据库操作。
常见的字符串为注入点的SQL注入攻击是通过在输入的字符串中插入SQL语句的特殊字符,使得这些特殊字符被误解为SQL代码的一部分,从而改变原始的SQL查询的含义。
示例代码:
http://127.0.0.1:8787/user/name?name=admin
#查询名为admin的用户
select * from vulin_users where username = 'admin';
此案例中通过用户输入的用户名来执行查询。
攻击示例:
user_input1 = ' OR 1=1 --
user_input2 = ' OR '1'='1
攻击者可以通过恶意构造的用户名来尝试注入SQL代码,如果应用程序未进行适当的处理,最终的查询语句会变成:
/*user_input1构造语句*/
select * from vulin_users where username = '' OR 1=1 --';
/*user_input2构造语句*/
select * from vulin_users where username = '' OR '1'='1';
这将使查询始终返回所有用户的数据,绕过了原本的身份验证过程。
防御措施:
参数化查询:使用参数化查询(Prepared Statements)来执行SQL语句。参数化查询会将用户输入与查询逻辑分开,有效地防止SQL注入攻击。
输入验证:在接收字符串输入之前,进行输入验证,确保它是一个合法的格式和长度。例如,对于用户名,验证是否包含特殊字符或空格。
转义或过滤特殊字符:在执行查询之前,对用户输入进行转义或过滤,确保不会被误解为SQL代码。在大多数编程语言和数据库引擎中,都有提供相关的转义函数,例如在Python中可以使用escape_string()
来转义字符串。
白名单验证:对于一些特定的输入字段,可以使用白名单验证,只接受预定义的合法输入,拒绝其他非法输入。
靶场演示:视频
字符串注入点模糊查询
在此案例中,使用了LIKE
语句进行模糊查询,查询vulin_users
表中username
字段包含字母a
的所有记录。然而,该SQL语句没有对用户输入进行任何过滤或转义,这就为注入攻击提供了机会。
示例代码:
http://127.0.0.1:8787/user/name/like?name=a&debug=1
/*查询名称为a的用户*/
select * from vulin_users where username LIKE '%a%';
在该查询中,username
字段进行了模糊查询,查找包含字母a
的用户。
攻击示例:
假设攻击者在输入中注入以下内容
a' OR '1'='1' --
/*更改后的sql语句变成如下*/
select * from vulin_users where username LIKE '%a' OR '1'='1' -- %';
/*等同于*/
select * from vulin_users where username LIKE '%a' OR '1'='1';
在这个示例中,--
表示SQL中的单行注释,它会导致数据库忽略后续的查询语句,从而绕过了原本的查询过滤条件,获取了所有用户的数据。
攻击者还可以执行其他恶意操作,比如删除数据、修改数据等,具体取决于应用程序的权限和数据库的配置。
防御措施:
参数化查询:使用参数化查询(Prepared Statements)来执行SQL语句。参数化查询会将用户输入与查询逻辑分开,有效地防止SQL注入攻击。
靶场演示:视频
字符串注入点模糊查询(括号边界)
在此案例中,仍使用了LIKE
语句进行模糊查询,但增加了查询条件并且使用了括号包裹,考验攻击者能否正常闭合括号,该SQL语句没有对用户输入进行任何过滤或转义,这就为注入攻击提供了机会。
示例代码:
http://127.0.0.1:8787/user/name/like/2?name=a&debug=1
#查询名称为a并且年龄大于20的用户
select * from vulin_users where (username LIKE '%a%') AND (age > 20);
攻击示例:
http://127.0.0.1:8787/user/name/like/2?name=' OR 1=1) --&debug=1
#如果应用程序未进行适当的处理,最终的查询语句会变成:
select * from vulin_users where (username LIKE '%' OR 1=1) --%') AND (age > 20);
#实际语句同下
select * from vulin_users where (username LIKE '%' OR 1=1);
在这个示例中,攻击者将$a
设置为' OR 1=1)--
,这将导致SQL查询中的WHERE
条件永远为真,因为1=1
始终为真。并且--
表示SQL中的单行注释,会使后续的查询语句被忽略掉。这样,攻击者就可以绕过原本的查询条件,获取vulin_users
表中所有用户记录。
防御措施:
使用参数化查询或预处理语句:不要将用户输入直接拼接到SQL查询中。使用参数化查询或预处理语句,将用户输入作为参数绑定到查询中,数据库引擎会自动处理输入的转义,避免注入攻击。
使用ORM(对象关系映射):使用ORM框架,例如Hibernate、Sequelize等,可以避免直接使用原始SQL查询,ORM框架会自动进行查询参数的处理。
输入验证和过滤:对于所有从用户获取的输入,进行合法性验证和适当的过滤,确保输入符合预期的格式和范围。拒绝非法的输入,防止恶意输入进入数据库查询。
靶场演示:视频
参数编码字符串注入点模糊查询
(括号边界)
参数编码字符串注入点模糊查询是一种安全漏洞,通常发生在应用程序接受用户输入,并将其作为模糊查询条件用于SQL语句中。在这种情况下,如果应用程序未对用户输入进行适当的处理和过滤,攻击者可能通过注入特殊字符来改变查询条件,绕过预期的过滤,导致数据泄露或非预期的查询结果。
示例代码:
假设应用程序使用以下后端查询语句来执行模糊查询:
SELECT * FROM vulin_users WHERE (username LIKE '%a%') AND (age > 20);
在该查询中,username
字段进行了模糊查询,查找包含字母a
的用户,同时筛选出age
大于20岁的用户。
攻击示例:
假设攻击者在输入中注入以下内容:
/*payload-1*/
') OR 1=1 --
/*payload-2*/
' OR 1=1) --
构建的查询将变成:
/*payload-1的SQL语句*/
select * from vulin_users where (username LIKE '%a') OR 1=1 --%') AND (age > 20);
/*payload-2的SQL语句*/
select * from vulin_users where (username LIKE '%a' OR 1=1) --%') AND (age > 20);
在这个恶意输入中,攻击者成功地在查询条件中添加了额外的条件 1=1
,并用注释符号--
来注释掉后面的部分。这将导致查询忽略原本的条件 (age > 20)
,并返回所有用户数据,因为 1=1
总是为真。
防御措施:
为了防止参数编码字符串注入点模糊查询漏洞,应该始终使用参数化查询或预处理语句,不要直接拼接用户输入到SQL查询中,并对输入进行严格的过滤和验证。在示例中,可以使用预处理语句来避免漏洞,例如:
# 假设username和age是从用户输入获取的值
username = request.form['username']
age = request.form['age']
# 使用预处理语句构建查询
sql = "SELECT * FROM vulin_users WHERE (username LIKE ?) AND (age > ?)"
cursor.execute(sql, ('%' + username + '%', age))
result = cursor.fetchall()
通过采取这些安全措施,可以有效地防止参数编码字符串注入点模糊查询漏洞,并保护应用程序和数据库的安全。
靶场演示:视频
Base64参数(JSON)嵌套字符串
注入点模糊查询(括号边界)
Base64参数(JSON)嵌套字符串注入点模糊查询是一种安全漏洞,通常出现在应用程序接受经过Base64编码的JSON格式参数,并将其作为模糊查询条件用于SQL语句中。攻击者可以通过注入特殊的Base64编码和JSON字符串来改变查询条件,绕过预期的过滤,导致数据泄露或非预期的查询结果。
示例代码:
假设应用程序接受经过Base64编码的JSON格式参数,并使用以下后端查询语句执行模糊查询:
SELECT * FROM vulin_users WHERE (username LIKE '%a%') AND (age > 20);
攻击示例:
假设攻击者将data
参数设置为以下Base64编码的JSON字符串:
#payload-1
eyJuYW1lYjY0aiI6IicpIE9SIDE9MSAtLSJ9
#payload-2
eyJuYW1lYjY0aiI6IicgT1IgMT0xKSAtLSJ9
解码后的JSON字符串为:
#payload-1
{"nameb64j":"') OR 1=1 --"}
#payload-2
{"nameb64j":"' OR 1=1) --"}
/*payload-1的SQL语句*/
select * from vulin_users where (username LIKE '%a') OR 1=1 --%') AND (age > 20);
/*payload-2的SQL语句*/
select * from vulin_users where (username LIKE '%a' OR 1=1) --%') AND (age > 20);
在这个恶意输入中,攻击者成功地在查询条件中添加了额外的条件 OR 1=1
,并用注释符号--
来注释掉后面的部分。这将导致查询忽略原本的条件 (age > 20)
,返回所有用户数据,因为 1=1
总是为真。
防御措施:
为了防止Base64参数(JSON)嵌套字符串注入点模糊查询漏洞,应该始终使用参数化查询或预处理语句,不要直接拼接用户输入到SQL查询中,并对输入进行严格的过滤和验证。
靶场演示:视频
结尾
SQL注入虽说是一种流行的攻击方法,但是通过采取适当的预防措施也是可以进行防范的。牛牛在每一种类型后都附上了具体的防御措施,师傅们可在靶场练习过程中同步收入备忘录。
下周Yak靶场系列将开启新类型教学——XSS多场景,长按文末二维码一键关注哦,敬请期待~
Loading...
安全实体转义
直接拼接导致XSS注入
不安全的过滤导致XSS
XSS: 存在于 JS 代码中(字符串中)
XSS: 存在于 JS 代码中(字符串中 2)
XSS: 存在于 JS 代码中(字符串模版中)
输出存在于HTML节点on...属性中
输出存在于HTML节点属性中,但是不再on属性中(IMG ALT)
END
更新日志
Yaklang 1.2.7-sp5
1. 修复 GBK 判断的时候数组索引越界的 Bug
2. 新增 DisableAutoEncode 接口(mutate)
3. Web Fuzzer 新增 Response 重新染色的功能
4. 优化 SSA 错误提示
5. 增加一些基础日志
6. 修复 Content-Type 在 multipart 中错误设置的问题
7. 修复端口扫描中的map的并发读写的 Bug
8. 修复代理认证的 Bug
9. 优化 MITM 性能,使用新的连接池
10. Fuzztag 重构后不再会失效了
11. 优化流量生成的接口
12. 实现自动解码的反向操作
Yak官方资源
Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ