让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 相关文章推荐
PHP获取MAC地址的函数代码
Sep 11 PHP
PHP 获取文件路径(灵活应用__FILE__)
Feb 15 PHP
如何利用php array_multisort函数 对数据库结果进行复杂排序
Jun 08 PHP
简单实用的网站PHP缓存类实例
Jul 18 PHP
PHP SPL标准库之SplFixedArray使用实例
May 12 PHP
PHP生成器简单实例
May 13 PHP
PHP生成plist数据的方法
Jun 16 PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
Mar 01 PHP
php常用数组array函数实例总结【赋值,拆分,合并,计算,添加,删除,查询,判断,排序】
Dec 07 PHP
php批量删除操作代码分享
Feb 26 PHP
PHP 模拟登陆功能实例详解
Sep 10 PHP
PHP如何获取Cookie并实现模拟登录
Jul 16 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求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
JS清除IE浏览器缓存的方法
2013/07/26 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
2014/05/10 Javascript
Node.js中安全调用系统命令的方法(避免注入安全漏洞)
2014/12/05 Javascript
jQuery判断对象是否存在的方法
2015/02/05 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
react router 4.0以上的路由应用详解
2017/09/21 Javascript
nodejs爬虫初试superagent和cheerio
2018/03/05 NodeJs
世界上最短的数字判断js代码
2019/09/09 Javascript
使用Node.js在深度学习中做图片预处理的方法
2019/09/18 Javascript
谈谈IntersectionObserver懒加载的具体使用
2019/10/15 Javascript
微信浏览器左上角返回按钮监听的实现
2020/03/04 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
Vue2.0 ES6语法降级ES5的操作
2020/10/30 Javascript
Python读写Excel文件方法介绍
2014/11/22 Python
Python 获得命令行参数的方法(推荐)
2018/01/24 Python
浅谈关于Python3中venv虚拟环境
2018/08/01 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
python启动应用程序和终止应用程序的方法
2019/06/28 Python
Python类的动态绑定实现原理
2020/03/21 Python
Python 如何定义匿名或内联函数
2020/08/01 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
加拿大鞋子连锁店:Town Shoes
2016/09/26 全球购物
洛杉矶时尚女装系列:J.ING US
2019/03/17 全球购物
最新的小工具和卓越的产品设计:Oh That Tech!
2019/08/07 全球购物
人力资源部经理助理岗位职责
2014/03/04 职场文书
淘宝客服工作职责
2014/07/11 职场文书
2014年乡镇个人工作总结
2014/12/03 职场文书
2015年销售工作总结范文
2015/03/30 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
js前端图片加载异常兜底方案
2022/06/21 Javascript