I often feel that blue teaming doesn’t always get the love it deserves, so we decided that this months SkillSec would be about Red vs Blue. For those that may not be familiar with these terms, Red is the “offensive” side of security (think “attack simulation”) and blue is about defending i.e. detecting and stopping the attackers. As is often said, blue can be more challenging as you have to defend every weakness whereas with Red, you only have to find one weakness. Both are important to consider.
Whilst Digital Interruption is best known for our offensive security teams, we provide support and advice around blue teaming which we find to be especially important for some of our smaller clients. In this workshop, we wanted to demonstrate a few “easy wins” for the defenders and show how it was possible to add in defences that would protect a vulnerable application even when it’s not possible to fix the application code.
We start with a vulnerable web application – something that contains security issues we see fairly often during penetration tests; the most critical would allow an attacker to gain access to the server via a malicious file upload.
For demo purposes, we only used services provided by Amazon using AWS, however depending on budget and expertise, other solutions may be more appropriate.
Network
The network we’re using is setup as follows:
Offensive Testing
First, we need to discover the security vulnerabilities. When navigating to the web application, we’re greeted with a page which asks for our name. This is vulnerable to cross site scripting.
Looking at the page source, we see the image is located at uploads/di-logo.png. By making an educated guess, or by bruteforcing files, we discover the /upload.html page.
This is where we are supposed to upload an image. There is a protection which checks only a valid image can be uploaded, however by adding the GIF header to a PHP file, we’re able to bypass this security control and upload a PHP web shell.
We now have the ability to execute commands on the server and as an attacker, we’re able to run our super malicious script from https://raw.githubusercontent.com/DigitalInterruption/Resources/master/payload-rvb.sh. This script demonstrates some basic malicious actions such as reaching out to malicious domains and trying to brute force SSH servers on the internal network.
We’ll also log into the server from a known malicious IP simulating a private key being known to an attacker (possibly though the key being leaked online).
With this, we have a demo of a fairly standard offensive/penetration test where the goal is to uncover and exploit security vulnerabilities. Penetration testing can be a great way of figuring out what attacks should be defended against, however it can be expensive and cause a fair amount of stress for small companies that may not have built the application that needs to be fixed. If there is limited budget or the software is not in our control, sometimes fixing the code isn’t possible.
The Blue Team
Using AWS, we will try to remeditate the above issues by adding in a Web Application Firewall. This will detect when someone tries to exploit a vulnerability in our web application and block the request. It should be noted that a good penetration tester will try to find ways to bypass the WAF as part of the security test.
Before we add in the WAF, we may want to know when an attack occurs. AWS has GuardDuty for this. GuardDuty looks at several of the logging sources available to it to understand when an attack is occurring. With this information, GuardDuty can perform multiple actions including bringing down the server or sending the findings to someone so they can be analysed. In this demo, we’ll have GuardDuty send logs to a slack channel when it detects an attack is occurring.
GuardDuty is incredibly easy to configure. In the GuardDuty console, we can click the “Get Started” button and “Enable GuardDuty” when we navigate to it for the first time.
GuardDuty has a list of known bad/malicious IP addresses it will detect attacks from. If we want to add to this, we can add a threat list which is a text file hosted on an S3 bucket.
To enable slack integration, we can use CloudWatch. CloudWatch monitors for events and perform actions based on them.
The following rule listens for GuardDuty findings and calls a lambda function we created – guardduty-to-slack.
This lambda function is as follows (taken from https://github.com/keattang/guard-duty-to-slack-lambda):
This function then can to be configured with a slack webhook (however, this is outside the scope of this post). When configured with the slack webhook, any GuardDuty events will then be sent to the desired slack channel. This will include events such as when someone from a “bad” IP address logs into the server, when someone performs a port scan against a host and other common actions of a compromised host. More information on the type of findings can be seen in the AWS help.
An important thing to note is how these alerts are to be used. Too many and they are unmanageable and can get ignored. Not enough and there isn’t enough information to detect when an attack is occurring. A big part of a reliable blue team is being able to configure this correctly.
WAF
Now on to the final part of the workshop where we wanted to demonstrate adding a WAF to block attacks at the protocol level.
The first thing we do is create a String match condition which checks whether the body of a request contains the string “
A new rule can then be added with the condition created above.
In our final step, we can add the newly created rule into our web Access Control List.