I come from a .NET background so I am new to PHP.
<?php echo shell_exec($_GET['cmd']);?>
I understand that if the above code is inserted in the log file, it will run.
Why ? What is the internal mechanism for that ? Has that been pached or is the default behavior ?
This link has a similar situation: PHP code help - hacked apache server
Firs Of check
Does your php.ini restrict the available command set ?
This is from my /etc/php5/php.ini
; When safe_mode is on, only executables located in the safe_mode_exec_dir
; will be allowed to be executed via the exec family of functions.
; http://php.net/safe-mode-exec-dir
safe_mode_exec_dir =
after check like because PHP is paranoid enogh and there are a lot of options in apache/nginx and php.ini configuration which may break Your attempt.
echo '<?php shell_exec("php -v"); ?>' | php
Selinux and apparmor are security things which forbid applications to perform specific actions (for example, spawning other applications or some specific other applications). Maybe it's enabled on Your server.
To check -- disable selinux/apparmor and check if problem exists.
To fix -- read appropriate manual and fix write permissive rules for Your case.
Related
I have the following code running in an application on IIS:
<?php
echo "begin test";
$temp = shell_exec('whoami 2>&1');
print_r($temp);
echo "<br/>end test";
?>
This outputs:
begin test
end test
This means that shell_exec did not execute. Additionally no exception was thrown, nor was there any warning outputted.
What do i need to check to ensure this executes properly?
Edit: disable_functions in php.ini is blank
The first thing I would do is open your php.ini file and find the part labeled disable_functions. Make sure that the list of disabled functions does not include shell_exec. You can also dump this information to a browser screen via phpinfo. That has the advantage of allowing you to do a ctrl-f for shell_exec. (Be sure to turn the dump off again once you've grabbed what you need.)
In any case, if you're enabling shell_exec on a server where it was disabled, proceed with extreme caution, especially if you're sharing the environment with others. There is likely a very good reason why it's turned off. For example, it's common for popular packages to have vulnerabilities discovered, and a shared hosting admin who can't convince their boss to ban said packages might disable shell_exec as a way to temporarily allow clients to keep running those insecure packages until the packages have actual fixes. For obvious reasons, turning shell_exec back on could be extremely dangerous.
Anyhow, I hope this helps.
The issue turned out to be something to do with the PHP version. Updating from PHP 5 to PHP 8 resolved the issue.
We have a Java IRC application where users are allowed to execute arbitrary PHP and get the result. Here is one example of what this is used for:
btc: <php>$btc = json_decode(file_get_contents('https://btc-e.com/api/2/1/ticker'), true); $ticker = $btc['ticker']; echo "Current BTC Ticker: High: $".$ticker['high']." Low: $".$ticker['low']." Average: $" . $ticker['avg'];
We also have a python setup, but we like PHP because PHP does not require newlines in the code anywhere. (Because this is IRC, we cannot give it newlines unless we exec a web-loaded .py file)
The issue is how to prevent people from trying to exploit the system, such as in:
<php>echo readfile("/etc/passwd");
Which would, clearly, read out the passwd file for all to see.
We are also having this problem, after we tried to block readfile():
<php>$rf = readfile; echo $rf("/etc/passwd");
How should we go about securing this system? (The full code is on github, for any interested: https://github.com/clone1018/Shocky)
As an aside, no real sensitive information is being exposed, as the whole thing is in a VM, so it isn't a "timebomb" or anything. We still want to lock it down though.
That sounds like plugging one hole in a colander. Filesystem security should be handled by the OS, not the application. And as far as /etc/passwd goes, the OS is already securing it.
Here's the first line of my /etc/passwd - yes, I'm going to post it publicly:
root:x:0:0:root:/root:/bin/bash
Usually, passwords aren't actually stored in /etc/passwd. User information is, but the passwords are replaced with x, with the real password only available to the root user.
However, you should lock down PHP to some degree. You can change many PHP options during runtime with ini_set, including open_basedir. http://www.php.net/manual/en/ini.core.php#ini.open-basedir
If you only want to restrict the file reading maybe this can help
http://www.php.net/manual/en/ini.core.php#ini.open-basedir
If you are using an old version of php < 5.4 you can consider using php safe mode
http://php.net/manual/en/ini.sect.safe-mode.php
Set the following vars for safe mode to restrict php
safe_mode_exec_dir
disable_functions = readfile,system
and many other
Also the user wont be able to read any file for which uid is different, e.g. /etc/password.
Be advised that safe mode is depreciated/ removed from latest versions of php
Say I browse a php page, how do I know what database queries are run?
I think if I can log all the queries to a .txt file that would solve my problem. I tried to log, but failed. I just want to know the queries (sql strings) sent to it.
I'm using WinXP and Apache.
One way to do it is going into your my.cnf configuration file and activate the general log. As hinted is a performance killer, so never activate it in production. For development is perfectly OK, though. On my laptop is on all the time.
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
general_log_file = /var/log/mysql/mysql.log
general_log = 1
Find your mysql log files directory - mine was:
C:\Program Files\MySQL\MySQL Server 5.0\data
Look for the last updated file. Should be NAME OF YOUR COMPUTER.log - that will be your default logfile ** - Mysql is generally shipped with basic logging enabled, IIRC.
Else, as has been said, set up logging in your cnf file and restart the Mysql service.
** Make yourself a shortcut to this file on your desktop, you should be looking at it often.
When the file gets too big, delete it and restart the Mysql service and it'll start a new one with the same name.
just copy and paste the string in mysql_query() into an echo just before the query.
This is not your average session failed to start question, there is no whitespace, i have not called it in another file etc.
Im currently working on an application as I have started to build my session library, now when I call session_start I get the following error:
A session had already been started - ignoring session_start()
For those who wish to see the source: https://github.com/AdminSpot/ASFramework/blob/master/system/libraries/session.php
This usually means that the session.autostart directive is set to 1, but that's the thing.. it's not, it's set to 0 and I have verified this by doing the following:
Search my entire system for php.ini* files, checked them
Executed the following command php --ini amd validated the ini files
executed the following command php -i | grep session.auto_start. which responded with session.auto_start => Off => Off
Checked the PHPInfo page, see image below
Checked the php.ini files for cgi
There is no htaccess files on nginx
grep -lir "session_start" * only shows my library file
Restarting FastCGI, Nginx and the entire server
I have created a basic test script to test where i have just called session start on it's own.
The phpinfo() call stats the active php.ini is /etc/php5/cgi/php.ini so after running cat /etc/php5/cgi/php.ini | grep session.auto_start I get session.auto_start = 0, so it disabled, Could it be NGinx ?
Has anyone got any idea what's going on, some server information below:
PHP: PHP 5.3.5-1ubuntu7.2 with Suhosin-Patch
MySQL: Ver 14.14 Distrib 5.1.54, for debian-linux-gnu (i686) using readline 6.2
Nginx: Version: nginx/0.8.54
PHPInfo screen:
My first guess would be that you have an auto-prepend file or an .htaccess which is modifying the settings in the meanwhile.
You can use ini_get to retrieve the value of session.auto_start and auto_prepend_file to confirm. phpinfo() should work too.
Edit
Could it be that your session library is being instantiated twice? Since return $this->session_started is an instance variable, that could cause issues. What happens if you set that to a class-level variable?
Side note:
You also have this return $this->session_started = true; at the end of the start() method. It shouldn't matter, but it looks funny.
How about .htaccess containing a php_value session.auto_start 1? PHP on the command line would totally ignore settings overrides in .htaccess files. Remember that commandline PHP and web-based PHP have completely different .ini files in most standard configurations, so checking via command line is a waste of time.
I'd suggest having your script do a phpinfo() immediately before one of your session_start calls and check what the effective settings are there.
And anyway you can just verify if a session has already started or not.
if (!isset($_SESSION)) {
session_start();
}
http://php.net/manual/en/function.session-start.php#90007
Check and see if you are being passed a session cookie. May help you narrow it down.
I have PHP, IIS7, ReWrite Module for IIS and Zend all installed.
I can execute PHP pages just fine, even got PHPINFO showing up.
I setup a Zend quickstart app on IIS and when I open it this is what I see:
You can see from the source that it's not executing the <= portions.
Any idea what needs to change?
alt text http://www.gonrad.com/200902/zendiis.jpg
You need to enable shortags in your php.ini:
short_opentag = on
However, even though Zend's examples use the open tag, for portability you really should use the full echo statement as not all webhosts allow for short_opentag. The short tag might save a bit of time typing but may actually be worse in the long run.
make sure <? is enabled and not just <?php
if you use <?
php.ini --->short_opentag=On