• Home
  • Uncategorized
  • Run a script as root from a php web user who does not have root privileges

Run a script as root from a php web user who does not have root privileges

Adapted from Stackoverflow

Solution using a binary wrapper (with suid bit)

1) Create a script (preferrably .sh) that contains what you want to be ran as root.

cat > php_shell.sh <<CONTENT
  #!/bin/sh
  /sbin/service sshd restart
CONTENT

2) This file should be owned by root, and since it will later run with root permissions make sure that only root has permission to write to the file.

chown root php_shell.sh
chmod u=srwx,go=xr php_shell.sh

3) To run the script as root no matter what user that executes it, we will need a binary wrapper. Create one that will execute our php_shell.sh.

cat > wrapper.c <<CONTENT
  #include <stdlib.h>
  #include <sys/types.h>
  #include <unistd.h>

  int
  main (int argc, char *argv[])
  {
     setuid (0);

     /* WARNING: Only use an absolute path to the script to execute,
      *          a malicious user might fool the binary and execute
      *          arbitary commands if not.
      * */

     system ("/bin/sh /path/to/php_shell.sh");

     return 0;
   }
CONTENT

4) Compile and set proper permissions, including the suid bit (saying that it should run with root privileges):

gcc wrapper.c -o php_root
chown root php_root
chmod u=srwx,go=xr,+s php_root

php_root will now run with root permissions, and execute the commands specified in php_root.sh.
If you don’t need to the option to easily change what commands that will be executed I’d recommend you to write the commands directly in wrapper.c under step 4. Then you don’t need to have a binary executing a external script executing the commands in question.

In wrapper.c, use system ("your shell command here"); to specify what commands you’d like to execute.

New script without wrapper:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>

void ExecAsRoot (char* str);
int main ()
{
  setuid (0);
  setvbuf(stdout, NULL, _IONBF, 0);
  printf ("Host real ip is: ");
  ExecAsRoot("ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/'");
  ExecAsRoot("/usr/sbin/service tor restart");
  sleep(2);
  printf ("Tor should have switched to a new ip by now.\nNew ip is: ");
  ExecAsRoot("torify curl ifconfig.co 2>/dev/null");
  setvbuf(stdout, NULL, _IONBF, 1);
  return 0;
 }

void ExecAsRoot (char* str) {
  system (str);
}

/*  Additional things to do:
Compile:
gcc restartor.c -o restartor

Set permissions:
chown root restartor
chmod u=srwx,go=xr restartor

Prevent a folder wide permission change to affect this:
chattr +i restartor

*/