IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux应用程序动态更改用户ID -> 正文阅读

[系统运维]Linux应用程序动态更改用户ID

有时候为了系统安全,会将程序进行降权,但是当需要访问当前不允许访问的资源时,如何处理呢?那就是更改自己的用户ID或组ID,使新的ID具有合适的特权或访问权限,当处理完之后,再降低其特权,下面来介绍一下,如何在程序中动态修改程序的用户ID或组ID。

进程用户ID

首先,我们需要了解,一个进程相关联的ID有多少个,下面表格介绍:

ID作用
实际用户ID我们实际上是谁
实际组ID我们实际上是谁
有效用户ID用于文件访问权限检查
有效组ID用于文件访问权限检查
附属组ID用于文件访问权限检查
保存的设置用户ID由exec()函数保存
保存的设置组ID由exec()函数保存

另外,我们可以通过 getuid() 和 geteuid() 函数分别或者实际用户ID和有效用户ID,而设置用户ID我们是没有函数可以直接获取的。

动态更换用户ID

当我们在root用户下通过 chmod +s YourExe 命令给我们的可执行程序设置SUID位(“u+s”设置文件的用户ID位,“g+s”设置组ID位),这个时候,我们可以通过seteuid()函数暂时性的获得root权限。
测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/syscall.h>

int main(int argc, char *argv[])
{
	int fd;
	unsigned char *dev_name = "/dev/input/event0";

	printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());
	fd = open(dev_name, O_RDONLY);
	if (fd < 0)
		printf("open %s error,errno %d\n", dev_name, errno);
	else {
		printf("open %s ok\n", dev_name);
		close(fd);
	}

	/* 参数0是root用户ID */
	seteuid(0);
	printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());
	fd = open(dev_name, O_RDONLY);
	if (fd < 0)
		printf("open %s error,errno %d\n", dev_name, errno);
	else {
		printf("open %s ok\n", dev_name);
		close(fd);
	}

	/* 参数2是当前实际用户ID */
	seteuid(2);
	printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());
	fd = open(dev_name, O_RDONLY);
	if (fd < 0)
		printf("open %s error,errno %d\n", dev_name, errno);
	else {
		printf("open %s ok\n", dev_name);
		close(fd);
	}
}

默认的,我们user是没有 /dev 目录下节点的读取权限的,当我们去打开该节点时,将会出现报错说没有权限,但是,这个时候,如果通过 seteuid() 函数将有效用户ID设置为 root 用户(ID = 0),则可以正常访问 /dev 目录下的节点,当访问结束后,再通过 seteuid() 函数还原即可,注意,是 seteuid() 函数而不是 setuid() 函数。

实际上,上面示例在user用户环境的的工作步骤如下:

  1. 程序文件由root用户拥有且在设置用户ID位已设置,在user用户空间运行的,所以用户ID信息如下:

    实际用户ID = 我们的用户ID
    有效用户ID = 我们的用户ID
    保存的设置用户ID = root

    所以第一次open /dev 节点将会出现没有权限。

  2. 当调用 seteuid(0) 之后,由于我们已经设置了用户ID位,所以这种行为是允许的,用户ID信息将变为以下:

    实际用户ID = 我们的用户ID(未改变)
    有效用户ID = root
    保存的设置用户ID = root(未改变)

    由于当前有效用户ID为root,所以可以正常访问 /dev 节点。

  3. 当调用 seteuid(2) 降权之后,用户ID信息将变为以下:

    实际用户ID = 我们的用户ID(未改变)
    有效用户ID = 我们的用户ID
    保存的设置用户ID = root(未改变)

    降权后访问 /dev 将会无权限。

通过上述的配置,我们可以动态修改用户 ID,但是程序得到了额外的权限,编写这种程序时谨慎处理。

参考

《UNIX环境高级编程第3版》

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:22:28  更:2021-12-14 16:23:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 4:12:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码