Script added to sudoers.d is not executed as root

537 views Asked by At

On an xubuntu box, I have the following script to have PHP create directories owned by my user:

<?php
if(!isset($_REQUEST['path'])) die('No path specified');
$path = $_REQUEST['path'];
$res1 = shell_exec("sudo mkdir -p $path");
$res2 = shell_exec("sudo chown -R majid:majid $path");
var_dump($res1, $res2);
?>

The script is in /var/www/path/to/mkdir.php

I have also added this file to /etc/sudoers.d/grantmkdir with the following content:

www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/mkdir.php

I have chmoded the file to 0440 as well. Accessing the mkdir.php from the browser, the output is NULL NULL for the var dumps and no directory gets created. What am I doing wrong?

1

There are 1 answers

3
Lajos Veres On

Your setup is a bit confused.

When you access this script from your browser apache starts it with the www-data user.

Sudo isn't executed. You cannot make apache to call your scripts through sudo. You have to wrap your sensitive script into a sudo call.

For example this way:

Create two scripts. The first will be called by apache, and the second will be called by the first one through sudo.

first.php:

<?php
if(!isset($_REQUEST['path'])) die('No path specified');
$path = $_REQUEST['path'];
// By the way here you should verify the path! Otherwise malicious users can make your system execute whatever they want...
shell_exec("sudo /var/www/path/to/second.php " . $path);
?>

second.php

#!/usr/bin/php
<?php
shell_exec("sudo mkdir -p " . $argv[1]);
shell_exec("sudo chown -R majid:majid " . $argv[1]);
?>

And make second.php to be executable through sudo:

/etc/sudoers.d/second

www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/second.php

This way apache will start first.php which will start second.php using sudo.

You can test if sudo settings are working fine with logging into your server, switch to www-data (su www-data). And run the script manually.

A few side notes:

  • Checking the error logs will be probably useful. (tail /var/log/apache/error_log or stg similar)
  • Don't forget to validate your input, otherwise your system will be vulnerable. Details and solution to this problem: http://php.net/escapeshellarg
  • The NULL NULL can be normal. Details: http://php.net/shell_exec

Note:

This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution

failures using this function. exec() should be used when access to the program exit code is required.