Hack the OWASP Juice Shop Application and Protect It with AWS WAF (part 1)

Índice

Automat-it branded element design

This is the first post in this series about the penetration test of the vulnerable web application, OWASP Juice Shop, and how we can utilize AWS WAF to protect against some hacking techniques.

Problem statement

Nowadays, most software products have web applications, and developing a secure application is challenging. There are many ways to hack a web application, and these techniques and ways to protect against them evolve daily.

The most direct way to protect is to write the application code according to best practices and continuously perform penetration tests. However, this is not always possible because the world is not ideal.

Depending on where you deploy and run your web application, you can get extra protection tools. Automat-IT builds AWS infrastructures for many companies and deploys a Web Application Firewall (WAF) by default in front of web applications.

But how does it actually work? Let’s play with a vulnerable web application and AWS WAF.

OWASP Juice Shop is the most modern and sophisticated insecure web application! It can be used in security training, awareness demos, CTFs, and as a guinea pig for security tools. Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten⁠ and many other security flaws found in real-world applications.

For a detailed introduction, complete list of features, and architecture overview, please visit the official project page.

In this blog series, we will perform a penetration test of the OWASP Juice Shop web application and try to protect it with AWS WAF.

Setup

To install Docker on Amazon Linux 2023 and start the OWASP Juice Shop web application:

sudo yum update -y
sudo yum install -y docker

sudo service docker start
sudo usermod -a -G docker ec2-user

sudo docker run --restart always -d -p 3000:3000 bkimminich/juice-shop

I’ve prepared two identical environments, but one of them is with AWS WAF, and the second one is not:

Two prepared identical environments, but one of them is with AWS WAF, and the second one is not

 

Initially, I’ve enabled one Managed rule group.

OWASP Top 10 — The Complete Ruleset

Based on the FortiWeb web application firewall signatures and updated on a regular basis to include the latest threat information from FortiGuard Labs, the ruleset provides a comprehensive package to help address threats as described in OWASP Top 10

A demo screen

Which has the following list of rules:

Cross-Site-Scripting-01
Cross-Site-Scripting-02
Cross-Site-Scripting-03
SQL-Injection-01
SQL-Injection-02
SQL-Injection-03
Malicious-Robot
Web-Scanner-01
Web-Scanner-02
Web-Scanner-03
OS-Command-Injection-01
OS-Command-Injection-02
Web-Application-Injection-01
Web-Application-Injection-02
Source-Code-Disclosure
Database-Vulnerability-Exploit-01
Database-Vulnerability-Exploit-02
Database-Vulnerability-Exploit-03
Web-Server-Vulnerability-Exploit-01
Web-Server-Vulnerability-Exploit-03
Web-Server-Vulnerability-Exploit-04
Web-Application-Vulnerability-Exploit-01
Web-Application-Vulnerability-Exploit-02
Web-Application-Vulnerability-Exploit-03
Web-Application-Vulnerability-Exploit-04
Web-Application-Vulnerability-Exploit-05
Web-Application-Vulnerability-Exploit-06
Web-Application-Vulnerability-Exploit-07

Rules list

We don’t know what logic is hidden inside the rules, but let’s just start the penetration test.

Start a Penetration Test

Usually, a penetration test begins with Reconnaissance (Information Gathering):

  • Passive Recon: WHOIS lookup, subdomain enumeration (Sublist3rAmass), DNS enumeration, Google dorking, publicly available info (e.g., GitHub, Pastebin) — this is out of scope of the current article
  • Active Recon: Discover exposed endpoints, identify servers and technologies (WappalyzerBuiltWithWhatWeb), port scan (nmap), directory brute-forcing (dirbgobuster, ffuf, etc.)

Let’s try a couple of tools to scan the web server for directories using a dictionary file (Kali Linux),(/usr/share/wordlists/dirb/common.txt). This list contains 4600+ options for enumeration:

 

An example of using web server for directories using a dictionary file

 

There are different lists – some smaller and some bigger. But let’s begin with it and try to discover directories exposed by the web application (without AWS WAF):

Gobuster

