php: shellscript running before screen-output - php

I'm currently putting together a small web-based GUI to generate kickstart-scripts. I got a confirmation page that's sending the relevant data via POST to the PHP-page where the actual shell script is called to build the iso. So far it's working, but the page seems to execute the script before it outputs anything else (for example, the 'echo' I put in at the beginning of the page ...), and I'm absolutely clueless why. Would anyone care to enlighten me?
Here's the code to the PHP-page that's executing the shell script ...
echo 'Generating your ISO; this might take a while...';
sleep(20);
if (!isset($_POST['auth'])) {
$ad = 'N';
}
else {
$ad = 'Y';
}
if (!isset($_POST['oracle'])) {
$oracle = 'N';
}
else {
$oracle = 'Y';
}
if ((!isset($_POST['ip'])) or (!isset($_POST['hostname'])) or (!isset($_POST['rhsel'])) or (!isset($_POST['submit'])) or (!isset($_POST['gw'])) or (!isset($_POST['nm']))) {
die('Please use the correct form !');
}
if (isset($_POST['ip'])) {
$ip = trim($_POST['ip']);
}
if (isset($_POST['gw'])) {
$gw = trim($_POST['gw']);
}
if (isset($_POST['nm'])) {
$nm = trim($_POST['nm']);
}
if (isset($_POST['hostname'])) {
$hostname = trim($_POST['hostname']);
}
if (isset($_POST['rhsel'])) {
$rhsel = $_POST['rhsel'];
}
passthru("/usr/bin/sudo /data/skripte/webconfig.sh $rhsel $oracle $ad $ip $gw $nm $hostname 2>&1");

PHP scripts accessed via a browser are request-response, meaning all processing is done on the server prior to headers and content being sent to the client. This means you will not get a continually updating output like you would see on the command line. There is no way around this. Sorry.

Related

Run PHP code after ending the HTTP request

I'm writing a simple code to simply show to clients, data that is actually loaded from another HTTP server. The problem is that loading it from the remote server can take up to multiple seconds, and I don't want that much page load delay. So, I make my server cache a copy of this data. So that whenever a client sends a request to my server, it sends the ready-loaded copy and then loads a new copy from the remote server to update the local copy in case any changes were made.
So here's my pseudo code:
if(file_exists($cache_path)){
echo file_get_contents($cache_path);
// I need to end the HTTP request and close the connection here while continuing with the code.
$uptodate_content = file_get_contents("https://docs.google.com/document/export?format=pdf&id=$id");
// I don't want the user to wait for nothing, until this line.
}
else {
$uptodate_content = file_get_contents("https://someremotehost.com/someresource");
echo $uptodate_content;
}
echo file_put_contents($cache_path, $uptodate_content);
Hi I think the best solution is using a queue For example if you use the the queue, you can send it to the queue and then your consumer can pick it from the queue when it has time and user do not need to wait for it
This link is helpful
And this link will help you to use redis for this problem
This is a bad practice.
The connection can never end and you should be careful with such code
The better method is to run a cron job/queue every houerget data from remote server, or alternatively the remote server will trigger a trigger when updating data.
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort();
ob_start();
//your code
//your code
//your code
echo "response foo bar";
$obSize = ob_get_length();
header("Content-Length: $obSize");
ob_end_flush();
flush();
session_write_close();
// Do processing here
request_to_remote_server();
One way of doing it:
First, create a new PHP file, let's call it update.php, and write the following:
if (isset($argv[1])) {
storeDocumentToCache($argv[1]);
}
And in your current file, change the code to:
echo readDocumentFromCache($id) ?? storeDocumentToCache($id);
In old PHP versions (<7) it should be:
$content = readDocumentFromCache($id);
echo isset($content) ? $content : storeDocumentToCache($id);
Then require the following helper functions in both files (and set $cache_path):
function readDocumentFromCache($id, $fetch = true)
{
$cache_path = "?";
if (file_exists($cache_path)) {
return file_get_contents($cache_path);
}
if ($fetch) {
execInBackground("php " . __DIR__ . "/update.php $id");
}
return null;
}
funciton storeDocumentToCache($id)
{
$cache_path = "?";
$uptodate_content = file_get_contents("https://docs.google.com/document/export?format=pdf&id=$id");
file_put_contents($cache_path, $uptodate_content);
return $uptodate_content;
}
function execInBackground($cmd)
{
if (substr(php_uname(), 0, 7) == "Windows") {
pclose(popen("start /B " . $cmd, "r"));
} else {
exec($cmd . ' > /dev/null 2>/dev/null &');
}
}

call the exec() php function in the web browser

