PHP shell exec help

DangerIsGo

2[H]4U
Joined
Apr 16, 2005
Messages
3,000
Last thing. Then my scripts are finally completed. I cannot get this to work for the life of me and I don't know why.

I have this line in my PHP code:

Code:
exec("sudo /bin/changeme");
exec("sed -i \"s/$username $oldpwhash/$username $newpwhash/\" <file>")

It doesnt work. I put this line in a new php file..just this line:
Code:
exec("sudo /bin/changeme");

and it works. /bin/changeme is a script to chmod 777 a file.

Anyone know why this would happen? Why would it not execute where I need it to and not where I dont want it to? Anyone know how to execute another PHP file from a PHP file?
 
Anyone know how to execute another PHP file from a PHP file?

Shell execs can be dangerous when coming from an untrusted space like the WWW.

But to execute another php file, just go:

exec("/usr/local/bin/php /var/www/html/execute_me.php");

I haven't tried this recently - so try it from a command line first. If there is any output returned, add > /dev/null to the end of the command...

alternately, you can use wget to 'execute' the other webpage (and again pipe the output to /dev/null or whatever)

also, it was probably just a cut/paste error, but don't forget to end each line with a ; (your second line of code)
 
Nope, For some reason, my PHP wont let me execute using the exec, shell_exec or popen. I cant run another php script that way..any ideas?
 
Are you using shared hosting or is this your own server?

Apache also has a command to execute shell commands -

If this is shared hosting, any ability to execute shell commands will be disabled. However, you can 'include' or 'require' another php page to cause it to be executed - just make sure that the included page doesn't generate unwanted output / or throw it into a layer/frame/table that is off the screen.
 
This is my own apache2 server. The files are executable php scripts with HTML forms inside (text boxes, and submit button) Whats the apache thing to execute shell commands?
 
Something else just dawned on me...

when you use the PHP shell exec command, you must specify the shell interpretter on the first line:

#!/usr/local/bin/php

if you want the contents to be directly parsed by php

but more likely, you want it parsed by:

#!/bin/sh
If the contents of the file include:
/usr/local/bin/php /var/www/html/execute_me.php



But your current question: executing commands with apache:

<pre>
<!--#exec cmd="ls" -->
</pre>

This would output the current directory. Change cmd to your command.

Also, browse through your apache.conf. You must change:
<Directory /foo>
Options +IncludesNOEXEC
</Directory>

to

<Directory /foo>
Options +Includes
</Directory>

(I believe - see apache.org to verify)



Possibly useful
 
Where do I put

<pre>
<!--#exec cmd="ls" -->
</pre>

Do i put thaton the 1st line or do I replace shell_exec with that?
 
you can put it anywhere.

Just don't put it inside of <?php ?> tags because you don't want PHP to parse it...

Test it out in a temp.html page to see how it works.
 
And your apache.conf has been edited to allow you to use that command?

You might consider copying/pasting the code in your temp.html and the file that you are attempting to execute.
 
Yes

Huh??


you can put it anywhere.

Just don't put it inside of <?php ?> tags because you don't want PHP to parse it...

Test it out in a temp.html page to see how it works.



And your apache.conf has been edited to allow you to use that command?

You might consider copying/pasting the code in your temp.html and the file that you are attempting to execute.




i.e., lets see the changes you made to your httpd.conf, the contents of your temp.html (does the command "ls" even work yet?) and the contents of the php file you are attempting to execute.

Also, anything in your syslog?
 
I changed this:

<Directory "/usr/share/apache2/error">
AllowOverride None
Options Includes
AddOutputFilter Includes html
AddHandler type-map var
Order allow,deny
Allow from all
LanguagePriority en es de fr
ForceLanguagePriority Prefer Fallback
</Directory>

the Options to Includes

and this is my whole php (HTML included)
Code:
<pre>
<!--#exec cmd="sudo /bin/changme" -->
</pre>

<?php

//Original code by Stargate_God
$username = (isset($_POST['name']))?$_POST['name']:"";
$oldpw = (isset($_POST['oldpw']))?$_POST['oldpw']:"";
$newpw = (isset($_POST['newpw']))?$_POST['newpw']:"";
$confpw = (isset($_POST['confpw']))?$_POST['confpw']:"";
$act = (isset($_POST['submit']))?$_POST['submit']:"";
$userfail = $pwmismatch = $pwfail = $pwlengthfail = "0";

if($act == "Submit")
{	
	if(!($newpw == $confpw)){$pwmismatch="1";}
	if(strlen($newpw) <4 or strlen($confpw)<4){$pwlengthfail="1";}
	
	if ($pwlengthfail == 0 and $pwmismatch == 0) {

	$link = mysql_connect ('localhost', 'blah', 'blah') or die(mysql_error());
	if(!$link){die("Could not connect to MySQL server: " . mysql_error());}
	$currdb = mysql_select_db ('blah', $link);
	if(!$currdb){die("Could not connect to database: " . mysql_error());}
	
	$table = 'regusers';
	$u = strtolower($username);
	$sql = "SELECT password, confirmed, salt FROM $table WHERE username='$u';";
	$query = mysql_query($sql);
	if(!$query){echo ("Invalid username");exit;}
	$found = mysql_fetch_array($query);
	$password = $found[0];
	$confirmed=$found[1];
	$pwsalt = $found[2];
	
	$oldpwhash = crypt($oldpw, $pwsalt);
	
	if(!($oldpwhash == $password)){$pwfail="1";}
	
	if ($pwfail == 0) {
	
	$saltchars = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$salt = "";
	for($i=0;$i<8;$i++){
		$r = rand(0,strlen($saltchars)-1);
		$salt = $salt . $saltchars[$r];}
	$salt = "\$1\$".$salt."\$";
	$newpwhash = crypt($newpw, $salt);

	if ($confirmed==1){
	//Edit reglist here with $username, $newpwhash and possibly $oldpwhash
	#shell_exec("sudo /bin/changeme");
	exec("sudo /bin/changeme");
	echo "I'm in.<br />";
	shell_exec("sed -i \"s/$u $oldpwhash/$u $newpwhash/\" /home/dangerisgo/.dbhub/reglist");
	}
	
	$sqlchange = "UPDATE $table SET password='$newpwhash', salt='$salt' WHERE username='$u';";
	$querychange = mysql_query($sqlchange);
	if(!$querychange){print(mysql_error());print("<br /><br />");}	
	echo "Password change successful.<br />";exit;}
	else {echo "Invalid Password.  Please try again.<br />"; exit;}
	} else {
	if($pwmismatch==1){echo "Your new password and password confirmation do not match.<br /> ";exit;}
	else if($pwlengthfail==1){echo "Please enter a new password of at least 4 characters.";exit;}
	}
}

