PHP 5.3 getallheaders - php

I'm developing a web application for which it is required to capture custom header data sent by clients. In my localhost PHP 5.4 was installed and I'm using getallheaders().
But in my hosting which has PHP 5.3 installed. I can't get the header. I already tried other ways such:
foreach ($_SERVER as $name => $value)
{
if (substr($name, 0, 5) == 'HTTP_')
{
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
$headers[$name] = $value;
} else if ($name == "CONTENT_TYPE") {
$headers["Content-Type"] = $value;
} else if ($name == "CONTENT_LENGTH") {
$headers["Content-Length"] = $value;
}
}
and
apache_request_headers(), apache_response_headers()
Is there any other way? My hosting is using PHP 5.3 (FastCGI).
UPDATE
Well, i got where the problem came from. so first(for proofing the concept), i switch the PHP to run as Apache module, and yes as expected i able to use getallheaders().
after that i tried other rest client/debuger to send custom header(now as FastCGI), and my code is able capture the header(inside $_SERVER). So the question is, why the first REST client able to send header only if the server run as Apache Module.
I'm afraid if one of my user got the same problem while the other is fine.

Related

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

SagePay Notification Blank

I have a problem that I'm hoping someone out there is going to be able to help me with, as SagePay support has been as helpful as a chocolate teapot. I have a bespoke e-commerce solution with SagePay Server Integration, some running v2.23 others v3.00. We have had a couple of websites suddenly stop working.
The Notification from SagePay is blank, completely and utterly empty. There is no post data available on either of the two websites. However we have two other websites where nothing else is wrong, everything is working fine.
The only difference between the 4 sites is the version, which necessitated some minor changes in what is sent to SagePay, and where they are hosted. The two working sites are hosted with HeartInternet, whereas the two that don't work are hosted with different hosts, one with 123reg and one with an unknown American host.
SagePay have sent me their logs for a couple of transactions, both show the Notification data present, so as far as they are concerned they are sending it to me fine and it's a server issue. I'm not even sure where to begin debuging this.
Not sure if it's relevant but I've added in the start of our Notification method:
public function Notify() {
$this->Load();
define('LOG_FILE', ROOT_LIB . 'sagepaylog-v2.23.txt');
error_log(date('c') . " NEW NOTIFICATION" . PHP_EOL, 3, LOG_FILE);
$input = file_get_contents('php://input');
$query = $response = array();
$exp = explode('&', $input);
foreach($exp as $keyVal) {
$e = explode('=', $keyVal, 2);
$response[$e[0]] = urldecode($e[1]);
}
/* Comment out the above code and uncomment below when testing using POSTMAN.
foreach($_POST as $key => $val) {
$response[$key] = $val;
}*/
error_log("Notification Post Data" . PHP_EOL . "-------------------------" . PHP_EOL, 3, LOG_FILE);
foreach($response as $key => $val) {
error_log("$key: $val" . PHP_EOL, 3, LOG_FILE);
}
//We record the transaction during the initial registration. We need to load the details of that transaction, and of the order for the specified order ID, and make sure they match the details sent to us by SagePay.
$valid = FALSE;
$orders = $this->glob->order->LoadOrderHistory("WHERE ordId = " . (int)$response['VendorTxCode'], TRUE);
if(count($orders)) {
$order = $orders[$response['VendorTxCode']];
} else {
$order = new Order($this->glob);
}
$transaction = new Transaction($this->glob, $order->txnId);
Turns out this was caused by an htaccess redirecting non-www to www, and the notification URL didn't include a www. This was fixed by checking the URL and adding a www in front if there wasn't already one.

Yahoo Placefinder Geocoding randomly stopped working... Are they not supporting it now?

I have a web app that uses Yahoo Geocoding Placefinder API and it was working perfectly until earlier today. It just randomly quit working. Are they not supporting it anymore? I have looked all over the net and I can't find anything about them dropping support, but my code no longer works. Here's my code...
function geocode_yahoo($address,$city,$state,$country) {
$address = array($address, $city, $state, $country);
$address = array_filter($address);
$address = urlencode(implode(', ', $address));
$appid = 'CYxSRa64';
$url = 'http://where.yahooapis.com/geocode?location='.$address.'&flags=J&appid='.$appid;
$data = file_get_contents($url);
if ($data != '') {
$data = json_decode($data);
if ($data && $data->ResultSet && $data->ResultSet->Error == '0' && $data->ResultSet->Found) {
return (object) array('lat'=>$data->ResultSet->Results[0]->latitude, 'lng'=>$data->ResultSet->Results[0]->longitude);
}
}
return false;
}
Nothing wrong with your code, the service has simply been stopped.
Note that http://where.yahooapis.com is now returning a 404 page.
The service was set to retire at the end of November 2012 but was left running in order to provide time for developers to migrate to the replacement Yahoo BOSS services: http://developer.yahoo.com/boss/geo/
There is nothing here that states that the service will be stopped: https://developer.yahoo.com/boss/geo/docs/free_YQL.html#table_pf
In fact, there is a link on the bottom of this page: https://developer.yahoo.com/boss/geo/ to the free YQL version.

Determining if public proxies are anonymous

I would like to set up on my server a service that would determine if a proxy server I scraped off the net is anonymous or not. What I need is just a uri, from which the server would return the request exactly as it was received, and then to check if my public IP is in the response string(in HTTP_X_FORWARDED_FOR for example).
Has anyone has ever done this before?
Any help would be appreciated!
Why not write a simple PHP script and check this for yourself?
<?php
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
?>
Save it as headers.php and call it in your browser via the proxy server. All the request headers seen by the server will be echo'd on screen.
OK, thanks to Gaurav I got it done with this simple php script (getallheaders() need PECL):
<?php
$headers = array();
foreach($_SERVER as $key => $value) {
if(strpos($key, 'HTTP_') === 0) {
$headers[str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
echo $value;
}
}
?>
If anyone ever needs this..

How to print all information from an HTTP request to the screen, in PHP

I need some PHP code that does a dump of all the information in an HTTP request, including headers and the contents of any information included in a POST request. Basically, a diagnostic tool that spits out exactly what I send to a server.
Does anyone have some code that does this?
To get $_GET, $_POST, $_COOKIE:
print_r($_REQUEST);
If you want the headers:
print_r(apache_request_headers());
Well, you can read the entirety of the POST body like so
echo file_get_contents( 'php://input' );
And, assuming your webserver is Apache, you can read the request headers like so
$requestHeaders = apache_request_headers();
A simple way would be:
<?php
print_r($_SERVER);
print_r($_POST);
print_r($_GET);
print_r($_FILES);
?>
A bit of massaging would be required to get everything in the order you want, and to exclude the variables you are not interested in, but should give you a start.
Nobody mentioned how to dump HTTP headers correctly under any circumstances.
From CGI specification rfc3875, section 4.1.18:
Meta-variables with names beginning with "HTTP_" contain values read
from the client request header fields, if the protocol used is HTTP.
The HTTP header field name is converted to upper case, has all
occurrences of "-" replaced with "" and has "HTTP" prepended to give
the meta-variable name.
foreach ($_SERVER as $key => $value) {
if (strpos($key, 'HTTP_') === 0) {
$chunks = explode('_', $key);
$header = '';
for ($i = 1; $y = sizeof($chunks) - 1, $i < $y; $i++) {
$header .= ucfirst(strtolower($chunks[$i])).'-';
}
$header .= ucfirst(strtolower($chunks[$i])).': '.$value;
echo $header.'<br>';
}
}
Details: http://cmyker.blogspot.com/2012/10/how-to-dump-http-headers-with-php.html
Putting together answers from Peter Bailey and Cmyker you get something like:
<?php
foreach ($_SERVER as $key => $value) {
if (strpos($key, 'HTTP_') === 0) {
$chunks = explode('_', $key);
$header = '';
for ($i = 1; $y = sizeof($chunks) - 1, $i < $y; $i++) {
$header .= ucfirst(strtolower($chunks[$i])).'-';
}
$header .= ucfirst(strtolower($chunks[$i])).': '.$value;
echo $header."\n";
}
}
$body = file_get_contents('php://input');
if ($body != '') {
print("\n$body\n\n");
}
?>
which works with the php -S built-in webserver, which is quite a handy feature of PHP.
If you want actual HTTP Headers (both request and response), give hurl.it a try.
You can use the PHP command apache_request_headers() to get the request headers and apache_response_headers() to get the current response headers. Note that response can be changed later in the PHP script as long as content has not been served.
file_get_contents('php://input') will not always work.
I have a request with in the headers content-length=735 and php://input is empty string. So depends on how good/valid the HTTP request is.
in addition, you can use get_headers(). it doesn't depend on apache..
print_r(get_headers());

Categories