I have a php function called getServerAddres() and I am trying to execute the exec() from the web browser. I understand this is not the proper way of using the function, I was just a task to exploit a web server using remote code injection. Any help on how to do remote code injection using the exec() through the web browser would be greatly appreciated.
Lets say the login in screen is: https://www.10.10.20.161/test/
function getServerAddress() {
if(isset($_SERVER["SERVER_ADDR"]))
return $_SERVER["SERVER_ADDR"];
else {
// Running CLI
if(stristr(PHP_OS, 'WIN')) {
// Rather hacky way to handle windows servers
exec('ipconfig /all', $catch);
foreach($catch as $line) {
if(eregi('IP Address', $line)) {
// Have seen exec return "multi-line" content, so another hack.
if(count($lineCount = split(':', $line)) == 1) {
list($t, $ip) = split(':', $line);
$ip = trim($ip);
} else {
$parts = explode('IP Address', $line);
$parts = explode('Subnet Mask', $parts[1]);
$parts = explode(': ', $parts[0]);
$ip = trim($parts[1]);
}
if(ip2long($ip > 0)) {
echo 'IP is '.$ip."\n";
return $ip;
} else
; // to-do: Handle this failure condition.
}
}
} else {
$ifconfig = shell_exec('/sbin/ifconfig eth0');
preg_match('/addr:([\d\.]+)/', $ifconfig, $match);
return $match[1];
}
}
}
The php script came from the login.php file.
You dont seem to understand the exec function....
First thing, read the documentation here.
This function gets executed on the server side, and thus cannot be executed on the client side.
If what you want is the information of the host machine, then you can run the command there, and output the result.
Create this file: example.php, and enter this code:
<?php
echo exec('whoami');
?>
Now, upload this file to the host, and make a request:
www.YOURHOST.smg/example.php
And read the result

PHP: Running PHP scripts without going on webpage?

I use WAMP and ever since I have learned PHP, I have been running my php scripts by going on the webpage itself to see the output. For example, to see the output on a script called script.php, I go on localhost/script.php.
Is there a better way to do this? I mean, in Java there's Eclipse and you can just click the green button and it'll run the code for you and see immediate output. Is there something like this for PHP?
It is possible to run PHP scripts from the command line without a web server. To do this add the following logic to your script:
if (defined('STDIN')) {
if (isset($argv)){
// handle your command line arguments here with getopt
}
}
// GET request parameter definitions //
else {
// handle your URL parameters (via GET or POST requests) here
}
When the script is run from the command line with the PHP interpreter
php myfile.php -s --longflag <argument>
STDIN is defined and you can handle command line switches, flags, and arguments with getopt in the if block.
The script reaches the else block when you access it by URL on a web server. The PHP code that you currently have can be placed in that block.
Here's an example from one of my projects that demonstrates how to handle the URL parameters as short or long command line options:
// Command line parameter definitions //
if (defined('STDIN')) {
// check whether arguments were passed, if not there is no need to attempt to check the array
if (isset($argv)){
$shortopts = "c:";
$longopts = array(
"xrt",
"xrp",
"user:",
);
$params = getopt($shortopts, $longopts);
if (isset($params['c'])){
if ($params['c'] > 0 && $params['c'] <= 200)
$count = $params['c']; //assign to the count variable
}
if (isset($params['xrt'])){
$include_retweets = false;
}
if (isset($params['xrp'])){
$exclude_replies = true;
}
if (isset($params['user'])){
$screen_name = $params['user'];
}
}
}
// Web server URL parameter definitions //
else {
// c = tweet count ( possible range 1 - 200 tweets, else default = 25)
if (isset($_GET["c"])){
if ($_GET["c"] > 0 && $_GET["c"] <= 200){
$count = $_GET["c"];
}
}
// xrt = exclude retweets from the timeline ( possible values: 1=true, else false)
if (isset($_GET["xrt"])){
if ($_GET["xrt"] == 1){
$include_retweets = false;
}
}
// xrp = exclude replies from the timeline (possible values: 1=true, else false)
if (isset($_GET["xrp"])){
if ($_GET["xrp"] == 1){
$exclude_replies = true;
}
}
// user = Twitter screen name for the user timeline that the user is requesting (default = their own, possible values = any other Twitter user name)
if (isset($_GET["user"])){
$screen_name = $_GET["user"];
}
} // end else block
I find this to be helpful for testing. Hope it helps.
Jetbrains PHP storm is a good debugging tool
If you use Sublime Text as text editor you can use XDebug

How to mimic a command line run with arguements inside a PHP script?

