首页
社区
课程
招聘
[原创]如果你的php程序要在服务器上进行一些高权限的操作咋办?来吧我教你用管到
发表于: 2016-5-25 20:55 4506

[原创]如果你的php程序要在服务器上进行一些高权限的操作咋办?来吧我教你用管到

2016-5-25 20:55
4506

php跟管道通信网上很少有,我探索了好几天
很多时候php需要在服务器上进行一些高权限的操作,比如网站后台管理启动停止Mysql服务,
显然这是很难用exec之类的函数实现的?而即使实现了,也很危险,容易被别人利用,因为exec它不知道你到底要做啥动作,那些命令都是字符串,不可能一个个排除。

这时你就得在服务器上运行一个管理员权限的程序,该程序建个管道,而php就跟该管道通信.

先看exe程序的源码,g_DataBuf是通信的数据,很重要

#include "stdafx.h"
#pragma warning(push)
#pragma warning(disable:4996)
#include<stdio.h>
#include <conio.h>
#include <stdlib.h>
#include<windows.h>
#define PIPE_SIZE 1024
LPTSTR g_pPipeName = L"\\\\.\\pipe\\phphelper";
char g_DataBuf[PIPE_SIZE]={0};//第一个字节为具体操作,第二个字节为0表示还有操作不能断开,为其他值表示当前可以断开连接
BOOL ProcCmd(HANDLE hpipe,char *pData);
//本程序为webserver上帮助php去执行一些权限操作的客户端。webserverhelp_S对应的服务端,执行本程序的命令
int _tmain(int argc, _TCHAR* argv[])//命令字符不超过8个
{
        HANDLE hPipe;
        PSECURITY_DESCRIPTOR psd;
        BOOL fConnected;
        DWORD dwRead;
        psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
        if(!psd)return -1;
    if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))  
    {  
        LocalFree((HLOCAL)psd);  
        return -1;  
    }
    if (!SetSecurityDescriptorDacl(psd, TRUE, (PACL)NULL, FALSE))  
    {  
        LocalFree((HLOCAL)psd);  
        return -1;  
    }
        SECURITY_ATTRIBUTES saAttr;  
    saAttr.nLength =sizeof(SECURITY_ATTRIBUTES);  
    saAttr.lpSecurityDescriptor = psd;  
    saAttr.bInheritHandle = TRUE;
        hPipe=CreateNamedPipe(g_pPipeName,   PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,   PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,   
                                                        1, PIPE_SIZE, PIPE_SIZE, 1000, &saAttr);
        LocalFree((HLOCAL)psd);  
        if (hPipe == INVALID_HANDLE_VALUE)
     {
          return -1;
     }
        fConnected=FALSE;
        while(1)
        {
                if(_kbhit())//ESC退出
                {
                        char ch;
                        ch=getch();
                        if(ch==27)break;
                }
                if(!fConnected)fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
                if (fConnected)
                {
                        if(ReadFile(hPipe, g_DataBuf, PIPE_SIZE, &dwRead, 0))
                        {
                                ProcCmd(hPipe,g_DataBuf) ;
                                if(g_DataBuf[1]){DisconnectNamedPipe(hPipe);fConnected=FALSE;}
                        }
                        else DisconnectNamedPipe(hPipe);
                }
                else Sleep(200);//等0.1s

        }
        CloseHandle(hPipe);  
        return 0;
}
BOOL StopMysql()
{
        char *pCmd="net stop mysql";
        int reslt;
        reslt=system(pCmd);
        if(reslt==0)return true;
        else return false;
}
BOOL StartMysql()
{
        char *pCmd="net start mysql";
        int reslt;
        reslt=system(pCmd);
        if(reslt==0)return true;
        else return false;
}
BOOL ProcCmd(HANDLE hpipe,char *pData)
{
        BOOL result;
        DWORD cbWritten;

        switch(pData[0])
        {
        case 1:
                result=StopMysql();
                break;
        case 2:
                result=StartMysql();
                break;
        default:
                result=true;
                break;
        }
        WriteFile(hpipe, (PVOID)&result, 1 ,&cbWritten,NULL);
        FlushFileBuffers(hpipe);
        return result;
}
#pragma warning(pop)

再看php这边的

$pipe =@fopen("//./pipe/phphelper", 'r+');
        if($pipe==false)
        {
                $retdata[1]='打开管道失败';
                return $retdata;
        }
        @fwrite($pipe,"\x1\x0");//stop
        $datapp=@fread($pipe,1);
        if($datapp!="\x1")
        {
                fclose($pipe);
                $retdata[1]='停止Mysql服务失败';
                return $retdata;
        }
        停止后进行其他操作
        @fwrite($pipe,"\x2\x1");//start
        $datapp=@fread($pipe,1);
        if($datapp!="\x1")
        {
                fclose($pipe);
                $retdata[1]='重启Mysql服务失败';
                return $retdata;
        }
        fclose($pipe);

转载请注名幽叶无情


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//