Linux|系统管理|WEB开发

关注Linux,系统管理,WEB开发以及开源世界

和wirlfly讨论setuid的结论

| Comments

今天大半天和wirlfly在讨论setuid的问题,结论就看他的blog吧,我就偷懒剽窃他的帖子一次(也许会有很多下次的,呵呵)

一下是他的帖子的内容

在unix环境中setuid是一个很有创意的东西.善用者可以实现很多极其巧妙的东西,乱用者弄得系统千疮百孔.著名的缓冲区溢出攻击大多与其相关,因为setuid是基于提升权限的策略.

服务器管理员并没有给我配备root的密码.而/etc/sudoers里面虽然我在root组,但是次次在sudo的时候要输入长长的密码,很是麻烦, 或者干脆sudo vi /etc/sudoers,让组长看见了不好.呵呵.同时,对于shell内部命令,如cd之类的,sudo cd是不会成功的.虽然有其他的办法做到同样的功能,但是略显麻烦,因此想做一个setuid的shell,需要用内部命令的时候就用这个shell了.
藏好一点,或许组长不会知道.也不做什么坏事就是了.因此,测试开始了. 首先,代码a.c

1
2
3
4
5
6
7
void main()
{
 execl("/bin/sh","/bin/sh",(char*)0);
}
gcc -o a a.c
sudo chown root.root a
sudo chmod +s a

然后用非root帐号./a 然后出现$shell-version$whoami 居然得到的不是root. 立即man whoami,看看该命令是不是查看euid,结果whoami是查看euid.

后来想想莫非shell中执行进程时,进程只复制父进程的uid,而不是euid?忘记了,因此将execl中的命令写成了/bin/vi,结果还是不能打开诸如/etc/shadow,geteuid()一把之后,发现居然是540,而不是0.那么证明该策略行不通.

翻开apue,讲到的也只是为什么要用setuid()函数来改变setuid的程序的保存-设置-用户-id的重要性.这点理解起来不难,但是并没有解决我的问题.突然记起,好像哪本书上讲过,bash是一个安全shell,它对限制setuid程序有些特殊的操作.莫非是bash的原因? 因此,浏览了/bin目录,在/bin下面的sh是一个链接到/bin/bash的符号链接,而对于bash来说,是限制其自己的setuid执行的.所以直接使用另一个shell,/bin/ash,或者创建一个到ash的链接也可.

在程序中,改成execl("/bin/ash","/bin/ash",(char*)0),编译之后,设置属主权限,ok.
终于在whoami上是root了,同时cd /root是没有问题的.

说到此处,就不能不提臭名昭著的缓冲区溢出了,google缓冲区溢出,文章一大把,这里不再赘述.他的做法是将上面那段代码转成机器码之后放在堆栈桢上,当函数返回调用中断的地址时就执行了这段代码.因此大家窃取了root的euid了.

Comments