SQL注入-高权限注入(上)

数据库与网站的关系

在数据库中区分有数据库系统用户与数据库普通用户,二者的划分主要体现在对一些高级函数与资源表的访问权限上。直白一些就是高权限系统用户拥有整个数据库的操作权限,而普通用户只拥有部分已配置的权限。
网站在创建的时候会调用数据库链接,会区分系统用户链接与普通用户链接;当多个网站存在一个数据库的时候,root就拥有最高权限可以对多个网站进行管辖,普通用户仅拥有当前网站和配置的部分权限。所以当我们获取到普通用户权限时,我们只拥有单个数据库权限,甚至文件读写失败;取得高权限用户权限,不仅可以查看所有数据库,还可以对服务器文件进行读写操作。
 

多个网站可能共用同一个mysql服务器,关系图可能如下

高权限注入就是例如网站A含有SQL注入漏洞,那我们注入后通过MYSQL服务器不止能够访问数据库A还可以同时对数据库B进行查看,但前提是网站A使用的账号也就是访问的用户权限足够访问数据库B,一般是root权限等。

在上上个文章中有提到,在我们搭建的mysql数据库的服务器中包含4个数据库,分别数information_schema库,informance_schema库,mysql库,以及sys库,其中mysql库里就有保存我们用户的一些信息,包括能够访问的权限等。

MYSQL中存在4个控制权限的表,分别为user表,db表,table_priv表,columns_priv表

mysql权限表的验证过程为:
先从user表中的Host, User ,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证
通过身份认证后,进行权限分配,
按照user, db, tables_priv, columns_priv的顺序进行验证。
即先检查全局权限表user,如果user中对应的权限为v,则此用户对所有数据库的权限都为v,
将不再检查db,tables_priv,columns_priv:如果为N,则到db表中检查此用户对应的具体数据库,
并得到db中为Y的权限﹔如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。

接下来我们以版本为8.0.12的MYSQL进行操作

通过进入我们的数据库查询后发现有一个上面说的mysql库

接着我们使用mysql这个数据库,进入后查询发现了我们所说的user表,table_priv表,columns_priv表这四个表,如下图

首先我们要知道MYSQL的权限级别有哪些 

 MysQL权限级别分为:
全局性的管理权限:作用于整个MysQL实例级别
数据库级别的权限:作用于某个指定的数据库上或者所有的数据库上
数据库对象级别的权限:作用于指定的数据库对象上(表、视图等)或者所有的数据库对象

接下来我们查看mysql这个数据库中有哪些用户,语句为

select user,host from mysql.user;

从这个表可以看到表里一共有4个用户,其中包括我们用于登录的root这个用户,接下来我们来看看root这个登录账号有什么权限,即查看用户对应的权限,语句如下:

select * from user where user='root' and host='localhost' \G;

这下我们可以看到这个最高权限,root权限,基本上都是yes的,接下来我们创建一个普通用户来对比权限上的区别

有两种方式创建MySQL授权用户
        1.执行create user/grant命令(推荐方式)
        2.CREATE USER 'finley'@' localhost’IDENTIFIED BY 'some_pass ';通过insert语句直接操作MysQL系统权限表。                                                                         

这里我们以第二种方式来示例,解读为创建一个test1的用户,密码为12345

CREATE USER 'test1'@'localhost'IDENTIFIED BY '12345';

接下来我们重复之前的操作,查询mysql这个数据库中的用户有哪些,语句也就是和上面相同

select user,host from mysql.user;

这时候就发现多了一个test1的用户,接着我们查看一下test1这个用户的权限有哪些,语句相同

select * from user where user='test1' and host='localhost' \G;

发现test1这个普通用户的权限很低,什么都干不了,我们来验证一下是不是这样我们先退出当前的root用户,然后用下列语句登录我们的test1的普通用户

mysql -utest1 -p12345

发现我们访问不到任何数据库只能访问到它自带的information_schema这个数据库,这个默认有权限访问的数据库。接下来我们给test1这个用户赋予root的权限,即把普通用户变为管理员的语句:

GRANT ALL PRIVILEGES ON *.* TO 'test1 '@' localhost' WITH GRANT OPTION;

然后按上述查询权限语句,查看test1这个用户的权限有没有发生变化,发现test1这个用户的权限发生了改变,基本上都可以执行

然后我们退出root账户,登录test1账户,查看数据库,发现已经有权限可以查询到数据库了

如果想要删除用户,然后查询数据库中的用户,即删除用户语句如下

 drop user test1@'localhost';

我们还可以玩一点奇怪的,如果你只想赋予用户一点权限,但又不想赋予像root一样那么多的权限,假如我们创建一个test2用户,我们的数据库中有一个test数据库,里面有一张表叫做t1表,我们给test2用户查询test数据库中t1这张表的id的权限,即只提供id查询权限的语句如下:

grant select(id) on test.t1 to test2@'localhost' identified by '12345';

发现我们可以查询得到test这个数据库但却无法查询到所有有关t1的信息,这是因为我们前面设置了test2这个用户只能查看t1表中的id,不能看其他的,所以查询语句得改成:

select id from t1;

发现可以正常查询到id了

### SQL注入攻击与防御方法 #### 攻击方式 在DVWA (Damn Vulnerable Web Application) 中,SQL 注入漏洞存在于多个功能模块内。当应用程序未能正确过滤用户输入并将其直接拼接到SQL查询语句中时,就可能发生SQL注入。 例如,在登录表单处尝试提交如下用户名和密码组合: ```sql ' OR '1'='1 ``` 这将导致数据库执行条件始终成立的查询[^1]。 对于更复杂的场景,可以利用布尔盲注技术来逐位猜解出隐藏的信息。通过发送精心构造的数据包给服务器,并观察响应时间或页面返回内容的变化来进行判断[^2]。 #### 防御措施 为了防止SQL注入的发生,应该采取以下几种主要策略: - **参数化查询**:使用预编译语句代替字符串连接构建SQL命令。这样即使恶意代码被插入到变量之中也不会改变原有逻辑结构。 Python中的`sqlite3`库提供了这样的接口: ```python import sqlite3 conn = sqlite3.connect('example.db') cursor = conn.cursor() user_input = "some input" query = "SELECT * FROM users WHERE username=?;" cursor.execute(query, (user_input,)) ``` - **存储过程调用**:把业务操作封装成存储过程的形式,在应用层只负责传递必要的参数而不涉及具体语法细节。 - **最小权限原则**:确保用于访问数据库的应用程序账户仅具有完成其工作所需的最低限度权利;比如读取特定表格而不是整个数据库的所有对象。 - **输入验证**:严格限定允许接收字符集范围内的数据项长度以及格式等属性,拒绝不符合规则的内容进入后续处理流程之前就被拦截下来[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值