我正在制作一个程序,它将运行PHP的人员C ++代码。如何安全地编译,运行,返回C ++程序的输出?我的意思是,如果不让我的系统容易受到黑客攻击,我该怎么办呢?我想我只是使用exec comman到GCC编译程序然后使用exec运行程序。但我怎么能这样做呢?
答案 0 :(得分:2)
对于非自定义服务器,您可以使用更高级的功能。最有可能的。因为大多数服务器提供商都不允许你执行进程,即使他们也不允许你在那里安装GCC并在他们的机器上运行可能不安全的代码(执行进程,还记得吗?)......
我想有一天会做这样的事情(有多语言编译器,沙盒,SVC等的在线开发工具),但仅仅因为我有很多空间以及我的普通计算机旁边的自定义服务器
如果您有自定义服务器(假设它是Linux,很可能是LAMP):
proc_open - http://php.net/manual/en/function.proc-open.php
答案 1 :(得分:1)
退房http://codepad.org,尤其是“如何运作”部分http://codepad.org/about
答案 2 :(得分:0)
检查this项目。简而言之,整个项目就是你想要实现的目标(我给你的svn子目录是你需要的沙箱部分。如果你想自己这样做,那么你应该从哪里开始:chroot。 如果您在Windows上,则需要严重依赖Windows API。搜索msdn。
答案 3 :(得分:0)
我以前做过,但是运行生成的二进制文件,它输出二进制文件作为下载。用户可以编译,但他们需要下载二进制文件并在其计算机中运行它。让用户在您的服务器上编译和运行任意代码是一个很大的漏洞IMO。
无论如何,这是我的快速实施:
<强>的index.php 强>
<?php
include 'compiler-gcc-mingw.php';
$docompile = intval($_REQUEST['docompile']);
if($docompile){
//compile
setUpDirectory();
compile();
if(IsError()){
//
cleanUp();
}
else {
getExecutable();
cleanUp();
downloadExecutable();
exit();
}
}
$defaultSource = "
#include <iostream>
using namespace std;
int main(){
cout<<\"Hello Word!\"<<endl;
getchar();
return 0;
}
";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Online C++ Compiler v1.0</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Online Compiler v1.0</h1>
<p>Online Windows C++ compiler using Mingw compiler </p>
<?php
if(IsError()){
$error = getError();
echo '<p><b>Compilation Error! Check your source code</b></p>';
echo '<p>'.$error.'</p>';
}
?>
<form name="compile" method="post">
<input type="hidden" name="docompile" value="1" />
<p><b>Source Code:</b></p>
<textarea name="source" rows="20" cols="80"><?php
if($docompile) echo stripslashes($_REQUEST['source']);
else echo $defaultSource;
?>
</textarea> <br />
<input type="submit" name="Submit" value="Compile">
</form>
</body>
</html>
<强>编译器GCC-mingw.php 强>
<?php
$dir = '';
$exeData;
$errorFlag;
$errorDetail = array();
function makeDir(){
//
global $dir;
$count = 0;
do{
$count++;
$dir = 'source/data'.$count;
}while(!@mkdir($dir));
}
function setUpDirectory(){
//make source dir : source001, source 002 etc
//make source file
global $dir;
makeDir();
$source = stripslashes($_REQUEST['source']);
file_put_contents($dir.'/source.cpp', $source);
}
function compile(){
// compile, get error message, assuming the compiler is in the system PATH
// cd to compile dir
global $dir;
$compileString = 'g++ '.$dir.'/source.cpp -o '.$dir.'/a.exe ';
global $errorFlag;
global $errorDetail;
$output = exec($compileString, $errorDetail, $errorFlag);
}
function isError(){
// if error return true
global $errorFlag;
return $errorFlag;
}
function getError(){
// get error detail
global $errorDetail;
$data = '';
foreach($errorDetail as $key=>$value){
$data .= $value.'<br />';
}
return $data;
}
function getExecutable(){
// retrieve exe data to memory
global $exeData;
global $dir;
$exeData = @file_get_contents($dir.'/a.exe');
}
function cleanUp(){
// delete all temporary files
global $dir;
$alist = scandir($dir);
foreach($alist as $key => $value){
if(is_file($dir.'/'.$value)) {
unlink($dir.'/'.$value);
}
}
rmdir($dir);
}
function downloadExecutable(){
// download to browser
global $exeData;
outputFile('program.exe', $exeData);
}
/**
* download content
* return value: false=cannot output the header, true=success
*/
function outputFile($filename, $data){
//Download file
if(ob_get_contents())
return false;
if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
header('Content-Type: application/force-download');
else
header('Content-Type: application/octet-stream');
if(headers_sent())
return false;
header('Content-Length: '.strlen($data));
header('Content-disposition: attachment; filename="'.$filename.'"');
echo $data;
}
?>
基本上它编译文本区域中编写的代码,将其保存到临时文件夹中的临时文件中,编译它(我使用mingw编译器),读取生成的二进制文件,删除所有临时文件(包括* .o和二进制* .exe文件)并将生成的二进制文件作为下载提供给用户。