?>

<form action="/change.php" method="POST" name="changepw">
	<font color="FF0000" ><strong>Password Change Form</strong></font></td>
  <table width="275" border="0">
  <tr>
    <td width="124"><font face="Verdana">Nickname:</font></td>
    <td width="151"><input name="name" type="text" size="25"  maxlength="50" value="" /></td>
  </tr>
  <tr>
    <td><font face="Verdana">Old Password:</font></td>
    <td><input name="oldpw" type="password" id="oldpw" value="" size="25" maxlength="64" /></td>
  </tr>
  <tr>
    <td><font face="Verdana">New Password:</font></td>
    <td><input name="newpw" type="password" id="newpw" value="" size="25" maxlength="64" /></td>
  </tr>
  <tr>
    <td><font face="Verdana">New Pass Confirm:</font></td>
    <td><input name="confpw" type="password" id="confpw" size="25" maxlength="64" value="" /> </td>
  </tr>
    <td><input name="submit" type="submit" value="Submit" /></td>
    <td></td>
  </tr>
</table>
</form>
<br />
<font face="Verdana"><strong>NOTE</strong>: New accounts will <strong>NOT</strong> be active until confirmation e-mail is sent.<br />
<a href="/confirm.html">Click here for instructions to confirm your account.</a><br /></font>

THats my whole code

I changed this

$blah = exec("ls");
echo $blah;
and i got an output of step4.jpg, a picture in the /var/www folder
 
<Directory "/usr/share/apache2/error">

Find the directory tag for your /var/www/html directory (or wherever your html files live).

Make the change there...
 
In httpd.conf

There are many <directory tags.

Only edit the one for /var/www
 
there is on in httpd.conf in the apache folder (a level up)

/etc/apache/httpd.conf has /var/www directory in it

while

/etc/apache2/apache2.conf has no /var/www/ in it
 
apache2.conf must be your global settings and httpd.conf is your local settings for that particular website.

So go ahead and edit it in your httpd.conf (and undo the change you did to apache2.conf since you don't want people to execute random code from your apache error directory).

I did mention that allowing PHP to execute shell scripts is a bad idea, right? I just want to make sure I mentioned that.
 
That's fine. apache2 still uses httpd.conf as far as I know. (I've been working in the IIS world for the last 2 years, but I was a die hard *nix software engineer for five years before that)

It sounds like you might need some telephone help, remote help or one-on-one help.

Just for fun I setup apache2 in a vmware image (Ubuntu) on my machine just now. I tried executing a shell script using both the apache method and the php shell exec method and both worked perfectly!

Remember, start small. See if you can execute 'ls' before going on to the next step.
 
Wait,
I have another script called pop3.php and it has this in it:

shell_exec("sudo /bin/changeme");

And it works..theres nothing extraneous in the php, just that and it works...it asks me for the sudo password though :( when i do php -f pop3.php. Why does that exec work in that php but not the other one?
 
Wait,
I have another script called pop3.php and it has this in it:

shell_exec("sudo /bin/changeme");

And it works..theres nothing extraneous in the php, just that and it works...it asks me for the sudo password though :( when i do php -f pop3.php. Why does that exec work in that php but not the other one?

is php in your path? sudo is for sure, but I'm doubtful that php is...
 
What you mean, in my path? I have another php file in /var/www and when i activated that with php -f pop3.php, it was able to do the

exec("sudo /bin/changeme");

part of the code that was in the php file

I had to enter the sudo password though, could you think thats the problem?

When change.php (what im working on now, and what was posted before) is activated, no sudo password is entered, it is activated by the user clicking submit.
 
sorry, I forgot about your thread!


When you type sudo, your shell will look in the current working directory for a program called sudo. (some exceptions to this rule). Then it will check /bin /sbin /usr/bin /usr/sbin, etc - it goes through all the paths in your "PATH" environment variable.

Now, when you type php from a normal shell, it executes php.

That is because when you open a shell, /usr/local/bin/ (or wherever php is installed to) is in your path.

But when APACHE executes a php file, it is running in a new environment with a more restricted path. So when apache parses your php file, that works fine. But now, inside that php file, you are attempting to execute another php file. It is possible that the folder that contains the php binary is not in your path in this context.

So, you need to fully qualify it.

First, figure out where php is. (whereis php) or just ls /usr/local/bin and see if it's there.

Now change your command in the php from:

exec("php /bin/changeme/blah.php");
to
exec("/usr/local/bin/php /bin/changeme/blah.php");

Same with the sed command that is failing - figure out where the sed binary is and directly call it.

/usr/bin/sed ....
 
Back
Top