Calling included remote functions and variables - php

I'm trying to include a remote file from one of LAN pcs using include, allow_url_fopen = On and allow_url_include = On.
One local PC (let's say pc2), I have remote.php, which contains:
<?php
echo $var_on_pc1; // this doesn't output
$remote_var = 'Var on pc2';
function square($num){
return $num * $num;
}
?>
In my PC (let's say pc1), I have test.php, which consists of this:
<?php
$var_on_pc1 = 'Var on pc1';
include "http://pc2/path/to/remote.php";
echo $remote_var; // this doesn't output
echo square(4); // this got error
?>
When I run the script test.php, i got the error:
"Fatal error: Call to undefined function: square() in
path/to/test.php on line 7.
What happened? I thought I could call the included functions and variables and vice versa?
If I cannot implement this, what is the best way?
I have no security concern because I use this locally for temporary development.

Type http://pc2/path/to/remote.php into your browser and see what you get. PHP gets exactly the same.
If the PHP file is being processed by the web server at pc2, you likely get zilch in that file, because the code as been processed. You'd need to configure the other server to not process the PHP file and serve its raw source code instead.
This is not a good idea overall.

Related

How to bypass security checks in a PHP script if run from the CLI?

I have a PHP script which is typically run as part of a bigger web application.
The script essentially makes some changes to a database and reports back to the web user on the status/outcome.
I have an opening section in my PHP:
require $_SERVER['DOCUMENT_ROOT'].'/security.php';
// Only level <=1 users should be able to access this page:
if ( $_SESSION['MySecurityLevel'] > 1 ) {
echo '<script type="text/javascript" language="JavaScript">window.location = \'/index.php\'</script>';
exit();
}
So, basically, if the authenticated web user's security level is not higher than 1, then they are just redirected to the web app's index.
The script works fine like this via web browsers.
Now to my issue...
I want to also cron-job this script - but I don't know how to bypass the security check if ran from the CLI.
If I simply run it from the CLI/cron with 'php -f /path/to/report.php' and enclose the security check in a "if ( php_sapi_name() != 'cli' )", it spews out errors due to multiple uses of $_SERVER[] vars used in the script (there may be other complications but this was the first error encountered).
If I run it using CURL, then the php_sapi_name() check won't work as it's just being served by Apache.
Please can anyone offer some assistance?
Thank you! :)
If you invoke the script through the CLI some of the $_SERVER variables will be defined however their values may not be what you expect: for instance $_SERVER['DOCUMENT_ROOT'] will be empty so your require will look for a file called 'security.php' in the filesystem root. Other arrays such as $_SESSION will not be populated as the CLI does not have a comparable concept.
You could get around these issues by manually defining the variables (see "Set $_SERVER variable when calling PHP from command line?" however a cleaner approach would be to extract the code that makes the database changes to a separate file which is independent from any specific and that does not depend on any SAPI-specific variables being defined.
For instance your PHP script (let's call it index.php) could be modified like this:
require $_SERVER['DOCUMENT_ROOT'].'/security.php';
require $_SERVER['DOCUMENT_ROOT'].'/db_changes.php';';
// Only level <=1 users should be able to access this page:
if ( $_SESSION['MySecurityLevel'] > 1 ) {
echo '<script type="text/javascript" language="JavaScript">window.location = \'/index.php\'</script>';
exit();
} else {
do_db_changes();
}
Then in the SAPI-agnostic db_changes.php you would have:
<?
function do_db_changes() {
// Do the DB changes here...
}
?>
And finally you would have a file, outside the web root, which you can invoke from cron (say cron.php):
<?
require("/absolute/path/to/db_changes.php");
do_db_changes();
?>
Like this you can continue using index.php for the web application and invoke cron.php from cron to achieve your desired results.

Error include functions.php

I have 2 pages :
functions.php
function get_test($name) {
return 'Yo '.$name.' !';
}
test.php
include('http://www.exemple.com/functions.php');
echo get_test(Thomas);
When I execute my script on the server :
Fatal error: Call to undefined function get_test() in /htdocs/test.php on line 5
Note: I don't use Wordpress
Thanks
Don't do this:
include('http://www.exemple.com/functions.php');
It causes PHP to issue a full-blown HTTP request to your own server, causing Apache to EXECUTE that script, and return its output. That means you're not getting PHP code. You're getting the OUTPUT of that php code, which is not likely to be valid PHP code.
include/require via HTTP is almost always a sign of bad design, and also a major security vulnerability, if you're include/requiring from an actual remote url. Nothing says that the remote url can't return something like <?php system('rm -rf /'); ?>, which your server will then happily start executing.
Almost certainly you only need something like this:
include('functions.php');

PHP, Cannot call functions from remote server

I am trying to keep my PHP code on one server, while calling the functions from a separate server.
Server 1
<?php
echo 'Server 1';
function testingStuff(){
echo 'Testing Stuff';
}
function testingStuff2(){
return "Testing Stuff 2";
}
?>
Server 2
<?php
include 'fullURLtoServer1.php';
testingStuff();
echo testingStuff2();
?>
I know the include statement is working, as "Server 1" is being properly echoed to the screen, but neither of the function calls displays anything. Am I missing something? Why do neither function calls work?
EDIT 1
The ideal situation would be having a single .php file on Server 1 that contains multiple functions, which I can call as often as I'd like.
When you "include" a remote file, you are included the output of that file.
For server 2, the file you are trying to include just says:
Server 1
If you want to execute remote functions, you can make a different file for each function, and execute the function when the file is called. That way, you can "include" the remote file and show the output. You can replace the "different file for each function" for a single file with a parameter.
Keep in mind, trough, that any user/server/bot can call those functions by simply loading the file from the webserver.

file_put_contents stops my code from executing

I want to send some data as a GET request to my php page (submit.php) and save it in a local file. I have:
$loc = 'data.txt';
if(isset($_GET["data"])) {
echo 'set';
file_put_contents($loc, $_GET["data"], FILE_APPEND);
}
echo 'foo';
But when I access submit.php?data=bar, nothing happens to data.txt; moreover, echo 'foo' does not seem to execute. Why is this?
echo 'foo' does not execute because file_put_contents() encounters an error and the execution stop.
Put error_reporting(E_ALL & ~E_NOTICES); ini_set('display_errors', '1'); in front of your script to let PHP display the errors on screen.
This way you can find that, I guess, the process that runs the PHP code (the web server probably) does not have the rights to write in the directory where you store the code.
Change $loc to '/tmp/data.txt' and it will work.
Or, even better, create a new directory, set its permissions to rwx for everybody and change the code to write files in it.

How to do command line from PHP script

I need to write a script that will give users info on a given Unix account (the same Unix server that the script lives on). Mostly thing kinds of things that are in the passwd file or available via finger.
PHP is in safe-mode, so I can't access the passwd file via something built into php like file_get_contents(). Also, because it's in safe mode, various other command-line functions are disabled.
I thought I could get the info via a socket (no clue yet what that means, but I thought I'd try) but I get a fatal error that socket_create() is an unknown function. I pulled up the php-config file (which I can't change, FYI), and sure enough, sockets are not enabled.
However, while I was in there, I saw the line '--with-exec-dir=' with no actual directory set.
So then I remembered that when I was trying EVERY command line function, that some threw "not allowed in safe-mode" type errors, while others did nothing at all. If I put something like:
echo "[[";
exec("finger user");
echo "]]";
I'd end up with [[]]. So no errors, just no results either.
Bottom line:
Is there something I haven't tried? (in general)
Is there a runtime config option I can set to make exec() work?
quick note: I tried passthru() as well, specifically passthru("pwd") with still no output.
update
based on feedback, I tried both of the following:
$stuff = exec("pwd", $return);
echo "stuff=".$stuff."\n";
echo "return=";
print_r($return);
which results in:
stuff=
return=Array
(
)
and
$stuff = passthru("pwd", $return);
echo "stuff=".$stuff."\n";
echo "return=";
print_r($return);
which results in:
stuff=
return=1
The 1 sounds hopeful, but not what I want yet.
Idea
So this is actually an update of an already existing script that (please don't ask) I don't have access to. It's a perl script that's called via cgi. Is there a way to do php via cgi (so I don't have to deal with perl or rely on the older code)?
I'm afraid you can't do that in safe-mode. You have to remove the safe-mode if you have control of the server configuration.
I think you can't rely on sockets to read local files, sockets are used for network related things.
exec doesn't inherently return any data.
Try something like,
exec("finger user",$output);
echo "[[";
foreach($output as $key => $value){
echo $value;
}
echo "]]";
Exec returns a value, so do:
$var = exec("finger user");
and then parse the output to get what you want. You can get return status by adding in an optional variable thus:
exec("finger user", $var, $return_status);
or just:
echo exec("finger user");
if all you want is to see the output.
Thanks to all that responded, the following is what finally worked:
Create a cgi-bin folder
Add the following to the top of the php script:
#!/usr/local/bin/php-cgi
I don't know if this is something special on my server configuration, but I can run exec() and get what I'm after.

Categories