The Platform as a Service (PaaS) for cloud based web applications is a fantastic platform for entry-level rapid application development prototyping, all the way through to enterprise-grade scalable application ecosystems. With that said, there are some caveats with regard to PaaS security that are often overlooked when evaluating PaaS as a deployment model.
PaaS security - is our understanding correct?
There is a common misconception that choosing a PaaS offering over a traditional Infrastructure as a Service (IaaS) deployment means that security is handled by the service provider, rather than the customer. And this is true to some extent - All the water and feeding of the compute layer is handled by the service provider who will take care of maintenance, patching and general OS (Operating System) hygiene. That's great, right?
We agree - and this is part of the shared responsibility model -- this is where things tend to get blurry. The responsibility of application security belongs to the customer, not the service or cloud provider. What this essentially means is that all of our favourite OWASP Top 10 and CVE application vulnerability prevention and remediation responsibilities are ours.
Note: To better understand the shared responsibility model we can always compare it with pizza!.
Cloud based example
Let us see a real-world example of a traditional PaaS deployment model in Azure.
We've gone through and registered the following domain:
That includes a simple PHP application with a MySQL data source.
Now, lets take a look at one of the common pitfalls developers make when writing code that requires OS specific commands. Examples that come to mind are
gzipping a collection of files, running external scripts within their code and so forth.
$archive = $_GET['archive_id'];
$archive_output = shell_exec('tar -zcvf ' . $archive);
echo 'Archiving directory by id: ' . $archive;
Without proper input sanitisation and validation, the pattern of accepting user input through web application parameters is often the root cause of key vulnerabilities including:
- XSS reflective - variations also include DOM based XSS
- XSS stored - sometimes referred to as persistent XSS
- OS Command injection - sometimes shortened to just command injection - e.g., shellshock
- SQL injection - SQLi is over 15 years old and still ranks in the top-5 most pervasive vulnerabilities
- Local and Remote File Inclusion - sometimes referred to as direct object reference
and the list goes on!
Lets examine the command injection vulnerability problem with regards to unsanitised user input on our Azure host
What we observe is the output from the GET query in the HTML response indicating an injection vulnerability. Once we've identified what sort of injection vulnerability exists, it's simply a case of enumerating through common fuzzing values and observing the HTML response.
In our case, we've identified command injection via the
dir command (*nix equivalent would be
Reverse shell time!
Lets now craft up a reverse shell
txt file (I'll be writing up an article describing the differences and trade-offs between a
reverse shell). In a nutshell this establishes a two-way connection between client and server. In our case it is the server who initiates the connection with the client (attacker) machine making it a reverse shell. We could've picked a number of languages to use as our reverse shell. For example:
python. We decided on
powershell - our favourite enterprise white-listed application!
In our case we have instructed our
powershell reverse shell to dial out to our machine on 18.104.22.168 which is listening on port 443. Lets urlencode that payload so we can pass to the
archive web parameter:
Another alternative is to hexencode our entire payload -- this technique is much more effective if WAF bypass is required:
Now lets get our
ncat listener up and running and prepare our
And we've got our reverse shell! This is validated via the
whoami command which as we can see is running in the context of IIS apppool\phpsqlapp.
Note: You can view this sequence of events as a short gif here. To avoid remote
C&C(Command & Control) through the shell technique would be to apply layer-3 egress routing restrictions from the app service. This requires an ASE (App Service Environment) and we'll cover that in a separate topic. Essentially, an ASE is a secure, dedicated environment with applicable network security policies.
At this point the security tester has control over both the OS environment and application source code. This includes the ability to traverse the file system, read, write and execute files and further retrieve payloads from external sources.
What has been demonstrated is that while PaaS deployment models do in fact remove the need for system administrators and developers to interface with the underlying OS directly, the idea that it's abstracted away entirely and can be overlooked from an application security perspective is not exactly the case.
In the next article we'll dig a little deeper into application security side of things and explore what DDoS/ DoS (Distributed/ Denial of Service) means in the context of the application layer, rather than the network layer.