su部分帐户免密码切换
一、需求
最近业务部分希望在几百台主机上安装python expect包(pexpect),向其了解了下需求,其需求是通过4a审计平台登陆到他们业务的任一主机后(默认是user1 用户登陆),其希望可以在user1下执行某命令后,可以向user2、user3、user4几个用户免密切换,除此之外的其他用户不能切换。了解需求后,发现可以通过如下方法实现该需求:
- 通过expect(包括其他语言的衍生类)通过自动匹配并输入密码实现;
- 通过sudo配置NOPASSWD su实现(将需要切换的用户在sudo里配死);
- 通过OS底层函数进行uid、gid切换(需要s权限位配置和相关权限控制)
像expect、python、java、ruby等语言实现的expect的代码是不加密或编译后弱加密的,都可以读取源码后获取其密码内容。尽管shell 类语言也可以加密,但相对于更底层的语言c、c++、golang等编译出的二进制文件相比还是太弱鸡。所以本篇就以golang和c语言为例实现下这个需求。
二、golang expect实现
github上找了几个expect相关功能的模块,发现都不成功,后来找了一个可用的模块:github.com/ThomasRooney/gexpect ,具体代码如下:
1package main
2import (
3 "fmt"
4 gexpect "github.com/ThomasRooney/gexpect"
5)
6func main() {
7 child, err := gexpect.Spawn("su - zabbix")
8 if err != nil {
9 panic(err)
10 }
11 child.Expect("Password")
12 child.SendLine("zabbixpasswd")
13 child.Interact()
14}
上面并没有进行用户控制,如有需要可以使用os/user模块或syscall模块实现。这部分代码是以切换zabbix用户为例,如果需要匹配多个用户,可以通过switch……case语句实现。
虽然上面的代码实现了功能,但是副作用也比较大。比如:输入的命令会重复输出,ps执行不能全屏幕,无法 tab补全等。虽然后面也尝试和其他pty和term模块进行整合,但功力不够,并没有成功。
三、c语言实现
网上找了下su命令的源码看了下,发现其内部调用了两个头文件unistd.h和pwd.h ,前都用以实现uid、gid、euid、egid等的切换和调用(需s权限位),后都用于读取/etc/passwd文件,返回结构体中相关的值。由于unistd.h的帮助信息较多,这里只截取下pwd.h的相关帮助信息,如下图:
这里使用的getpwnam方法,用于匹配哪一个用户可以调用该程序实现用户功能切换,同上面golang一样,这里以只切换zabbix为例,需要匹配多个用户,可以通过switch……case语句实现。代码如下:
1#include
2#include
3#include
4#include
5int main(void)
6{
7 int current_uid = getuid();
8 printf("My UID is: %d. My GID is: %dn", current_uid, getgid());
9 system("/usr/bin/id");
10 if (setuid(0))
11 {
12 perror("setuid");
13 return 1;
14 }
15 struct passwd *pw;
16 pw = getpwnam("kiosk");
17 if(pw->pw_uid==current_uid){ //进行用户控制,只有kiosk用户可以执行切换
18 system("/usr/bin/su - zabbix");
19 }
20 return 0;
21}
可以使用如下命令进行编译和设置用户属性和s权限位:
1gcc -o setuid setuid.c
2chown root.root setuid
3chmod u+s setuid 或chmod 4755 setuid
pwd.h相关的用户可以参考如下两篇文章:
https://aljensencprogramming.wordpress.com/tag/etcpasswd/
https://www.adampalmer.me/iodigitalsec/2009/10/03/linux-c-setuid-setgid-tutorial/
后来查了下golang的手册,发现syscall 模块包中也包含有上面的相关方法,理论也可以实现以上功能。具体可以参考官方文档:
https://golang.org/pkg/syscall/
s权限位比较便利,但也比较危险,使用不当很容易被提权,所以系统下的很多安全工具,都会通过find 查看带有s 权限的文件。当然本篇实现的这个需求,也有一个好处,就是不论主机的其他用户的密码如何更换,都可以成功进行用户切换,这点其实和sudo实现的功能是类似的。
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/nopasswd-su/5929.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.