Crie um script que implemente os comandos descritos e execute setuid
para permitir que ele seja executado como root quando alguém o invocar. Consulte o link para obter mais informações sobre o setuid.
A partir do PHP, você pode simplesmente chamar system('/bin/setupNewUser');
como de costume e o script será executado como root.
Solução alternativa que limita as oportunidades de injeção e funciona em sistemas com execução setuid em scripts desativados:
Crie um pequeno programa que tenha setuid. Um exemplo listado abaixo:
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cout << "Invalid arguments";
return 1;
}
//make sure the argument passed to the script has only [a-z]
for (char* i = argv[1]; *i != 'system('/test/setupUser '.escapeshellarg($username));
'; i++)
{
//check if the current character falls outside an allowed range
if (!(
//Allowed ranges:
// between a and z
('a' <= *i && *i <= 'z')
// between 0 and 9
|| ('0' <= *i && *i <= '9')
// '_' or '-'
|| ('_' == *i)
|| ('-' == *i)
))
{
cout << "Illegal character in username: " << *i << endl;
return 2;
}
}
//append the username
string command = string("/test/setupUser.sh ");
command += string(argv[1]);
//execute the command and return the result transparently
// return system(command.c_str());
// * OR *
// call mkdir directly
}
Chame o programa setuid do php
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cout << "Invalid arguments";
return 1;
}
//make sure the argument passed to the script has only [a-z]
for (char* i = argv[1]; *i != 'system('/test/setupUser '.escapeshellarg($username));
'; i++)
{
//check if the current character falls outside an allowed range
if (!(
//Allowed ranges:
// between a and z
('a' <= *i && *i <= 'z')
// between 0 and 9
|| ('0' <= *i && *i <= '9')
// '_' or '-'
|| ('_' == *i)
|| ('-' == *i)
))
{
cout << "Illegal character in username: " << *i << endl;
return 2;
}
}
//append the username
string command = string("/test/setupUser.sh ");
command += string(argv[1]);
//execute the command and return the result transparently
// return system(command.c_str());
// * OR *
// call mkdir directly
}