Je crée un programme qui exécutera un code C++ de PHP. Comment puis-je compiler, exécuter, retourner la sortie d'un programme C++ en toute sécurité? Par sécurité, je veux dire comment puis-je le faire sans rendre mon système vulnérable aux pirates? Je suppose que j'utiliserais juste le comman exec à GCC pour compiler le programme puis exécuter le programme en utilisant exec. Mais comment puis-je le faire en toute sécurité?Compiler, exécuter et retourner la sortie du programme C++, en toute sécurité à partir de PHP
Répondre
C'est quelque chose d'un peu plus avancé que quelque chose que vous seriez en mesure de faire avec un serveur non personnalisé. Probablement. Parce que la plupart des fournisseurs de serveurs ne vous laisseront pas exécuter des processus, et même si, ils ne vous laisseront pas installer GCC là-bas et exécuter du code potentiellement dangereux sur leur machine (processus d'exécution, vous souvenez?) ...
Je pensais de faire quelque chose comme ça (outils de développement en ligne avec des compilateurs multilingues, sandbox, SVC ...) un jour, mais juste parce que j'ai beaucoup d'espace ainsi qu'un serveur personnalisé juste à côté de mon ordinateur normal.
Si vous avez un serveur personnalisé (en supposant qu'il est Linux, et très probablement LAMP):
- ont gcc ou mieux encore g ++ installé
- ont une machine virtuelle (par exemple Bochs) installé, ainsi que d'une installation de base de toute Linux (autre plate-forme) - ce qui est juste pour C et D étapes
- mettre les fichiers sur un endroit temporaire
- utilisation proc_open pour démarrer le g ++ avec les fichiers répertoriés, mais assurez-vous d'exécuter cela comme un utilisateur dédié - par exemple gccuser - un utilisateur sans autorisations, mais à lire à partir du répertoire où les fichiers sont stockés
- A) lire la sortie (succès ou les erreurs/avertissements) de g ++
- B) permet à l'utilisateur de télécharger le fichier résultat
- C) mettre le fichier résultat par un éditeur de liens, puis écrire ce fichier sur le disque dur de la machine virtuelle - Puis exécutez-le, et vous pouvez montrer la sortie à l'utilisateur
- D) (le plus avancé) - faire une chose GUI (terminal) dans JavaSc ript/AS pour parler au fichier en cours en temps réel - ajouter une limite de temps ... ceci signifie cependant que vous avez besoin de plus d'un Bochs en même temps (plus d'utilisateurs) - cela signifie que vous devez copier un Bochs à une température répertoire, avec un disque dur vide (avec seulement OS), l'exécuter sur celui-là, lorsque vous avez terminé - supprimer
Même dans ce cas, ce n'est pas très sécurisé. – Gabe
Oui, je pensais juste à BOCHS ... Mais là encore, l'ajout d'une VM à tout le processus rend encore plus difficile l'installation d'un autre Linux sur la VM ... Le fait que cette VM peut être endommagée à tout moment - signifie la maintenir ... Hm ... Si je pense à ce sujet n'est pas si difficile juste garder un fichier de disque dur "vide" (juste installé par Linux) et toujours remplacer le fichier "usagé" par le fichier de sauvegarde lorsque vous avez terminé. Mais oh bien. C'est déjà quelque chose de très gros. –
Ajout de la VM ... –
Vérifiez this projet. En bref, ce projet entier est ce que vous essayez d'accomplir (et le svn subdir que je vous ai donné est la partie sandbox dont vous avez besoin.) Si vous voulez le faire seul, c'est ici que vous devriez commencer: chroot Si vous êtes sur les fenêtres, vous devez vous appuyer fortement sur l'API Windows.Recherchez msdn pour cela
Je l'ai déjà fait, mais à la place, le binaire qui en résulte sort le binaire en téléchargement. téléchargez le fichier binaire et exécutez-le dans leur ordinateur.Laisser les utilisateurs compiler et exécuter du code arbitraire sur votre serveur est une grande vulnérabilité IMO.
Quoi qu'il en soit, voici ma mise en œuvre rapide:
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>
compilateur gcc-mingw.php
<?php
$dir = '';
$exeData;
$errorFlag;
$errorDetail = array();
function makeDir(){
//
global $dir;
$count = 0;
do{
$count++;
$dir = 'source/data'.$count;
}while([email protected]($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;
}
?>
Fondamentalement, il compilez le code écrit dans la zone de texte, enregistrez-le dans un fichier temporaire dans un dossier temporaire, compilez-le (j'utilise mingw compi ler), lisez le binaire résultant, supprimez tous les fichiers temporaires (y compris * .o et les fichiers binaires * .exe) et offrez le binaire résultant en téléchargement à l'utilisateur.
consultez http://codepad.org, esp. la section "comment ça marche" http://codepad.org/about
- 1. Exécuter un programme à partir d'un programme C
- 2. Comment compiler et exécuter un programme Java?
- 3. Téléchargement d'images en toute sécurité avec PHP
- 4. Exécuter un programme externe à partir du code C#
- 5. Comment autoriser en toute sécurité les utilisateurs à exécuter du code Ruby arbitraire?
- 6. Comment exécuter un programme C à partir de VIM?
- 7. Php sortie de sécurité
- 8. Comment exécuter un script bash à partir du programme C++
- 9. retourner JSON et HTML à partir du script PHP
- 10. PHP popen et proc_open ne pas retourner la sortie binaire
- 11. Obtention d'événements à partir d'un thread en toute sécurité
- 12. encoder en toute sécurité et transmettre une chaîne d'un lien html au programme PHP
- 13. Sortie de tuyauterie du programme C dans le fichier (bash)
- 14. gcc compiler et exécuter l'habitude de bibliothèques MySQL C
- 15. en essayant de compiler mon programme C++.
- 16. exécuter javascript avant de retourner dans php
- 17. En écho en toute sécurité aux données MIDI en C#
- 18. contenu du répertoire de lecture en toute sécurité
- 19. Utiliser SciTE pour compiler/construire/exécuter un programme C
- 20. Servir le fichier via un script PHP et le remplacer en toute sécurité à la volée
- 21. exécuter php à partir de Java
- 22. objectif c xml compiler/exécuter
- 23. Quelle est la sortie de ce programme?
- 24. Comment retourner une chaîne à partir d'une fonction en PHP
- 25. Exécuter un programme C en python?
- 26. Exécuter un programme à partir de MemoryStream
- 27. C#: exécuter le programme de la console externe comme cachée
- 28. Comment faire une connexion TLS à partir de PHP sur un serveur web, et en toute sécurité
- 29. Comment compiler et exécuter un programme C/C++ sur le système Android (comme MinGW sur Windows)?
- 30. En toute sécurité en utilisant exec avec PHP pour lancer ffmpeg
Est-ce que votre question "comment laisser quelqu'un exécuter du code arbitraire sur votre machine en toute sécurité ?? – thetaiko
Tout ce qui est inférieur à la compilation et à l'exécution du code dans une machine virtuelle non connectée peut probablement être considéré »et« relativement dangereux ». Surtout si vous n'avez pas assez de connaissances techniques pour comprendre les étapes exactes nécessaires pour utiliser le sandbox avec une approche non-VM –