kayush
kayush

Reputation: 111

Php exec() command not working on localhost

I am trying to create a file when a user submits a form, using
exec("sudo touch a.cpp") or die("Unable to create file)";
Output: Unable to create file

I have checked following answers:
1: sudo in php exec()
2: https://askubuntu.com/questions/139723/sudo-does-not-ask-for-password/139733#139733
3: https://askubuntu.com/questions/810462/nopasswd-option-not-working-in-sudo?noredirect=1&lq=1
4: also tried exec("echo <password> | sudo -S touch a.cpp");

Added www-data ALL=(ALL) NOPASSWD: /var/www/html/<project-folder> in visudo

Nothing seems to work.

Update: As mentioned in comment by @Rolfie using fopen() resolves this issue but still i am unable to use any command using exec(), for example compiling a file again shows same error.

Upvotes: 0

Views: 715

Answers (1)

confused
confused

Reputation: 149

You don't have to run as root! My answer below does not require you to give root permissions to www-data.

This works - I tested on Ubuntu 20.04 LTS Server August 2021.

Let's begin:

Create a "sudocmds.txt" and "results.txt" text files outside of the web root path i.e.

If your webroot is /var/www/html/ then place your text files in /var/www/cmds/

Set permissions on the files to www-data:

sudo chown www-data /var/www/cmds/sudocmds.txt
sudo chown www-data /var/www/cmds/results.txt

I'll use iptables as an example to show "iptables -L" via a button press:

Create a form:

<form method="post">
<input type="hidden" name="cmd"> <br>
<input type="submit" name="cmd" value="CMD";">
</form>

Use PHP code to write a "1" to the sudocmds.txt file when the 'CMD' button is pressed:

<?php 
  if(isset($_POST['cmd']))
      {
       $data=$_POST['cmd'];
       file_put_contents("../cmds/sudocmds.txt", "1");
       sleep(1);
       echo nl2br( file_get_contents('../cmds/results.txt') );
      }
?>

Now create a service to run on your host that will monitor the file and look for that 1 to appear then exec a command.

For this I will use inotify-tools as an example:

sudo apt install inotify-tools -y

Create the script:

sudo nano /opt/cmd-watcher.sh

#!/bin/bash

inotifywait -mqr -e close_write "/var/www/cmds/sudocmds.txt" | while read line
do
if grep -q 1 "/var/www/cmds/sudocmds.txt"; then
  sudo iptables -L > /var/www/cmds/results.txt
fi
done

Make the script executable

sudo chmod +x /opt/cmd-watcher.sh

Run the script in the background

sudo sh /opt/cmd-watcher.sh &

Now go to your webpage refresh it and press the button, you will see the results of the command appear after 1 second :)

I know it's a bit of a process but it means that you don't have to have the security risk of running commands as root with www-data.

Upvotes: 1

Related Questions