Security vunerability - What is this URL trying to do? - php

I've just received the following error from a few sites I run:
Error Caught in Application_Error event
Error in:
https:///phppath/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=""+-d+open_basedir=none+-d+auto_prepend_file=php://input+-n
Error Message:A potentially dangerous Request.Form value was detected
from the client (="Stack Trace: at
System.Web.HttpRequest.ValidateString(String value, String
collectionKey, RequestValidationSource requestCollection)
Obviously, the ASP.NET has just rejected this - a good thing.
But what I do not understand, not being a PHP type chap, is what it is trying to do?

The attacker has sent PHP code in the HTTP request body, and he is trying to have that code executed by your web server.
The php://input references the request body (ie POST data). The auto_prepend_file directive allows the script to include PHP code in the same way that include() and require() work. If successful, the uploaded code would be prepended and executed.
The payload most likely contains a backdoor script and some code to call home to let the developer know that a hack was successful.
This is most likely a bot that has randomly selected your server, as opposed to a human manually attempting it.
The bug that the attacker is trying to exploit is CVE-2012-1823:
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not properly handle query strings that lack an = (equals sign) character, which allows remote attackers to execute arbitrary code by placing command-line options in the query string, related to lack of skipping a certain php_getopt for the 'd' case.
http://www.cvedetails.com/cve/CVE-2012-1823

Related

How to prevent apache from sending connection close header <s>on 304 answers</s>

I have the following setup:
Some files are dynamically generated dependent on some (only a few) session parameters. Since they have not a great diversity, i allow caching in proxys/browsers. The files get an etag on their way, and the reaction of the whole web application at first glance seems correct: Files served in correct dependence from session situations, traffic saved.
And then this erroneous behavior:
But at closer inspection, i found that in his answer in case of a 304 for those dynamically generated files, apache wrongly sends a "Connection: close" Header instead of the normally sent "Connection: KeepAlive". What he should do is: Simply do not manipulate anything concerning "connection".
I cannot find any point where to pinpoint the cause of this behavior: Nowhere in the apache config files is anything written except one single line in one single file where it is instructed to send a keepalive - which it does - as long as it does not send a 304 response for a dynamically generated file. Nowhere in PHP do i instruct that guy to send anything other than keepalives (and the latter only to try to counter the connection:close).
The apache does not do this when it serves "normal" (non-dynamic) files (with 304 answers). So in some way i assume that maybe the PHP kernel is the one who interferes here without permission or being asked. But then, an added "Header set Connection 'Keep-Alive'" in the apache config, which i too added to counter the closing of the connection, does not work, too. Normally, when you put such a header set rule (not of "early" type) in the apache config, this rules takes action AFTER finalization of any subordered work on the requested document (thus AFTER finalization of the PHP output). But in my case, nothing happens - well: in case of a 304 response. In all other cases, everything works normal and correct.
Since there do some other files go over the line at a page request, i would appreciate to get the apache rid of those connection-closures.
Is there anybody who has an idea what to do with this behavior?
P.S.: One day (and a good sleep) later, things are clearing:
The culprit in this case was a shortsightedly (on my behalf) copied example snippet, which had "HTTP/1.>>>0<<< 304" (the Null!) in it.
This protocol version number gets (correctly) post-processed by apache (after everything otherwise - including any apache modules work - got finalized), in that it decides not to send a "Connection: Keep-Alive" over the wire, since that feature didn't exist in version HTTP/1.0.
The problem in this case was to get the focus on the fact that everything inside php and apache modules worked correctly and something in the outer environment of them must have been wrong, and thereafter to shift the view to anything in the code that could possibly influence that outer environment (e.g. the protocol version).

Requesting file via PHP fails, but succeeds in Python

The URL in question : http://www.roblox.com/asset/?id=149996624
When accessed in a browser, it will correctly download a file (which is an XML document). I wanted to get the file in php, and simply display its contents on a page.
$contents = file_get_contents("http://www.roblox.com/asset/?id=149996624");
The above is what I've tried using (as far as I know, the page does not expect any headers). I get a 500 HTTP error. However, in Python, the following code works and I receive the file.
r = requests.get("http://www.roblox.com/asset/?id=147781188")
I'm confused as to what the distinction is between how these two requests are sent. I am almost 100% it is not a header problem. I've also tried the cURL library in PHP to no avail. Nothing I've tried in PHP seems to succeed with the URL (with any valid id parameter); but Python is able to bring success nonchalantly.
Any insight as to why this issue may be happening would be great.
EDIT : I have already tried copying Python's headers into my PHP request.
EDIT2 : It also appears that there are two requests happening upon navigating to the link.
Is this on a linux/mac host by chance? If so you could use ngrep to see the differences on the request themselves on the wire. Something like the following should work
ngrep -t '^(GET) ' 'src host 127.0.0.1 and tcp and dst port 80'
EDIT - The problem is that your server is responding with a 302 and the PHP library is not following it automatically. Cheers!

Why is my PHP code passed in source to the client?

I'have just started to learn PHP, I'm using a free host to test my code but nothing happens and also my php code passed in source of page, does it show that server don't interpret it?
Yes, that shows that the server isn't interpreting it properly. The user should never receive PHP code, just the html/javascript/whatever that your PHP script outputs.
As for why this is happening, here are a few basic things to check:
Your PHP code should begin with the <?php tag and end with the ?> tag (the ending tag isn't strictly necessary, but any code you put after it won't be interpreted).
The document's name should end with .php (not always necessary, but some server setups may require it).
If you haven't checked already, make sure that the host you're using supports PHP in the first place.
Is php code passed in source to the client?
No.
Your PHP interpreter isn't being invoked.

Querystring character limit for PHP scripts run through command line?

(Backstory: My PHP script is executing another PHP script through the command line (PHP's "exec()" command) so that the cURL session the target script creates doesn't cause the original PHP script to hang. I'm doing this so that I can send transactional email without slow page loads for my user if the email provider's servers are laggy.)
I'm calling a PHP script like this:
exec("[php] [target script] [querystring]"), where [querystring] is a typical HTTP GET querystring (variable=value&variable2=value2). The reason I'm passing the email data to the target script via a querystring is that my PHP host has a flag disabled in the PHP.ini that disallows PHP scripts from detecting the $argv's they're called with via the command line. (For whatever reason, appending a querytring works though.)
So, the question is: What would be the character limit on this querystring? Would there even be one? There is no HTTP or web browser in the mix -- would this mean Apache's and browsers' GET character limits wouldn't be a constraint? Would there naturally be a command line constraint, though?
I don't think there is any character limit, if it is, it's probably determined by the operating system that you use or the language which in this case would translate to your memory.
I hope that answers your question.
Please note that PHP setups with the suhosin patch installed will have a default limit of
512 characters for get parameters. Although bad practice, most browsers (including IE)
supports URLs up to around 2000 characters, while Apache has a default of 8000. To add
support for long parameters with suhosin, add suhosin.get.max_value_length = in php.ini

Apache: reverse proxy to process PHP from another server

I have the following setup:
Plain-Server: Delivering php-files as plain text
Proxy-Server: Asking the Plain-Server for the php file and parsing it.
Now my question: How do I configure the Proxy-Server (a fully configurable apache 2.2 with PHP 5.3) to interpret the plain php files from Plain-Server?
Example: Given a small php script "hello.php" on Plain-Server (accessible throw http://plainserver/hello.php):
<?php
echo "Hello World";
?>
Plain-Server only outputs it as plain text, no parsing of php-code.
On the Proxy-Server the file "hello.php" does not exist. But when requesting hello.php from Proxy-Server it should get the hello.php from Plain-Server with mod_proxy (Reverse Proxy). It should also parse and execute the php, saying only "Hello World".
The Reverse Proxy is already running, but the execution of php code not working. I tried mod_filter, but couldn't is work. Any ideas how to that?
You may consider instead sharing the php files from your source server via an nfs mount or something similar to your target server. Tricking the proxy server into doing what you ask seems like the long way around the barn?
I totally agree with jskaggz,
you could build some awfull tricks building some apps that fetch the remote page ,
dowload it into a local file and then redirect the user to that page that could be executed...
but there is a milion security issues and things that might go wrong with that...
Can't you just convert the 'plain server' to a php excuting server and do some traditional reverse proxying
on your 'proxy server'
maybe using mod_proxy:
http://www.apachetutor.org/admin/reverseproxies ?
Answered this on the ServerFault version of this thread: https://serverfault.com/a/399671/48061

Categories