How can you mimic a command line run of a script with arguements inside a PHP script? Or is that not possible?
In other words, let's say you have the following script:
#!/usr/bin/php
<?php
require "../src/php/whatsprot.class.php";
function fgets_u($pStdn) {
$pArr = array($pStdn);
if (false === ($num_changed_streams = stream_select($pArr, $write = NULL, $except = NULL, 0))) {
print("\$ 001 Socket Error : UNABLE TO WATCH STDIN.\n");
return FALSE;
} elseif ($num_changed_streams > 0) {
return trim(fgets($pStdn, 1024));
}
}
$nickname = "WhatsAPI Test";
$sender = ""; // Mobile number with country code (but without + or 00)
$imei = ""; // MAC Address for iOS IMEI for other platform (Android/etc)
$countrycode = substr($sender, 0, 2);
$phonenumber=substr($sender, 2);
if ($argc < 2) {
echo "USAGE: ".$_SERVER['argv'][0]." [-l] [-s <phone> <message>] [-i <phone>]\n";
echo "\tphone: full number including country code, without '+' or '00'\n";
echo "\t-s: send message\n";
echo "\t-l: listen for new messages\n";
echo "\t-i: interactive conversation with <phone>\n";
exit(1);
}
$dst=$_SERVER['argv'][2];
$msg = "";
for ($i=3; $i<$argc; $i++) {
$msg .= $_SERVER['argv'][$i]." ";
}
echo "[] Logging in as '$nickname' ($sender)\n";
$wa = new WhatsProt($sender, $imei, $nickname, true);
$url = "https://r.whatsapp.net/v1/exist.php?cc=".$countrycode."&in=".$phonenumber."&udid=".$wa->encryptPassword();
$content = file_get_contents($url);
if(stristr($content,'status="ok"') === false){
echo "Wrong Password\n";
exit(0);
}
$wa->Connect();
$wa->Login();
if ($_SERVER['argv'][1] == "-i") {
echo "\n[] Interactive conversation with $dst:\n";
stream_set_timeout(STDIN,1);
while(TRUE) {
$wa->PollMessages();
$buff = $wa->GetMessages();
if(!empty($buff)){
print_r($buff);
}
$line = fgets_u(STDIN);
if ($line != "") {
if (strrchr($line, " ")) {
// needs PHP >= 5.3.0
$command = trim(strstr($line, ' ', TRUE));
} else {
$command = $line;
}
switch ($command) {
case "/query":
$dst = trim(strstr($line, ' ', FALSE));
echo "[] Interactive conversation with $dst:\n";
break;
case "/accountinfo":
echo "[] Account Info: ";
$wa->accountInfo();
break;
case "/lastseen":
echo "[] Request last seen $dst: ";
$wa->RequestLastSeen("$dst");
break;
default:
echo "[] Send message to $dst: $line\n";
$wa->Message(time()."-1", $dst , $line);
break;
}
}
}
exit(0);
}
if ($_SERVER['argv'][1] == "-l") {
echo "\n[] Listen mode:\n";
while (TRUE) {
$wa->PollMessages();
$data = $wa->GetMessages();
if(!empty($data)) print_r($data);
sleep(1);
}
exit(0);
}
echo "\n[] Request last seen $dst: ";
$wa->RequestLastSeen($dst);
echo "\n[] Send message to $dst: $msg\n";
$wa->Message(time()."-1", $dst , $msg);
echo "\n";
?>
To run this script, you are meant to go to the Command Line, down to the directory the file is in, and then type in something like php -s "whatsapp.php" "Number" "Message".
But what if I wanted to bypass the Command Line altogether and do that directly inside the script so that I can run it at any time from my Web Server, how would I do that?
First off, you should be using getopt.
In PHP it supports both short and long formats.
Usage demos are documented at the page I've linked to. In your case, I suspect you'll have difficulty detecting whether a <message> was included as your -s tag's second parameter. It will probably be easier to make the message a parameter for its own option.
$options = getopt("ls:m:i:");
if (isset($options["s"] && !isset($options["m"])) {
die("-s needs -m");
}
As for running things from a web server ... well, you pass variables to a command line PHP script using getopt() and $argv, but you pass variables from a web server using $_GET and $_POST. If you can figure out a sensible way to map $_GET variables your command line options, you should be good to go.
Note that a variety of other considerations exist when taking a command line script and running it through a web server. Permission and security go hand in hand, usually as inverse functions of each other. That is, if you open up permissions so that it's allowed to do what it needs, you may expose or even create vulnerabilities on your server. I don't recommend you do this unless you'll more experienced, or you don't mind if things break or get attacked by script kiddies out to 0wn your server.
You're looking for backticks, see
http://php.net/manual/en/language.operators.execution.php
Or you can use shell_exec()
http://www.php.net/manual/en/function.shell-exec.php

How can I use a php file's output with Ajax?

I was following this tutorial.
I need to use a php file's ouput in my HTML file to dynamically load images into a gallery. I call
function setOutput()
{
if (httpObject.readyState == 4)
document.getElementById('main').src = httpObject.responseText;
alert("set output: " + httpObject.responseText);
}
from
function doWork()
{
httpObject = getHTTPObject();
if (httpObject != null) {
httpObject.open("GET", "gallery.php?no=0", true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput;
}
}
However, the alert returns the php file, word for word. It's probably a really stupid error, but I can't seem to find it.
The php file:
<?php
if (isset($_GET['no'])) {
$no = $_GET['no'];
if ($no <= 10 && $no >1) {
$xml = simplexml_load_file('gallery.xml');
echo "images/" . $xml->image[$no]->src;
}
else die("Number isn't between 1 and 10");
}
else die("No number set.");
?>
If the alert is returning the contents of the PHP file instead of the results of executing it, then the server is not executing it.
Test by accessing the URI directly (instead of going via JavaScript).
You probably need to configure PHP support on the server.
Your Server doesn't serve/parse PHP files! You could test your JavaScript code by setting the content of gallery.php to the HTML code you want to receive.

Categories