Reputation: 111
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
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
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