让PHP以ROOT权限执⾏系统命令的⽅法
⽤来作为解决php以root权限执⾏⼀些普通⽤户不能执⾏的命令或应⽤的参考。
其实php⾥的popen()函数是可以解决这个问题的,但是由于某些版本的linux(如我使⽤的Centos 5)对系统安全的考虑,
使得这个问题解决起来⿇烦了好多。先来看⼀个⽹友使⽤popen()函数的例⼦。
复制代码代码如下:
/* PHP中如何增加⼀个系统⽤户
下⾯是⼀段例程,增加⼀个名字为james的⽤户,
root密码是 louis。仅供参考
*/
$sucommand = "su root --command";
$useradd = "/scripts/demo/runscripts.php";
$rootpasswd = "louis";
$user = "james";
$user_add = sprintf("%s %s",$sucommand,$useradd);
$fp = @popen($user_add,"w");
@fputs($fp,$rootpasswd);
@pclose($fp);
经过⾃⼰的测试,证实此段代码是不能实现(⾄少在我的系统⾥是这样的)作者想要获得的结果的。经过⾃⼰很长时间的google之后,
问题的关键是su root这个命令需要的密码必须以终端的⽅式输⼊,不能通过其它的⽅式(我也不知道还有没有其它的⽅式)获得。
⼜由于项⽬要求不能使⽤类似于sudo这种应⽤,⽆奈之下,我选择了⽹友提出的⽤编写C程序的⽅法来解决此问题。
⾸先写个C程序,命名为:run.c 放在⽬录/scripts/demo/下
复制代码代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
uid_t uid ,euid;
//char cmd[1024]; //变量暂时未使⽤
uid = getuid() ;
euid = geteuid();
printf("my uid :%u\n",getuid()); //这⾥显⽰的是当前的uid 可以注释掉.
printf("my euid :%u\n",geteuid()); //这⾥显⽰的是当前的euid
if(setreuid(euid, uid)) //交换这两个id
perror("setreuid");
printf("after setreuid uid :%u\n",getuid());
printf("afer sertreuid euid :%u\n",geteuid());
system("/scripts/demo/runscripts.php"); //执⾏脚本
return 0;
}
编译该⽂件:
gcc -o run -Wall run.c
在该路径下⽣成run⽂件,这个可执⾏⽂件。如果现在⽤PHP脚本调⽤该run的话,即使setreuid了也是不⾏的。
接下来要做的是:给run赋予suid权限
# chmod u+s run
# ls
# -rwsr-xr-x 1 root root 5382 Jul 2 21:45 run
好了,已经设置上了,再写⼀个php页⾯调⽤它。
复制代码代码如下:
如何运行php项目<?php
echo '<pre>';
$last_line = system('/scripts/demo/run', $retval);
echo '
</pre>
<hr />Last line of the output: ' . $last_line . '
<hr />Return value: ' . $retval;
>
在浏览器中浏览。
my uid :48
my euid :0
after setreuid uid :0
afer sertreuid euid :48
--------------------------------------------------------------------------------
Last line of the output: afer sertreuid euid :48
--------------------------------------------------------------------------------
Return value: 0
该命令执⾏成功。
从显⽰结果可以看出: apache(daemon)的uid 为48(事实上很多linux系统下daemon的uid为2)。
调⽤setreuid后将有效⽤户id和实际⽤户id互换了。(必须在chmod u+s⽣效的情况下) 使apache当前的uid为0这样就能执⾏root 命令了。
只需要更改 C⽂件中的system所要执⾏的命令就可以实现⾃⼰的PHP以root⾓⾊执⾏命令了。
在玩C 以前玩过⼀段时间的PHP, 哪个时候需要⽤PHP 来运⾏root命令,⼀直未果,直到有⼀天搜索到了super这个插件.
随着玩C的⽇⼦多了.发现可以⽤C语⾔来包裹要运⾏的外部命令. 实验了⼀下.成功了.
不需要任何外部⼯具就可以实现⽤PHP 执⾏root命令.
我下⾯就把⽅法发布给⼤家,有需求⽤php来运⾏root命令的朋友可以不⽤发愁了.
平台:Linux. 实验命令iptables 当前的⽬录是/var/www/html/http
写程序的时候⽤root⽤户
⼤家都知道iptables ⾮root⽤户不能运⾏.
⾸先写个C程序
命名为:ipt.c
复制代码代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
uid_t uid ,euid;
uid = getuid() ;
euid = geteuid();
printf("my uid :%u\n",getuid()); //这⾥显⽰的是当前的uid 可以注释掉.
printf("my euid :%u\n",geteuid()); //这⾥显⽰的是当前的euid
if(setreuid(euid, uid)) //交换这两个id
perror("setreuid");
printf("after setreuid uid :%u\n",getuid());
printf("afer sertreuid euid :%u\n",geteuid());
system("/sbin/iptables -L"); //执⾏iptables -L命令
return 0;
}
编译该⽂件 gcc -o ipt -Wall ipt.c
在该路径下⽣成ipt 这个可执⾏⽂件.
如果现在⽤PHP⽹页调⽤该ipt的话,即使setreuid了也是不⾏的.
接下来要做的是chmod u+s ./ipt
ls ⼀下
-rwsr-xr-x 1 root root 5382 Jul 2 21:45 ipt
s位已经设置上了.
再写⼀个php页⾯调⽤它.
复制代码代码如下:
<?php
echo '<pre>';
$last_line = system('/var/www/html/http/ipt', $retval);
echo '
</pre>
<hr />Last line of the output: ' . $last_line . '
<hr />Return value: ' . $retval;
>
在浏览器中浏览.
[color=Red]Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT)
target prot opt source destination [/color]
[color=Blue]my uid :48
my euid :0
after setreuid uid :0
afer sertreuid euid :48[/color]
--------------------------------------------------------------------------------
Last line of the output: afer sertreuid euid :48
--------------------------------------------------------------------------------
Return value: 0
该命令执⾏成功..
众所周知: apache的uid 为48. 调⽤setreuid后将有效⽤户id 和实际⽤户id互换了.(必须在chmod u+s⽣效的情况下) 使apache 当前的 uid为0 这样就能执⾏root命令了。
⼤家只需要更改 C⽂件中的 system所要执⾏的命令就可以实现⾃⼰的PHP执⾏root命令了.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论