Can PHP move around and edit root system files on a server? - php

this might seem like a stupid question but I've Googled to no avail.
I've always thought of PHP as a language for creating dynamic database driven sites, and I've never thought about using it to move system files on the actual server (as I have never had a need to). My question is:
can a standard PHP 5.3.x.x installation move, copy or edit system files (I'm using a Linux sever as an example) around in /bin or maybe /etc?
is this a good idea/practise?
It has never occurred to me that if a malicious hacker were to be able to inject some PHP into a site, that they would effectively be granted access to the entire Linux server (and all its system files). I have only ever thought of PHP as something that operates inside the /vhosts directory (perhaps naively).
Sorry if this sounds like a stupid question, but I can't really test my theory as if my boss was to see me writing/uploading/executing a script that moved stuff around in the Linux file system I would be dead.
Thanks for your help guys! :)

PHP can to your server whatever the permissions of the user account it runs as allow it to do. PHP as a language is not restricted in any way (at least, in terms of permissions), it is the user account that is restricted.
This is why people will usually create a user for Apache/nginx/insert web server here to run as, and only give it permissions to manipulate files and directories related to the web server. If you don't give this user access permissions to /bin or /etc, it's can't do anything that will affect them.
is this a good idea/practice?
Normally not. Leave system administration to your sysadmin and not the user requesting your PHP scripts.

PHP can attempt to call many system commands to move or directly edit files on the hard disk. Whether it succeeds depends on the security settings.
Let's assume your running PHP thru apache and apache is set up to run all processes as the user www-data - a default setup for OS's like Debian. If you give the user www-data permission to edit /etc then yes, PHP can read and write to files in /etc
There is only one major drawback as you identified; security, security and security. You also better be sure that your PHP works properly as 1 wrongly written file could now take down the entire server.
I would also definitely not practice on your server behind your bosses back. Look into getting a cheap virtual machine, either hosted elsewhere or on your own machine curtsey of VirtualBox

Yes it can. Its a programming language, it can do anything.
It completely depends who is running it. If its root it can do anything. If its just a normal user bob. It can not do much outside the home /home/bob. Apache is also like bob. Apache usually runs under www-data, www, apache user names.

Related

can PHP create a new PHP and access thus the server?

i am quite new to the PHP business and thus please forgive me, if the questions sounds stupid to you. (always ask for forgiveness, never for permission ;)
Nevertheless, my theoretical question: I have a php based website, which is located in web root. This Php allows to create another php file, and its saved also in the web root. Later, i can "request" this newly created php and thus the php will be run. That means for my understanding, as a php script can include/access files outside the web root, I have basically full access to the server via this php-programm. Is it right ? I would be shocked if it is true .... so if I am wrong, what is preventing this access ?
This is going to be based on file permissions. If you're on a hosted server, you have permission to change everything on your area of the server (and you'll have a special identity that gives your permission). You should also be able to send requests just about anywhere (which is including/accessing files outside your area). Chances are your special user does not have permission to write outside your dedicated space on the server. This is pretty standard. I'd look into File Permissions, and how they work on webservers if you're interested in learning more.

PHP application to replicate websites from single code source

