19 December, 2022

Twelve Days of ZAPmas - Day 8 - Spidering

Twelve Days of ZAPmas - Day 8 - Spidering
Mic Whitehorn
Author: Mic Whitehorn
Share:

Spidering is an automated process that recursively finds and follows all the navigation from an entry point, in such a way that all linked resources should be identified. I rarely use it in penetration testing engagements because I conduct the mapping manually. Burp Suite also shows linked resources that I haven’t navigated to in its site map, so I still get the benefit of knowing what I haven’t seen yet, and having the tool help ensure that I get full coverage. However, if you’re using ZAP as more of an automated tool to automatically detect flaws, you’re likely to make use of its spidering capabilities.

Tool-based Exclusions

Scope is a big deal when testing an application, that’s why I put a big warning about it at the start of this series. Most notably, if you accidentally wander out of scope, you’re likely to attack something you don’t have permission to attack. That’s not something to take lightly, since having permission is the defining characteristic for whether hacking an app is a criminal activity and not.  You should definitely ensure that you’ve correctly defined what is in scope within ZAP, following the guidance processes I went over on Day 5

But you may also want to exclude in-scope paths from certain tools. For example, if you know you have a large subsection of your site that’s entirely static, non-interactive content, you may decide that it’s not worth the time it would take to spider it. To create an exclusion rule for the Spider specifically, you can go to the Sites pane on the left side of the main window, or the History tab which we’ve already used. For my example, I’m going to use the Sites pane. As you might anticipate at this point, I’m going to start by right-clicking the target domain to open the context menu.

ZAP's sites pane with the context menu open, and the Exclude from submenu open, with the spider option highlighted on the submenu.

I chose a particular subpath of my wayfarer.test:3001 domain (the API server for the Wayfarer test app). I navigated to the Exclude from submenu, and I’m going to pick Spider.

ZAP's session properties dialog with the Exclude from Spider options showing, and the newly-added exclusion rule listed.

That’s it. It’s a straightforward and simple process, but it’s good to know the option is available.

Handling Authentication

Caveats

ZAP’s handling of authentication is problematic, especially if it’s not straightforward form-based cookie auth. For handling complex flows (and a number of other tasks), ZAP has powerful scripting capabilities, but it’s a challenge to find the correct details in the documentation for even simple tasks.  If you need to use Bearer tokens or OAuth flows or anything like that, you will be better off obtaining the auth token and just configuring ZAP to inject it into the requests. In the upcoming day on scanning, I’ll show a workaround that accomplishes just that. If you need to use scripting, check out the Zest Scripting video and its sequel by ZAP Project Founder/Lead Simon Bennetts. For cases where you just need to make a request and receive a cookie, it should work as indicated below.

Setting up Authentication in the Context

If you anticipate needing to have the Spider enter an authenticated context, you will obviously need credentials for it. You will also want to determine how the application behaves when you have valid authentication versus when you do not. You can login, and then tamper with a request to remove the valid auth in order to compare. I used the Juice Shop app for this, and saw that when I requested an authenticated route with the Bearer token removed, I got the following. A response body with a json payload containing an error object, with a message of "No authorization header was found" and a code property showing "credentials_required".

This shows the case of a missing token, but what if the token was simply expired? If I had wanted to take the time, I could have waited for it to expire (it was a JWT, so the exp claim was almost certainly there and could be examined). In my case, I made an educated guess that the status property of 401 would be the same, even if the message and code were different. For comparison, the same request with a valid Bearer token returned a status property of the string success.

An HTTP response with a section of the JSON body highlighted, showing a "status" property with a value of "success".

I made note of this. Then I used the History pane to locate a request where I had logged into the application. I right-clicked it to open the context menu, went to the Flag as Context submenu, and found the entry for http://muddybank.test  : JSON-based Auth Login Request. (for a form-urlencoded POST, there’s the Form-based option as well)

ZAP's context menu open, with the "Flag as Context" submenu open, and the option for "muddybank.test - JSON-based auth login request" highlighted.

I chose this particular request because http://muddybank.test was the name of my scope for Juice Shop, and the authentication request submitted the credentials as a JSON payload, as shown below.

An HTTP POST request with a JSON body containing an email and password.

This opened the Session Properties dialog, having automatically navigated to the Authentication options for the context. It prepopulated some of the fields, but I had to rework it a bit. First of all, I made the Login Request POST Data field fit my parameters better, as both Parameter selects defaulted to email.

ZAP's session properties dialog with two highlighted sections. The first section covers 3 fields, the Login Request POST Data shows a JSON structure as in the login request previously shown. The Username parameter dropdown has selected email. The password parameter dropdown has selected password. Each correspond with the respective properties in the json payload. The subsequent section is the Configure Authentication Verification section, with regex patterns set to match the previously identified status: success and status: 401 response bodies.

Second, based on my previous research, I added the Regex patterns to help ZAP determine whether I was logged in or logged out.

The last step in setting up the authentication was to navigate to the Users option on the Session Properties dialog using the menu tree on the left.

The menu of ZAP's session properties dialog with the Users option highlighted.

From here I was able to add my user…

The Users options within the session properties dialog with the Add button highlighted.

And input the credentials.

ZAP's Add a New User pop-up dialog, with the fields filled in to match the user previously used in the example login. The Add button is highlighted.

That should have me setup for authenticated spidering.

Running the Spider

I right-clicked the context I had created for this application, and selected Spider from the context menu.

ZAP's sites pain with the context menu opened on the target host and the Spider option highlighted on the menu.

 

This opened the dialog pictured below. I made sure the Context and User were set, and ran the spidering operation with the Start Scan button.

ZAP's Spider dialo, populated with the context and user that were previously setup.

This opened the Spider tab in the bottom pane of the main ZAP window, and populated it with a bunch of new URLs it had found.

Burp's spider pane with many requests listed.

That’s Spidering. In this case, I saw several resources added to the Alerts tab as well, but generally these were Alerts ZAP had previously discovered from my manual mapping.

In Summary…

This was a quick way to discover a lot of the application surface. I would generally prefer doing it manually, as I said in the beginning, but Spidering is a good setup for using other automated tools, like ZAP’s Automated Scanner which is the topic for Day 9.

Join the professionally evil newsletter