A presentation at PHPSW Security in in Bristol, UK by Drew McLellan
SECURING DISTRIBUTED SOFTWARE DREW MCLELLAN, PHPSW SEPTEMBER 2016
DEALING WITH BUGS ON A PROJECT WITH RESIDENT DEVS IS EASY
FOR AN UPDATE TO A DEPENDANCY > Read about an update > Download and test the patch > Push it to production
FOR YOUR OWN CODE > Identify the problem > Fix the problem > Test the patch > Push it to production
DEALING WITH BUGS AS A LIBRARY MAINTAINER IS EASY
BUGS IN LIBRARIES > Identify the problem > Fix the problem > Test the patch > Publish a new release > Announce that users should update
BUT WHAT HAPPENS FOR THINGS THAT FALL IN BETWEEN?
PERCH IS A SELF-HOSTED CONTENT MANAGEMENT SYSTEM
PERCH > PHP + MySQL > (GD, Imagick etc) > The WordPress Stack
AN ANTIDOTE TO WORDPRESS
PERCH > No reliance on dozens of third party plugins > Stable and reliable, set and forget > Update when you work on the site, not in between > Excellent security track record
PROJECT-WORK FRIENDLY
EXCELLENT SECURITY TRACK RECORD
FROM MAY 2009 TO NOVEMBER 2015: NO EXPLOITABLE SECURITY ISSUES
WE GOT AN EMAIL… From a user saying they could hack our online demo server and download a list of all our customers and would we pay them for this information?
WE KNEW TWO THINGS
THEY FAILED TO REALISE WE COULD JUST LOOK AT OUR LOGS
FROM THE LOGS > I could see they’d uploaded a PHP webshell > I could see how they’d uploaded it, which lead me directly to the bug > I could also see that even though they’d uploaded it, our server wouldn’t run it
WEBSHELL ATTACKS
WEBSHELL I wasn’t familiar with these Single page PHP script that provides a web console for executing shell commands and causing havoc
TWO THINGS NEED TO HAPPEN FOR THE ATTACK TO WORK 1. The attacker needs to be able to get the script onto the server 2. The script needs to be able to execute via a standard HTTP request
IT WAS POSSIBLE TO GET THE FILE ONTO THE SERVER > Our demo server is well configured, so it failed at the second part > the script couldn’t run
PERCH HAS PLUGINS FOR USING RICH EDITORS ON TEXTAREAS
F'KING WYSIWYG > These can be plain text, Markdown, Textile, or HTML > As long as the editor enhances an HTML textarea input, it’ll work
YOU NEED TO WRITE TWO THINGS 1. A bit of JavaScript to initialise the editor 2. If the editor has a file upload button, a quick PHP script to handle the file upload via our API
UH OH. FILE UPLOADS.
FILE UPLOADS The default editor we include does Markdown and is called MarkItUp. It has a very quick, simple image and file upload script which grabs the file uses the Perch API to add it as content
THE PERCH API HAS TWO POSSIBLE ENTRY POINTS
ONE DESIGNED FOR ON-PAGE USE AS WEB PAGES ARE RENDERED > light, fast, does as little work as possible > ‘runtime’
ONE DESIGNED FOR CONTROL PANEL OPERATIONS > more complex, richer, does far more to assist but uses more resources > ‘admin’ > checks authentication > checks authentication > checks authentication
CHECKS AUTHENTICATION
THE MARKITUP UPLOAD SCRIPT WAS USING THE RUNTIME ENTRY POINT
should have been using the admin entry point > files could be uploaded without first checking that the user was authenticated
ANYTHING COULD POST A FILE TO THE SCRIPT AND IT WOULD UPLOAD IT… … AND HELPFULLY GET A RESPONSE WITH THE URL TO THE UPLOADED FILE. JEEZ.
BUT WE’RE NOT COMPLETELY DAFT
All uploads are processed through a central clearing house that does basics like checking mime types and file extensions You can’t upload a file to Perch if it has a file extension with ‘php’ in it (.php, .php3, .php5). They get saved as .php.txt
THIS HELPS TO ADDRESS THE SECOND PART OF THE ISSUE THEY CAN UPLOAD THE FILE, BUT IT WON’T EXECUTE BECAUSE WE’VE DEFUSED THE FILE EXTENSION
LOOKING AT MY LOG FILES I COULD SEE THIS IN ACTION webshell.php > webshell.php.txt webshell.php5 > webshell.php5.txt
THE DAMAGE WAS:
LOOKING BACK THROUGH SOURCE CONTROL, THIS PROBLEM HAD EXISTED FOR 6 YEARS
Apart from this one guy, no one seemed to have found it > I’d missed it in dozens of code reviews
SO... > We figured the best course of action was to fix it swiftly and move on without drawing specific attention to it. > Entry in the change log said: Fixes bugs in MarkItUp editor
TIME PASSES
A FEW WEEKS LATER WE GOT AN EMAIL FROM SOMEONE CLAIMING THEIR PERCH SITE HAD BEEN HACKED
We get these from time to time - it’s always something else on the server, or the server itself
Except then we got another with the same symptoms
and another, but with more information. A webshell had been uploaded to the Perch resources folder with a .phtml extension.
.phtml
THIS WAS A NEW ONE ON ME I HAD NO IDEA IT WAS USED FOR PHP
.phtml WAS THE FILE EXTENSION FOR PHP 2
.phtml FILES COULD BE UPLOADED WITHOUT BEING DEFUSED which was no big deal because we don’t have our web servers configured to run random file extensions we’ve never heard of. So no problem. … but wait.
SOME OF OUR CUSTOMERS USE REALLY TERRIBLE HOSTING
WHICH IS BADLY CONFIGURED AND MIGHT BE EXPECTING PHP 2 FILES TO BE UPLOADED CRAP
THIS PUT US IN AN ODD SITUATION
a bug in the software was being exploited > but we’d already fixed it weeks ago > but customers weren’t updating their software so they were still vulnerable
THE VENN DIAGRAM OF CUSTOMERS ON BAD HOSTING AND CUSTOMERS UNLIKELY TO APPLY SOFTWARE UPDATES IS ALMOST A PERFECT CIRCLE
EVEN IF WE MADE A LOT OF NOISE ABOUT THIS, WE POSSIBLY WOULDN’T EVEN REACH THE PEOPLE AFFECTED, AND THEY MIGHT NOT BE IN A POSITION TO DO ANYTHING
WE HAD CUSTOMERS ON VERY OLD VERSIONS OF THE SOFTWARE SOMETIMES UP TO 4 OR 5 YEARS OLD. UPDATING TO THE CURRENT VERSION WOULD BE A CHARGEABLE PROJECT THAT WOULD REQUIRE PLANNING AND SCHEDULING.
SO WHAT DO YOU DO?
YOU MAKE 79 INDIVIDUAL PATCH FILES
We produced a drop-in replacement file for 79 previous releases of Perch Updating a site was a case of finding your version, downloading the patch, uploading it to your site Guaranteed to change nothing else but patching the bug
This was important as it needed to be safe to do to a live site If anything needed testing, it would need time scheduling and it wouldn’t get done
We emailed customers and stressed that there was an important security update that needed applying straight away
DOWNSIDES > Generating 79 patches is laborious > We have no way to easily see if a site is patched > That one file doesn’t affect the part of the app that reports its version number > (We could tackle this various ways if it became and issue)
UPSIDES > A easy fix gave customers confidence that we were on top of the problem > A quick and safe-to-apply update meant that customers actually updated > …Or enough updated that it wasn’t worthwhile attackers to continue to waste energy on
WHAT WE LEARNED
THANKS! JOIND.IN/TALK/8062B @DREWM
Managing the security of your own project is one thing - but what happens when your software is installed on tens of thousands of hosting accounts that you don’t control? Find out how those challenges are faced with Perch CMS, and what happened last year when an exploitable security bug with found within a default plugin.
Here’s what was said about this presentation on social media.
We're getting a really good perch war story from @drewm pic.twitter.com/18AHUgIzWG
— PHP South West UK (@phpsw) September 14, 2016
Next up is @drewm speaking to us about securing distributed software. pic.twitter.com/vLSKY5w1kR
— PHP South West UK (@phpsw) September 14, 2016