zoukankan      html  css  js  c++  java
  • 如何在Linux中临时获取超级用户权限,你还是只知其一不知其二吗

    大家好!我是Sean!

    好久没有出现了,今天讲下如何让我们的程序临时获取到root权限。

    前言

    首先熟悉两个个概念:权限位、用户。

    权限位

    Linux 将访问文件的用户分为 3 类,分别是文件的所有者(u),所属组(g)(也就是文件所属的群组)以及其他人(o)。并为 3 种不同的用户身份,分别规定了是否对文件有读(r)、写(w)和执行(x)权限。

    用户

    Linux系统中的用户分为超级用户(uid=0)和普通用户(uid=[500, 60000])以及系统用户(uid=[1, 499]),其中:
    超级用户拥有操作一切的能力。
    系统用户是Linux系统正常工作所必需的内建的用户,一般是用于管理服务所用。系统用户不能用来登陆,如bin、daemon、lp等用户。
    普通用户是为了让使用者能够使用Linux系统资源而建立的,用户新建的账号一般就是普通账号。

    因此

    出于安全考虑,程序在Linux系统中要求以普通用户身份运行,当然有些公司直接拿root跑程序,也不是不可以,只是root权限过于大,啥事情都能干,比如哪天手误脚本了写了个:

    rm -rf *
    

    说不定就把某些重要数据给删除了,甚至直接把自己的系统都给搞宕机,出现这种情况,不管是对公司还是对个人的损失都是巨大的。

    临时获取超级用户权限的两种方式

    方式一:sudo

    这中方式是针对shell命令或shell脚本,程序中通过sudo调用脚本达到临时获取root权限的效果,我们可以这么用:

    sudo hello_world.sh
    

    在没有做sudoers配置的情况下,使用sudo执行是需要输入root密码的,如果不想输入密码,可以在/etc/sudoers中配置脚本的全路径名称即可,调用时要用全路径:

    sudo /opt/Sean/hello_world.sh
    

    (关于sudoers的配置后续再出一篇文章详细讲解。)

    方式二:setuid

    说setuid前,有一个特殊的权限位不得不提一下,强制位(s权限),这个是我们实现临时获取root权限的关键。

    s权限

    s权限:设置使文件在执行阶段具有文件所有者的权限,相当于临时拥有文件所有者的身份. 典型的文件是passwd. 如果一般用户执行该文件, 则在执行过程中, 该文件可以获得root权限, 从而可以更改用户的密码。
    可以通过以下命令进行s权限设置:

    chmod 4755 hello_world
    或
    chmod u+s hello_world
    

    话不多说,show the code

    #include <iostream>
    #include <string>
    #include <unistd.h>
    
    using namespace std;
    
    int main()
    {
    	uid_t uid = getuid();
    	cout << "try to change: uid{" << getuid() << "} euid{" << geteuid() << "}" << endl;
    	// 任何用户执行时,都以setuid程序文件所属的用户的身份运行
    	if(setuid(0))
    	{
    		cout << "change failed: uid{" << getuid() << "} euid{" << geteuid() <<"}" << endl;
    		return -1;
    	}
    	cout << "change success: uid{" << getuid() << "} euid{" << geteuid() <<"}" << endl;
    	
    	// do what you want to do by root
    
    	setuid(uid);
    	if(getuid() == uid)
    	{
    		cout << "change back: uid{" << getuid() << "} euid{" << geteuid() <<"}" << endl;
    	}
    	
    	return 0;
    }
    

    运行效果

    [sean@CentOS code]$ g++ main.cpp
    [sean@CentOS code]$ ll
    total 20
    -rwxr-xr-x 1 sean sean 9104 Dec 31 10:50 test
    ---------- 1 sean sean  670 Dec 31 10:17 main.cpp
    [sean@CentOS code]$ ./test
    try to change: uid{1001} euid{1001}
    change failed: uid{1001} euid{1001}
    # 注:此时没有改为正确的权限,setuid会失败,切root修改权限
    [sean@CentOS code]$ su - root
    [root@CentOS code]# chown root:root test
    [root@CentOS code]# chmod 4755 test
    [root@CentOS code]# ll
    total 20
    -rwsr-xr-x 1 root root 9104 Dec 31 10:50 test
    ---------- 1 sean sean  670 Dec 31 10:17 main.cpp
    # 再以普通用户的身份运行程序
    [sean@CentOS code]$ ./test
    try to change: uid{1001} euid{0}
    change success: uid{0} euid{0}  #uid=0代表获取到了root权限
    change back: uid{1001} euid{1001}
    

    因为目的是临时获取root权限,所以注意做完想要的事情之后要把原来的用户身份恢复回来,这点千万要记得!不然你用ps命令查看进程的时候会发现,它的所属用户是root,会有安全隐患。

    以上就是在Linux中临时获取root权限的两种方式。

    今天就分享到这里啦!感谢各位的阅读!码字不易,如果本文对你有帮助的话,帮忙点个赞吧~

  • 相关阅读:
    I2C总线的设计
    注意: Cyusb2.0插在PC上的端口
    BULKTranfer
    浅析值类型与引用类型的内存分配
    sql server2008用ip远程连接,解决默认连不上的问题
    Decimal 结构
    单例模式 需要用showdialog 如果用show需要做如下改动
    NET4.0新功能之String.IsNullOrWhiteSpace() 方法
    SQLserver2008打不开的问题
    (C#)Winform修改DateTimePicker控件的背景色
  • 原文地址:https://www.cnblogs.com/ws007/p/14219476.html
Copyright © 2011-2022 走看看