Method to have PHP execute system commands as ROOT

  • 2020-03-31 21:29:55
  • OfStack

Used as a reference for PHP to root out commands or applications that ordinary users cannot execute.
The popen() function in PHP solves this problem, but some versions of Linux (such as Centos 5, which I use) have security concerns.
It makes the problem a lot more difficult to solve. Let's start with an example of a netizen using the popen() function.
 
 
$sucommand = "su root --command"; 
$useradd = "/scripts/demo/runscripts.php"; 
$rootpasswd = "louis"; 
$user = "james"; 
$user_add = sprintf("%s %s",$sucommand,$useradd); 
$fp = @popen($user_add,"w"); 
@fputs($fp,$rootpasswd); 
@pclose($fp); 

Through my own tests, it turned out that this piece of code didn't work (at least in my system) as the author wanted. After a long time at Google,
The point is that the su root command requires a password that must be entered terminally, not otherwise (I don't know of any).
Moreover, due to the requirements of the project, I could not use sudo, so I chose the method of writing C program proposed by netizens to solve this problem.
First write a C program named run.c under the directory /scripts/demo/
 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main() 
{ 
uid_t uid ,euid; 
//char cmd[1024]; // The variable is not currently in use  
uid = getuid() ; 
euid = geteuid(); 
printf("my uid :%un",getuid()); //This is the current uid that you can comment out.
printf("my euid :%un",geteuid()); //The current euid is shown here
if(setreuid(euid, uid)) //Exchange these two ids
perror("setreuid"); 
printf("after setreuid uid :%un",getuid()); 
printf("afer sertreuid euid :%un",geteuid()); 
system("/scripts/demo/runscripts.php"); //Execute the script
return 0; 
} 

Compile the file:
Gcc-o run-wall run.c
Under this path, the run file, the executable, is generated. If you call the run now with a PHP script, even setreuid won't work.
Next up: give run suid rights
# chmod u + s run
# the ls
# -rwsr-xr-x 1 root root 5382 Jul 2 21:45 run
Okay, so we've set it up, so let's write another PHP page and call it.
 
<?php 
echo '<pre>'; 
$last_line = system('/scripts/demo/run', $retval); 
echo ' 
</pre> 
<hr />Last line of the output: ' . $last_line . ' 
<hr />Return value: ' . $retval; 
?> 

Browse in a browser.
My uid: 48
My euid: 0
After setreuid uid: 0
Afer sertreuid euid: 48

--------------------------------------------------------------------------------
Last line of the output: afer sertreuid euid :48
--------------------------------------------------------------------------------
The Return value: 0
The command executed successfully.
The results show that apache (daemon) has a uid of 48 (in fact, many Linux daemons have a uid of 2).
The setreuid call interchanges the valid user id with the actual user id. Make apache's current uid 0 so that the root command can be executed.
All you need to do is change the command to be executed by the system in the C file to implement your own PHP to execute commands as root.

I played PHP for a while before I played C, and when I needed to run root in PHP, I failed until I found super.
As the days of playing C increased, I found that I could use C language to wrap the external commands I wanted to run.
You don't need any external tools to execute root commands in PHP.
I'm going to post the method to you, so you don't have to worry if you need to run root in PHP.
The current directory of iptables is /var/www. htm/http
Write with root
You know that iptables cannot be run without root.
First, write a C program
Name: ipt. C
 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main() 
{ 
uid_t uid ,euid; 
uid = getuid() ; 
euid = geteuid(); 
printf("my uid :%un",getuid()); //This is the current uid that you can comment out.
printf("my euid :%un",geteuid()); //The current euid is shown here
if(setreuid(euid, uid)) //Exchange these two ids
perror("setreuid"); 
printf("after setreuid uid :%un",getuid()); 
printf("afer sertreuid euid :%un",geteuid()); 
system("/sbin/iptables -L"); //Execute the iptables -l command
return 0; 
} 


Compile the file GCC -o ipt -Wall ipt. C
The ipt executable is generated under this path.
If you now call this ipt using a PHP web page, even the setreuid will not work.
The next thing to do is chmod u+s./ipt
Ls it
-rwsr-xr-x 1 root root 5382 Jul 2 21:45 ipt
The s bit is set.
Write another PHP page to call it.
 
<?php 
echo '<pre>'; 
$last_line = system('/var/www/html/http/ipt', $retval); 
echo ' 
</pre> 
<hr />Last line of the output: ' . $last_line . ' 
<hr />Return value: ' . $retval; 
?> 

Browse in a browser.

[color = Red] Chain INPUT (policy ACCEPT)
Target prot opt source destination
Chain FORWARD policy (DROP)
Target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
Chain the OUTPUT (the policy ACCEPT)
Target prot opt source destination [/color]
[color = Blue] my uid: 48
My euid: 0
After setreuid uid: 0
Afer sertreuid euid: 48 [/ color]

--------------------------------------------------------------------------------
Last line of the output: afer sertreuid euid :48
--------------------------------------------------------------------------------
The Return value: 0

The command executed successfully..
As we all know: apache has a uid of 48. Calling setreuid interchanges the valid user id with the actual user id.(only if chmod u+s is in effect) make apache's current uid 0 so that the root command can be executed.

You only need to change the command to execute system in the C file to implement your own PHP root command.

Related articles: