让PHP以ROOT权限执行系统命令的方法


Posted in PHP onFebruary 10, 2011

用来作为解决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 
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命令了.

PHP 相关文章推荐
安装APACHE
Jan 15 PHP
PHP syntax error, unexpected $end 错误的一种原因及解决
Oct 25 PHP
php实现的遍历文件夹下所有文件,编辑删除
Jan 05 PHP
PHP--用万网的接口实现域名查询功能
Dec 13 PHP
PHP连接局域网MYSQL数据库的简单实例
Aug 26 PHP
分享一段php获取linux服务器状态的代码
May 27 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
Mar 19 PHP
PHP实现补齐关闭的HTML标签
Mar 22 PHP
php面向对象值单例模式
May 03 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
Aug 15 PHP
thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例
Aug 13 PHP
解决php扩展安装不生效问题
Oct 25 PHP
PHP开发中常用的字符串操作函数
Feb 08 #PHP
php提交表单时判断 if($_POST[submit])与 if(isset($_POST[submit])) 的区别
Feb 08 #PHP
php 数组的指针操作实现代码
Feb 08 #PHP
PHP游戏编程25个脚本代码
Feb 08 #PHP
PHP通用检测函数集合
Feb 08 #PHP
.htaccess文件保护实例讲解
Feb 06 #PHP
延长phpmyadmin登录时间的方法
Feb 06 #PHP
You might like
PHP与MySQL开发中页面乱码的产生与解决
2008/03/27 PHP
PHP查询网站的PR值
2013/10/30 PHP
PHP调用MySQL存储过程并返回值的方法
2014/12/26 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
解决laravel中日志权限莫名变成了root的问题
2019/10/17 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
Jquery遍历checkbox获取选中项value值的方法
2014/02/13 Javascript
详解页面滚动值scrollTop在FireFox与Chrome浏览器间的兼容问题
2015/12/03 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
使用jQuery判断浏览器滚动条位置的方法
2016/05/30 Javascript
JavaScript类的写法
2016/09/17 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
jquery广告无缝轮播实例
2017/01/05 Javascript
ES6新特性:使用export和import实现模块化详解
2017/07/31 Javascript
jQuery Ajax向服务端传递数组参数值的实例代码
2017/09/03 jQuery
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
下载糗事百科的内容_python版
2008/12/07 Python
transform python环境快速配置方法
2018/09/27 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
python把转列表为集合的方法
2019/06/28 Python
PyTorch在Windows环境搭建的方法步骤
2020/05/12 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
2020/12/10 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
波兰数码相机及配件网上商店: Cyfrowe.pl
2017/06/19 全球购物
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
来自世界上最好大学的在线课程:edX
2018/10/16 全球购物
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
德国W家官网,可直邮中国的母婴商城:Windeln.de
2021/03/03 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
商场活动策划方案
2014/01/24 职场文书
小学优秀班主任事迹材料
2014/05/17 职场文书
预防艾滋病宣传标语
2014/06/25 职场文书
旅行社优秀创业计划书
2014/08/16 职场文书
小学教师岗位职责
2015/04/02 职场文书
学校学期工作总结
2015/08/13 职场文书
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js