Php shell_execute not working - php

I have a problem that i can't to shell_exec(), but it just won't work. Is there a problem whit shell_exec() or it just cant run myfile.sh somehow..
If i run code in shell it works fine. My php wont run in safe mode, i did check it from php.ini file and i did check disable_functions aswell.
My php code returns right now just null. And i did try also for testing purpose :
$result = exec('myfile.sh', $output, $status);
i got :
array(0){}int(127)
Both files have chmod 775 read and execute premissions.
I have file message.php what looks like
<?php
$user = "username";
$pass = "pass";
$from = "from who";
$to = "1234567";
$msg = "test message";
$host="https://web.myurl.ee:portnr/etc/etc";
$handle = curl_init($host);
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_exec($handle);
$res = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($res >= 400){
exit;
}else if($res < 200){
exit;
}else{
if(function_exists('shell_exec') && !ini_get('safe_mode')){
$file = 'myfile.sh';
if(file_exists($file)){
$result = shell_exec($file ."$user $pass $from $to $msg");
var_dump($result);
}else{
echo "No files";
}
}else{
echo "check status";
}
}
?>
and myfile.sh file looks like
#!/bin/sh
if [$# -ne 5 ]; then
echo"jahas"
exit 1
fi
etc...
What i miss here, any tips what to look or what to do for next.
In code can be some mistypes, i didn't copy paste it.

Two things to check here:
First determine if exec and shell_exec are disabled in php.ini
disable_functions = exec
exex() accepts commands and no files if i am not mistaken so instead of simply adding the file name you should try:
exec(dirname(FILE) . '/myfile.sh');
Using the right directory and actually passing a command and not a file name.

You can use either an absolute path or a relative path. For relative paths, the current directory is usually the PHP files's. If you can't access your scripts even with an absolute path, there could be a problem with filesystem access rights. Keep in mind PHP scripts are typically executed as the web server's (system) user account.
Your shell scripts should be stored somewhere near or inside your application tree, so that you can grant acces to them to your PHP scripts (i.e. to your web server), without compromising too much your file system security.

Related

shell_exec() always returning an empty string

I am trying to create a server within my Android phone. I am unable to execute any shell script from my PHP code.
Here's the code:
//index.php
<?php
$output=shell_exec("sdcard/htdocs/myscript.sh 2>&1");
if(!$output){
echo "Failed";
}else{
echo $output;
}
?>
//myscript.sh
cd sdcard/htdocs/images
ls -t1 | head -n 1
The script works fine within terminal emulator. I also tried changing permissions of the script file but that didn't work. I don't know if it requires superuser permissions to execute shell scripts within PHP code.
The whole code is used to return the filename of the last file created in the images directory.
Need suggestions to make this code work.Is there any other way to perform the required job?
Make sure what you have run
chmod a+x sdcard/htdocs/myscript.sh
on your file.
Also $output is not a boolean.
Your code looks fine. Superuser permission is not necessary for script execution. You should turn on PHP error output or check the PHP error log file. I bet you find the reason there. If not, recheck the directory, and file permissions:
./index.php
./sdcard/htdocs/myscript.sh
./sdcard/htdocs/images
sdcard and sdcard/htdocs require executable persmissions. sdcard/htdocs/images requires executable and read permission (ls in myscript.sh), and so does sdcard/htdocs/myscript.sh. But I guess it's something else because permission errors should be displayed (2>&1).
Edit
You can find the last modified file with PHP, no need to run another process. Take one of these two:
$images = glob('sdcard/htdocs/images/*');
$images = array_combine(array_map('filemtime', $images), $images);
asort($images);
echo $lastModifiedImage = end($images);
Or with some fewer array operations:
$images = glob('sdcard/htdocs/images/*');
array_reduce($images, function($previous, $element) use (&$found) {
$mtime = filemtime($element);
$found = $previous < $mtime ? $found : $element;
return $previous < $mtime ? $mtime : $previous;
}, 0);
echo $found;
sdcard and sdcard/htdocs require executable persmissions. sdcard/htdocs/images requires executable and read permission (ls in myscript.sh), and so does sdcard/htdocs/myscript.sh. But I guess it's something else because permission errors should be displayed (2>&1).
Probably FAT !

Finding correct of PHP binary - exec()

I'm trying to execute a separate PHP script from within a PHP page. After some research, I found that it is possible using the exec() function.
I also referenced this SO solution to find the path of the php binary. So my full command looks like this:
$file_path = '192.168.1.13:8080/doSomething.php';
$cmd = PHP_BINDIR.'/php '.$file_path; // PHP_BINDIR prints /usr/local/bin
exec($cmd, $op, $er);
echo $er; // prints 127 which turns out to be invalid path/typo
doSomething.php
echo "Hi there!";
I know $file_path is a correct path because if I open its value; i.e. 192.168.1.13:8080/doSomething.php, I do get "Hi there!" printed out. This makes me assume that PHP_BINDIR.'/php' is wrong.
Should I be trying to get the path of the php binary in some other way?
The file you are requesting is accessible via a web server, not as a local PHP script. Thus you can get the result of the script simply by
$output = file_get_contents($file_path);
If you however for some reason really have to exec the file, then you must provide a full path to that file in your server directory structure instead of server URL:
$file_path = '/full/path/to/doSomething.php';
$cmd = PHP_BINDIR.'/php '.$file_path;
exec($cmd, $op, $er);

Python called from PHP but SQLite3 not working

I have this PHP script:
<?php
if($_GET["name"] != null && $_GET["name"] != ""){
$name = urlencode($_GET["name"]);
$name = htmlentities($name);
$title = urlencode($_GET["title"]);
$title = htmlentities($title);
$art = urlencode($_GET["art"]);
$art = htmlentities($art);
$output = array();
exec("python add.py $name $title $art",$output);
}
?>
and here's the add.py file:
import sys
import sqlite3
name = sys.argv[1]
title = sys.argv[2]
art = sys.argv[3]
tup = (name,title,art)
conn = sqlite3.connect('arts.db')
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS arts(name,title,art)')
c.execute('INSERT INTO arts VALUES(?,?,?)',tup)
conn.commit()
conn.close()
When the file runs there is no arts.db file in my current directory. Not only that, when I debugged my program by adding print statements every here and there I realised that my program runs till conn = sqlite3.connect('arts.db') and then exits before the statement is executed.
There is no error in my program because I used the python editor in the terminal (I use Ubuntu) and then I could execute this program successfully but this doesn't happen when I execute this from the PHP script.
If you're trying to reference an existing arts.db file, which is not in the current directory when the PHP script runs, then it's probably easiest to refer to the file by its full path, i.e. change the line...
conn = sqlite3.connect('arts.db')
...to something like...
conn = sqlite3.connect('/the/full/path/to/arts.db')
If you're trying to create a new arts.db, it's highly probable that the webserver process doesn't have permission to create the file in the current directory when the PHP script runs.
It's probably safer not to give PHP permission to write to the directory containing the PHP script[s], so create a directory somewhere else to store the file, give it the appropriate permissions, and use the full path to that directory in the script.
Update
i have figured out that i dont have permissions to write hence i
created a db using another program and created a table in it but still
for inserting values into it i require permissions, can you tell me
how to do that?
Problem is that any process spawned by the PHP script will inherit the permissions from the parent process, and will have the same limitations.
On recent versions of Ubuntu, the /var/tmp directory can always be written to by any user, so you could put it there with...
conn = sqlite3.connect('/var/tmp/arts.db')
...or you can put it anywhere else by modifying the permissions, with...
$ sudo chgrp www-data /the/full/path/to/directory
$ sudo chmod g+ws /the/full/path/to/directory
Of course, this means there's not much point in using a seprate Python script, so you may as well do it all in PHP.

Cron jobs help

I am trying to make a cron job via my websites cpanel. I have talked to the support services and they gave me this command to run to execute a php file on my website.
/usr/local/bin/php -q /home/mymcstatus/domains/mymcstatus.net/public_html/redesign/scripts/update.php
This doesnt seem to work though, I have also set the minute interval to every minute using */1.
I am using the code below inside of the file update.php:
<?php
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(E_ALL);
require('minequery.class.php');
include('../config/config.php');
$date = date("D-M-Y");
$file = fopen("UPDATE_LOG($date).txt", 'w');
$query = mysql_query("SELECT * FROM servers") or die(mysql_error());
if($query) {
while($row = mysql_fetch_array($query)) {
$ip = $row['ip'];
$port = $row['port'];
$name = $row['name'];
$string = "[UPDATE LOG]: $date - Updated Server $name \n";
fwrite($file, $string);
print("[UPDATE LOG] Updated Server $name </br>");
}
mail("duncan#mymcstatus.net","UPDATED","Server has updated","From: Mymcstatus");
} else {
print("Cant query");
}
?>
When I go to update.php manually through the web browser that code works, but nothing seems to happen with the Cronjob. What am I missing or doing wrong?
There are a few things that could be going on here. The first is to check the file permissions of update.php and make sure it is executable. The cron may be executing as a different user that doesn't have permission to execute update.php. The 2nd thing you can try is including this as the very first line of update.php with no whitespace before it.
#!/usr/local/bin/php
Usually cron jobs aren't run from the same directory where your PHP lives so it's possible that it is running but the output file is being created elsewhere. Try changing the output file path to be the full path to the file, i.e:
$file = fopen("/home/mymcstatus/domains/mymcstatus.net/public_html/redesign/scripts/UPDATE_LOG($date).txt", 'w');
With the help of the above comments I managed to fix the file paths but it also came down to the command. I had put the wrong user path in here is the command that works.
/usr/local/bin/php -q /home/mymcstat/domains/mymcstatus.net/public_html/redesign/scripts/update.php
Thanks for the help
It's always a good idea to cd to your script's path. This way you don't need any change in the name of the include and require files and any other file names engaging in file operations. Your cronjob command could look like this:
cd /home/mymcstatus/domains/mymcstatus.net/public_html/redesign/scripts/; /usr/local/bin/php -q /home/mymcstatus/domains/mymcstatus.net/public_html/redesign/scripts/update.php
You don't need to supply any absolute file paths this way.

PHP exec ZIP with password

Ok Guys I am working on it since yesterday, and this is driving me crazy.
I am creating a way to upload and zip a file on the fly, but also this zip should be then password protected (customer request, unfortunately).
Now everything is fine until the password protection, that is not working at all.
I know exec is so unsafe, but trust me, I just want to have a solution right now.
This is the code
if(isset($_FILES['fileSound']['name']) && isset($_FILES['fileLyric']['name'])) {
$nameFileSound = $_FILES['fileSound']['name'];
$tmpNameSound = $_FILES['fileSound']['tmp_name'];
$nameFileLyric = $_FILES['fileLyric']['name'];
$tmpNameLyric = $_FILES['fileLyric']['tmp_name'];
$download_folder = './CopyrightFiles/';
$zip = new ZipArchive();
$fileconpress = $download_folder . $RefNum . ".zip";
$conpress = $zip->open($fileconpress, ZIPARCHIVE::CREATE);
if ($conpress === true)
{
$zip->addFile($tmpNameSound, $nameFileSound);
$zip->addFile($tmpNameLyric, $nameFileLyric);
$zip->close();
echo $fileconpress."<br/>";
echo "yess !! Success!!!! ";
}
else echo " Oh No! Error";
}
exec("zip -r ".$download_folder.$RefNum.".zip -P password ".$download_folder.$RefNum."-protected.zip");
Now $RefNum is a string like this 1333-COP-3899827399283.
I checked if the command exec is up on the server and yes it is.
No errors show up.
What am I doing wrong?
Maybe the path?
What path should I use for the exec command?
For example the $zip option start from the public_html
Where the exec starts?
Do you think is that the problem or is there any other issue?
Please help me.
Thank you!
For one thing you need to change the argument order:
exec("zip -P password $download_folder$RefNum-protected.zip $Orig.zip");
Btw there seems no way with the common Unix zip command to update the zip file. You will repackage the original zip file as another password-protected zip file here.
If that fails, then look into the error.log for clues. Or use print exec(...) after adding 2>&1 behind the command to see all error messages.

Categories