Mar 19

[原]在apache中运行root权限的CGI脚本 晴

linuxing , 11:16 , 网络服务 » 常见服务 , 评论(1) , 引用(0) , 阅读(52812) , Via 本站原创 | |

2、使用suidperl
suidperl是super user id perl的意思,也就是如果脚本拥有suid权限,则以该权限执行脚本。其使用参数与普通的perl命令相同。实际上,在现在的版本中,若脚本拥有suid权限,调用perl时会自动调用suidperl。
以红旗 Asianux 3.0 for x86为例,suidperl是作为一个单独的rpm存放的,如果你要使用它,请安装好:
引用
# rpm -qa|grep suidperl
perl-suidperl-5.8.8-10

◎ 编写一个suidperl脚本
# cat test.pl

#!/usr/bin/suidperl -w
$ENV{PATH}='/sbin;/usr/bin;/bin;';
print "From suidperl file test.pl:<br>";
my $HTML=qx(/usr/bin/id);
print $HTML,"<br>";
$HTML=qx(/sbin/iptables -L);
print $HTML;

权限:
引用
# chmod +x test.pl
# ll test.pl
-rwxr-xr-x 1 root root 229 03-17 13:09 test.pl

修改CGI脚本:

......
print "From CGI scripts:<br>";
my $HTML=qx(id);
print $HTML,"<br>";
#$HTML=qx(/var/www/cgi-bin/run_root);
$HTML=qx(/var/www/cgi-bin/test.pl);
print $HTML;
print "<br>End";

没有给test.pl赋予suid前,看看浏览器结果:
点击在新窗口中浏览此图片
不行吧。
还是给个suid权限:
引用
# chmod u+s test.pl
# ll test.pl
-rwsr-xr-x 1 root root 229 03-17 13:15 test.pl

再看看浏览器的结果:
点击在新窗口中浏览此图片
似乎可以了?

※ 注意,为安全起见,若要调用suid的脚本,perl会要求你设置$ENV{PATH}环境变量。否则会报错:
引用
[Tue Mar 17 12:35:09 2009] [error] [client 10.8.0.6] Insecure $ENV{PATH} while running setuid at /var/www/cgi-bin/test.pl line 3.

但仔细看看图中红色标记的地方,uid还是apache(48),而不是root(0),只有euid=0(root)。
这有问题吗?我们修改一下test.pl调用的root权限命令:

......
#$HTML=qx(/sbin/iptables -L);
$HTML=qx(/sbin/service proftpd restart);
print $HTML;

看看浏览器的结果:
点击在新窗口中浏览此图片
失败了!看看后台日志:
引用
From suidperl file test.pl:<br>uid=48(apache) gid=48(apache) euid=0(root) groups=48(apache)
<br>rm: 无法删除 “/var/run/proftpd.pid”: 权限不够
touch: 无法触碰 “/var/lock/subsys/proftpd”: 权限不够

关闭 proftpd:                                             [失败]
启动 proftpd:

虽然给test.pl赋予了suid权限,但suidperl执行时只是增加了euid的属性,执行用户仍是apache(48)。还不能完全实现root用户的操作。
(iptables -L检查的是euid,成功了。但service proftpd restart检查的是uid,失败了)
OK,在解决这个问题前,先来看看perl和suidperl是否有区别?

◎ 用perl替代suidperl
修改test.pl脚本:
# cat test.pl

#!/usr/bin/perl -w
$ENV{PATH}='/sbin;/usr/bin;/bin;';
print "From suidperl file test.pl:<br>";
my $HTML=qx(/usr/bin/id);
......

再看看浏览器显示:
点击在新窗口中浏览此图片
结果完全相同。证明perl与suidperl是通用的,实际上,perl的更新日志中已经表明,不建议使用suidperl,因为今后可能会去掉该命令。并且,当遇到suid权限的脚本时,perl会自动调用suidperl。

◎ 用euid替换uid
要解决上面的问题,方法与C写的程序相同,就是用euid替换uid。perl中$<表示执行文件的uid,$>表示执行文件的euid。
修改test.pl脚本:
# cat test.pl

#!/usr/bin/perl -w
print "From suidperl file test.pl:<br>";
print "Now:<br>";
print "\$< is uid :",$<,"<br>";
print "\$> is euid :",$>,"<br>";

$< = $>;
print "After put euid to uid:<br>";
print "\$< is uid :",$<,"<br>";
print "\$> is euid :",$>,"<br>";

$ENV{PATH}='/sbin;/usr/bin;/bin;';
my $HTML=qx(/usr/bin/id);
print $HTML,"<br>";

用浏览器看看:
点击在新窗口中浏览此图片
这次是真的成功了。虽然原理相同,但该方法不用借用第三方的代理,可扩展性和安全性都比方法一要好。
另外,还有朋友说可以用sudo来实现,我就没有再尝试,有兴趣的朋友可以试试。

◎ 源码
这次测试使用到的几个脚本:

三、安全问题
由于这个时候,在这个httpd服务上的CGI脚本运行时,apache是拥有系统root用户的所有权限的,可以进行任何的操作,包括破坏系统。所以,在传递参数给suid的程序时,务必检查信息来源、格式、操作等。
perl命令的-T参数相信会给您带来好建议,详细看看下面类似的安全控制:
Web基本窗体——安全性部分
四、参考资料
关于UNIX和Linux系统下SUID、SGID的解析
Perl Server Side CGI Scripting
内文分页: [1] [2]
Tags:
logicmd Email Homepage
2012/11/06 15:58
如果就my $HTML=qx(id);都permission deny怎么办?是apache配置错误么?
分页: 1/1 第一页 1 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]