I'm attempting to build an application in PHP to help me configure new websites.
New sites will always be based on a specific "codebase", containing all necessary web files.
I want my PHP script to copy those web files from one domain's webspace to another domain's webspace.
When I click a button, an empty webspace is populated with files from another domain.
Both domains are on the same Linux/Apache server.
As an experiment, I tried using shell and exec commands in PHP to perform actions as "root".
(I know this can open major security holes, so it's not my ideal method.)
But I still had similar permission issues and couldn't get that method to work either.
But I'm running into permission/ownership issues when copying across domains.
Maybe a CGI script is a better idea, but I'm not sure how to approach it.
Any advice is appreciated.
Or, if you know of a better resource for this type of information, please point me toward it.
I'm sure this sort of "website setup" application has been built before.
Thanks!
i'm also doing something like this. Only difference is that i'm not making copies of the core files. the system has one core and only specific files are copied.
if you want to copy files then you have to take in consideration the following:
an easy (less secured way) is to use the same user for all websites
otherwise (in case you want to provide different accesses) - you must create a different owner for each website. you must set the owner/group for the copied files (this will be done by root).
for the new website setup:
either main domain will run as root, and then it will be able to execute a new website creation, or if you dont want your main domain to be root, you can do the following:
create a cronjob (or php script that runs in a loop under CLI), that will be executed by root. it will check some database record every 2 minutes for example, and you can add from your main domain a record with setup info for new hosted website (or just execute some script that gains root access and does it without cron).
the script that creates this can be done in php. it can be done in any language you wish, it doesn't really matter as long as it gets the correct access.
in my case i'm using the same user since they are all my websites. disadvantage is that OS won't create restrictions, my php code will (i'm losing the advantage of users/groups permissions between different websites).
notice that open_basedir can cause you some hassle, make sure you exclude correct paths (or disable it).
also, there are some minor differences between fastCGI and suPHP (i believe it won't cause you too much trouble).

Is it possible to create ftp users and assign them access to select folders using php?

I just needed to know that is it possible in php to create an ftp user, and then create folders on the server and grant ftp access to selected folders for the ftp user created.
Thanks again!
Native PHP can not do this. The task is way out of PHP's scope.
Depending on the server OS and FTP server software used, however, PHP could call some shell scripts (or WMI / PowerShell scripts on Windows) that accomplish the task. This is not trivial to set up, though, especially not if it's to be done safely (without giving the PHP process root level privileges).
The question may be better suited on Serverfault.com.
There are a few web hosting panels written in PHP that crate ftp accounts among other things so it's definitely possible.
The exact procedure depends completely on the FTP server you use. It may involve creating new Unix user accounts.
This is more an FTP or operating system question than a PHP question though as you need to shell out to do the configuration. As Pekka said you may have more luck asking on Serverfault if you include the details of your setup.
No but if I'm not mistaking you could do something like this
Create a shell script (ftp.sh) that's has SUID (make sure it's owned by root and only can be read/written by root) that creates users, sets the permissions, etc
Call the script from php
system("./ftp.sh ".escapeshellarg($newUsername)." ".escapeshellarg($newPassword))
However I'm pretty sure there are more secure/correct ways of doing this. I can definitely see this becoming a security nightmare.
The answer is "Yes" if the web process where the script runs allows changes on the FTP settings e.g adding users, group etc. either by native PHP function or additional "Shell script" and it would be "No" if the web process doesn't have access nor privilege to make changes.

Securing a shared lighttpd setup

(Yes, I know that questions pertaining to lighttpd fit better on SF, but I thought it was more apt to be asked here since it's primarily concerned with security policy.)
We're planning to set up a small web server in my college, so that people could get some web space to put up web pages and the like. They could also upload PHP pages. The whole setup runs from within a chroot jail.
We are thinking about using the same infrastructure to put up some more services, for instance a discussion forum. My problem is, putting the forum in the same document root (or indeed, the same chrooted environment) pretty much allows any user to place small PHP scripts in their directories that can access the forum configuration files (using, say, file_get_contents). This is a massive security risk! Is there any way to solve this issue, short of disabling PHP for the user accounts, and only keeping it enabled for the discussion forum and the like, or serve the forum elsewhere and proxy it using lighttpd?
I doubt setting ownerships/permissions would do anything to fix this, since, the way I see it, the PHP FastCGI process is spawned by the web server, and hence, any page that can be accessed by the server (they all must be, seeing how it is the server that must ultimately serve them) can be accessed by the PHP scripts uploaded by a user.
Any help would be appreciated!
Well, a few points.
First off, while Lighttpd is GREAT for high performance needs, it was not designed to be used in a shared host setting. Apache would likely be the better choice for that, since it supports things like .htaccess...
Secondly, PHP does not need to be run as the same user as Lighttpd. You can use the spawn_fcgi program to launch each fastcgi listener as the user of that website. You would declare a fastcgi backend for each virtual host. Note, that you likely won't be able to use any of the built in vhost modules (simple_vhost, etc). Simply use the regular expression matching:
Either by IP and Port:
$SERVER["socket"] == "127.0.0.2:80" {
fastcgi.server = (
".php" => (
"username" => (
"socket" => "/tmp/user_php.fastcgi",
)
)
)
)
Or by host name:
$HTTP["host"] =~ "example\.com" {
# ...
}
You would likely need to modify the init script to also execute spawn_fcgi to launch the php processes for each user.
Each user needs to have its own Linux user account. Then you need to use SuPHP+LightHTTPD to make sure that the php code is run with the privileges of that user. Next you should make sure that all files are owned by the correct user and chmod 700 or chmod 500 (best for .php files). The last 2 zeros in the chmod, along with suphp makes it such that users cannot file_get_contents() each others files.

php & filesystem +setUID/permissions ... i just don't get it!

i have to admit, i never really completely got the *nix filesystem permission model. oh, the rwxrwxrwx stuff isn't too complicated, but i get confused easily when programs create new files and how i can handle them.
my current problem is the mixture of a (closed source) java-applet that does file uploads over ftp and php (it's on a dedicated server and the data isn't really critical, so i'm not all too concerned about world-writeability).
so, i have two users: ftp (1000) and apache/php (81). groups don't match, so they're basically "others", if i'm correct.
an "import" directory, set to 0777 owned by ftp.
if a visitor acesses the upload page, a subdirectory named after his username is created by my script. let's say, the visitors username is "foo", so it's "import/foo", set to 0777, user 81/php.
next, the visitor uses the java applet to upload a file to this directory (test.jpg). the file's permissions are now rw-r--r--, user ftp.
first question
the first thing i don't understand is: i'm able to unlink that file through php.
why? the users don't match, and the file isn't world writeable.
is this because of the parent directories world-write permission? understandably, i can't chown or chmod through php.
so far no problem, because as long as i can read and unlink, everythings ok.
second question
the java applet is able to upload whole directories, which is nice. if i do this, the new subdirectory import/foo/test has permissions rwxr-xr-x/ftp. the files in this directory are rw-r--r--/ftp.
now i'm out of luck. i can't do anything with those files (besides reading, which i do successfully), no unlinking, no chmod/chowning. they just sit around and gobble up diskspace.
so, what's the plan behind the default-permissions new files have? my guess is they have the permission set through umask, as long the creating script doesn't chmod them to something else. am i right?
third question
what can i do about it? i mean, what would a sensible person do? can i/should i change the umask for the ftp user? (i just learned about umask yesterday). i'm not very comfortable with this, as this would affect all ftp traffic, doesn't it? also, the server is dedicated but i'm not an admin, so my access is restricted.
i just had another idea. before starting this post i read up on the basic linux permission stuff. first, the sticky bit isn't set anywhere in the directory chain. and then, there it was: the "set user ID bit".
so, my current plan is to write a simple shell script with owner ftp that is other-executable with setuid. the script just transfers the file in the import directories ownership to user php.
then, after each import i just exec() that file from my php-script and process files further.
would that work? and more important: is that clean and legal? or would the sysadmin put a bounty on my head?
thx a lot!
update: i just tried to set the uid bit (4755) through winscp (through an ftp connection), but it somehow doesn't work - it seems to "forget" only the uid bit (the other bits get set). why is that? why can't the owner set the uid himself? is that server-specific or generally the case?
update 2:
wikipedia says it all
Due to the increased likelihood of security flaws, many operating systems ignore the setuid attribute when applied to executable shell scripts.
is it still possible for user root to set the uid-bit?
First answer
Correct, you have permission to modify the directory so you can unlink the file. Whether that file is readable or writable to you is irrelevant.
Second answer
Yes you are correct that the user's default umask will be used unless the script/applet then chmods the file permissions to something else
Third answer
Setting the default umask for ftp is the simplest solution, but as you say this affects all files then created by the ftp user. If that user is only used for the upload via the applet (and it should be really) then this isn't really an issue I'd say.
The other option is to have a cron job running that executes a script (like you suggest), chmoding/owning the files (and maybe virus scanning them etc) from the FTP upload area to somewhere on the webroot.
You don't state why having these files readonly to Apache is an issue (or is it the fact that the FTP root isn't under the web root?), maybe clarifying that would help point to a sensible solution? Generally you don't want to trust anything the user has given you unless you've vetted it first.
EDIT - just seen you're not an admin of the machine which makes things difficult.
what i learned today: the setuid bit is often deactivated for scripts.
the solution i've settled on: apache/php gets sudoer-rights for certain scripts (all scripts in one directory outside the webroot) that may run as either the ftp- or apache-user. i can then call those scripts with sudo out of php with system/exec/etc.
i didn't know sudo could be configured in this way. amazing

Categories