$ gobuster dir -u http://open-webapp-1170625636.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://open-webapp-1170625636.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] Exclude Length:          71432
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/api                  (Status: 500) [Size: 3017]
/apis                 (Status: 500) [Size: 3019]
/assets               (Status: 301) [Size: 156] [--> /assets/]
/ftp                  (Status: 200) [Size: 11062]
/profile              (Status: 500) [Size: 1154]
/promotion            (Status: 200) [Size: 6586]
/redirect             (Status: 500) [Size: 3119]
/restaurants          (Status: 500) [Size: 3033]
/rest                 (Status: 500) [Size: 3019]
/restore              (Status: 500) [Size: 3025]
/restored             (Status: 500) [Size: 3027]
/restricted           (Status: 500) [Size: 3031]
/robots.txt           (Status: 200) [Size: 28]
/snippets             (Status: 200) [Size: 792]
/video                (Status: 200) [Size: 10075518]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

ffuf — Fuzz Faster U Fool

$ ffuf -u http://open-webapp-1170625636.us-east-1.elb.amazonaws.com/FUZZ -w /usr/share/wordlists/dirb/common.txt -fs 71432 -t 10 -timeout 30


        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://open-webapp-1170625636.us-east-1.elb.amazonaws.com/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 30
 :: Threads          : 10
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 71432
________________________________________________

api                     [Status: 500, Size: 3017, Words: 235, Lines: 50, Duration: 155ms]
apis                    [Status: 500, Size: 3019, Words: 235, Lines: 50, Duration: 155ms]
assets                  [Status: 301, Size: 156, Words: 6, Lines: 11, Duration: 120ms]
ftp                     [Status: 200, Size: 11062, Words: 1568, Lines: 357, Duration: 117ms]
profile                 [Status: 500, Size: 1154, Words: 159, Lines: 50, Duration: 159ms]
promotion               [Status: 200, Size: 6586, Words: 560, Lines: 177, Duration: 217ms]
redirect                [Status: 500, Size: 3119, Words: 244, Lines: 50, Duration: 126ms]
rest                    [Status: 500, Size: 3019, Words: 235, Lines: 50, Duration: 134ms]
restricted              [Status: 500, Size: 3031, Words: 235, Lines: 50, Duration: 146ms]
restored                [Status: 500, Size: 3027, Words: 235, Lines: 50, Duration: 148ms]
restaurants             [Status: 500, Size: 3033, Words: 235, Lines: 50, Duration: 149ms]
restore                 [Status: 500, Size: 3025, Words: 235, Lines: 50, Duration: 151ms]
robots.txt              [Status: 200, Size: 28, Words: 3, Lines: 2, Duration: 114ms]
snippets                [Status: 200, Size: 792, Words: 1, Lines: 1, Duration: 151ms]
video                   [Status: 200, Size: 10075518, Words: 0, Lines: 0, Duration: 0ms]
Video                   [Status: 200, Size: 10075518, Words: 0, Lines: 0, Duration: 0ms]
:: Progress: [4614/4614] :: Job [1/1] :: 60 req/sec :: Duration: [0:01:16] :: Errors: 0 ::

The results are similar.

Let’s do the same on the WAF-protected application:

$ gobuster dir -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://waf-webapp-617047269.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] Exclude Length:          71432
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/api                  (Status: 500) [Size: 3017]
/apis                 (Status: 500) [Size: 3019]
/assets               (Status: 301) [Size: 156] [--> /assets/]
/ftp                  (Status: 200) [Size: 11062]
/profile              (Status: 500) [Size: 1154]
/promotion            (Status: 200) [Size: 6586]
/redirect             (Status: 500) [Size: 3119]
/rest                 (Status: 500) [Size: 3019]
/restaurants          (Status: 500) [Size: 3033]
/restore              (Status: 500) [Size: 3025]
/restricted           (Status: 500) [Size: 3031]
/restored             (Status: 500) [Size: 3027]
/robots.txt           (Status: 200) [Size: 28]
/server-status        (Status: 403) [Size: 118]
/server-info          (Status: 403) [Size: 118]
/snippets             (Status: 200) [Size: 792]
Progress: 4614 / 4615 (99.98%)[ERROR] context deadline exceeded (Client.Timeout or context cancellation while reading body)
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

Gobuster still works.

FFUF resulted in all 403 codes, so WAF noticed something suspicious:

