This post is a part of a series of posts related to my Google Summer of Code ‘21 project.

As part of the project, I am working on creating a new add-on (called OAST) for ZAP. This add-on will allow users to exploit out-of-band vulnerabilities on target web applications.

In this post I’m going to share what I’ve been working on and what my next steps are going to be.

The First Commit

I started off with creating a new add-on in the zap-extensions GitHub repository.

GitHub Pull Request in zap-extensions: oast: Initial Commit
Pull Request on GitHub

The Add-On File Structure

Then, I looked at how classes in the add-on package should be organised. This is because we want to design the OAST add-on in such a way such that it is easy for users to use any OAST service (like BOAST or TukTuk) for receiving outbound requests.

This means that if someone wants to use an OAST service that isn’t supported by ZAP, we want them to be able to look at the existing code and figure out how to add support for that service without any major challenges.

With this in mind, I proposed the following two directory structures for the add-on in our IRC channel:

Option 1 Option 2
oast
├── api
│   ├── AbstractOastApi.java
│   ├── BoastApi.java
│   └── CallbackApi.java
├── automation
│   ├── AbstractAutomationOastJob.java
│   ├── AutomationBoastJob.java
│   └── AutomationCallbackJob.java
├── other
│   ├── BoastRegistrar.java
│   └── CallbackImplementor.java
├── param
│   ├── AbstractParam.java
│   ├── BoastParam.java
│   └── CallbackParam.java
└── ui
    ├── AbstractPanel.java
    ├── BoastPanel.java
    └── OptionsCallbackPanel.java
      
oast
├── AbstractAutomationOastJob.java
├── AbstractOastApi.java
├── AbstractPanel.java
├── AbstractParam.java
├── boast
│   ├── AutomationBoastJob.java
│   ├── BoastApi.java
│   ├── BoastPanel.java
│   ├── BoastParam.java
│   └── BoastRegistrar.java
└── callback
    ├── AutomationCallbackJob.java
    ├── CallbackApi.java
    ├── CallbackImplementor.java
    ├── CallbackParam.java
    └── OptionsCallbackPanel.java
      

…and here are the comments I received:

<psiinon> I like the separate boast package - we can then have another tuktuk one and other ones for any other servers we want to support in the future
<psiinon> but other than that I dont have a strong preference
<thc202> +1 to that

So we decided to go with Option 2.

Moving the Callback Extension to OAST

Before integrating the BOAST service, I decided to move the callback extension from the ZAP core to the OAST add-on. There were two reasons for doing so, as this would enable me to:

  • make use of the existing classes from the callback extension, and
  • focus on extensibility from the very beginning, because there would be two implementations (callback and BOAST) in the very first version of the add-on.

Designing the GUI

For the GUI, I went with a drop down menu that contained the OAST services as options, and the settings in the panel updated based on the selected service.

With some help from StackOverflow, I was able to achieve some decent results.

An animated GIF of the ZAP OAST Options Panel showing how the options for the selected OAST servers are displayed dynamically.
ZAP OAST Options Panel

Other Updates

  • I added a new constant to the HistoryReference class that will be used with HTTP messages received by OAST services in the ZAP database.
  • Added support for registering with a BOAST service. This is still in early stages - I still have to think about and handle possible points of failure (e.g. incorrect BOAST service URI supplied) and write unit tests.

Next Actions

  • Further integrate the BOAST service with ZAP - poll the server for events and display relevant information in the ZAP GUI.
  • Completely move the callback extension to the OAST add-on and then deprecate it in the ZAP core.

Notes

This section contains notes that may benefit my future self.

  • In order to make use of an updated ZAP core feature in add-ons,

    1. Publish a SNAPSHOT version of ZAP to the Maven local repository by running

       ./gradlew publishZapPublicationToMavenLocal -D"maven.javadoc.skip=true"
      

      inside the cloned zaproxy folder on your system.

    2. Add the following lines to the gradle build script of your add-on (e.g. oast.gradle.kts):

       repositories {
           mavenLocal()
           mavenCentral()
       }
      
       dependencies {
           compileOnly("org.zaproxy:zap:2.11.0-SNAPSHOT")
       }
      
    3. This is only a temporary solution - use reflection if pushing to remote repositories or publish a SNAPSHOT to the Maven central repository.