$ ffuf -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com/FUZZ -w /usr/share/wordlists/dirb/common.txt -fs 71432 -t 10 -timeout 30

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://waf-webapp-617047269.us-east-1.elb.amazonaws.com/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 30
 :: Threads          : 10
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 71432
________________________________________________

.bash_history           [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.config                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 116ms]
.cache                  [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 116ms]
.git/HEAD               [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 116ms]
.forward                [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 120ms]
.cvsignore              [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 122ms]
.history                [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 125ms]
                        [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 125ms]
.cvs                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 126ms]
.bashrc                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 126ms]
.htpasswd               [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.hta                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 116ms]
.htaccess               [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.listing                [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
.listings               [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
.mysql_history          [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.passwd                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.profile                [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.rhosts                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 117ms]
.perf                   [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 119ms]
.subversion             [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 113ms]
.ssh                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
.sh_history             [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
.svn                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.svn/entries            [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.swf                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
@                       [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
.web                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
_                       [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
_adm                    [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
_archive                [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 113ms]
_admin                  [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
_ajax                   [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 114ms]
_assets                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
_backup                 [Status: 403, Size: 118, Words: 3, Lines: 7, Duration: 115ms]
......................................................

 

You can see metrics in the AWS WAF console:

Metrics shown in the AWS WAF console:

And traffic characteristics:

Traffic characteristics shown in the AWS WAF console:

Details about the blocked requests:

Details about the blocked requests

 

But anyway, we got the successful scan from Gobuster, so we need rules other than the Fortinet-all_rules Managed rule group.

There are other managed WAF rules, for example, “Core rule set”:

Contains rules that are generally applicable to web applications. This provides protection against exploitation of a wide range of vulnerabilities, including those described in OWASP publications.

Selecting the Core rule set in the AWS WAF

Let’s add it:

Adding a demo rule in the AWS WAF

 

And rerun the Gobuster:

$ gobuster dir -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://waf-webapp-617047269.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] Exclude Length:          71432
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================

Error: the server returns a status code that matches the provided options for non existing urls. http://waf-webapp-617047269.us-east-1.elb.amazonaws.com/8454b721-1d27-47f7-8f1f-d356c8556219 => 403 (Length: 118). To continue please exclude the status code or the length



### IGNORE 403 ERRORS

$ gobuster dir -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt -b 403
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://waf-webapp-617047269.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   403
[+] Exclude Length:          71432
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

 

Now AWS WAF protects our application from scanning, but let’s dive deeper.

Maybe the new ruleset relies only on the “User Agent” header. Here is a sample of the blocked request:

A sample of the blocked request in AWS WAF

Obviously, the User-Agent is not good:

A screenshot of AWS WAF showing the User-Agent is not good:

Let’s change it for Gobuster:

$ gobuster dir -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://waf-webapp-617047269.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] Exclude Length:          71432
[+] User Agent:              Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.config              (Status: 403) [Size: 520]
/akeeba.backend.log   (Status: 403) [Size: 520]
/apis                 (Status: 500) [Size: 3019]
/api                  (Status: 500) [Size: 3017]
/assets               (Status: 301) [Size: 156] [--> /assets/]
/awstats.conf         (Status: 403) [Size: 520]
/development.log      (Status: 403) [Size: 520]
/ftp                  (Status: 200) [Size: 11062]
/php.ini              (Status: 403) [Size: 520]
/production.log       (Status: 403) [Size: 520]
/profile              (Status: 500) [Size: 1154]
/promotion            (Status: 200) [Size: 6586]
/redirect             (Status: 500) [Size: 3119]
/restore              (Status: 500) [Size: 3025]
/rest                 (Status: 500) [Size: 3019]
/restaurants          (Status: 500) [Size: 3033]
/restored             (Status: 500) [Size: 3027]
/restricted           (Status: 500) [Size: 3031]
/robots.txt           (Status: 200) [Size: 28]
/server-info          (Status: 403) [Size: 520]
/server-status        (Status: 403) [Size: 520]
/snippets             (Status: 200) [Size: 792]
/spamlog.log          (Status: 403) [Size: 520]
/web.config           (Status: 403) [Size: 520]
/WS_FTP.LOG           (Status: 403) [Size: 520]
/Video                (Status: 200) [Size: 10075518]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

 

And we see the partially successful scan again (code 200).

Let’s now add a Rate-based rule, for example, 300 per minute:

Adding a Rate-based rule in AWS WAF Setting rate-limiting criteria in AWS WAF

 

Scan again:

$ gobuster dir -u http://waf-webapp-617047269.us-east-1.elb.amazonaws.com -w /usr/share/wordlists/dirb/common.txt --exclude-length 71432 -t 10 -o gobuster_results.txt -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://waf-webapp-617047269.us-east-1.elb.amazonaws.com
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] Exclude Length:          71432
[+] User Agent:              Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.config              (Status: 403) [Size: 520]
/akeeba.backend.log   (Status: 403) [Size: 520]
/api                  (Status: 500) [Size: 3017]
/apis                 (Status: 500) [Size: 3019]
/assets               (Status: 301) [Size: 156] [--> /assets/]
/awstats.conf         (Status: 403) [Size: 520]
/demo                 (Status: 403) [Size: 520]
/delicious            (Status: 403) [Size: 520]
/demo2                (Status: 403) [Size: 520]
/deployment           (Status: 403) [Size: 520]
/demos                (Status: 403) [Size: 520]
/departments          (Status: 403) [Size: 520]
/deploy               (Status: 403) [Size: 520]
/deny                 (Status: 403) [Size: 520]
/denied               (Status: 403) [Size: 520]
/descargas            (Status: 403) [Size: 520]
/design               (Status: 403) [Size: 520]
/designs              (Status: 403) [Size: 520]
/desktop              (Status: 403) [Size: 520]
/desktopmodules       (Status: 403) [Size: 520]
/destinations         (Status: 403) [Size: 520]
/desktops             (Status: 403) [Size: 520]
/deutsch              (Status: 403) [Size: 520]
/details              (Status: 403) [Size: 520]
/detail               (Status: 403) [Size: 520]
/dev                  (Status: 403) [Size: 520]
/dev2                 (Status: 403) [Size: 520]
/dev60cgi             (Status: 403) [Size: 520]
/developer            (Status: 403) [Size: 520]
/development          (Status: 403) [Size: 520]
/development.log      (Status: 403) [Size: 520]
/develop              (Status: 403) [Size: 520]
.....................................
/zoeken               (Status: 403) [Size: 520]
/zipfiles             (Status: 403) [Size: 520]
/zips                 (Status: 403) [Size: 520]
/zimbra               (Status: 403) [Size: 520]
/zoom                 (Status: 403) [Size: 520]
/zope                 (Status: 403) [Size: 520]
/zt                   (Status: 403) [Size: 520]
Progress: 4614 / 4615 (99.98%)
/zorum                (Status: 403) [Size: 520]
===============================================================
Finished
===============================================================

As we saw, there are many ways to perform discovery for further hacking and many ways to protect against them.

Protecting an Exposed Directory

Earlier, we found several directories that can be targets for further discovery or attacks, for example, /ftp

===============================================================
Starting gobuster in directory enumeration mode
===============================================================
..........
/ftp                  (Status: 200) [Size: 11062]
..........

 

The first thing we can do is go and see:

Checking ftp in AWS WAP

Sometimes we can find sensitive information:

A screenshot showing an example of finding sensitive information

Ideally, you would handle such things on the application side and not expose what should not be explicitly exposed. But let’s assume someone made a mistake, and now we need to fix it as soon as possible, while developers fix the code:

If you want to allow or block web requests based on strings that match a regular expression (regex) pattern that appears in the requests, create one or more regex match conditions. A regex match condition is a type of string match condition that identifies the pattern that you want to search for and the part of web requests, such as a specified header or the query string, that you want AWS WAF to inspect for the pattern.

I use URI path matches regex /ftp*

A screenshot creating a new rule in AWS WAF A screenshot showing creating a new rule in AWS WAF

 

Try to reach the /ftp directory again — 403 Forbidden. This part is protected:

A screenshot showing a 403 Forbidden page

 

Conclusion

This is the first post in this series about the penetration test of the vulnerable web application, OWASP Juice Shop, and how we can utilize AWS WAF to protect against some hacking techniques.

We looked at initial application scanning, enumeration, AWS-managed, and custom WAF rules.

Stay tuned for our next post, where we will look at SQL injections and other interesting cases.