Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added time based delay analyzer to fuzzing implementation #5781

Open
wants to merge 18 commits into
base: dev
Choose a base branch
from

Conversation

Ice3man543
Copy link
Member

@Ice3man543 Ice3man543 commented Oct 29, 2024

Proposed changes

Added time delay verification by using alternating requests logic from ZAP to nuclei DAST mode and also added the concept of analyzers allowing more complicated verification checks. (HTTP - Fuzzing only)

Example template:

id: postgres-sqli-time-based

info:
  name: PostgreSQL Time based SQL Injection
  author: pdteam
  severity: critical


http:
  - payloads:
      prefixes:
        - " "
        - "' "
        - "\""
      suffixes:
        - "--"
        - "--"
        - "--"
    attack: pitchfork

    analyzer:
      name: time_delay
      #parameters:
      #  sleep_duration: 10
      #  requests_limit: 6
        
    fuzzing:
      - part: query
        type: postfix
        mode: single
        fuzz:
          # Ported from Ghauri
          # PostgreSQL > 8.1 OR time-based blind (comment)
          - "{{prefixes}}OR [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])){{suffixes}}"
          # PostgreSQL > 8.1 AND time-based blind (comment)
          - "{{prefixes}}AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])){{suffixes}}"
          
    stop-at-first-match: true
    matchers-condition: and
    matchers:
      - type: word
        # Also, DSL part analyzer_details contains detailed analysis
        # from the time delay analyzer.
        part: analyzer
        words:
          - "true"

Screenshot 2024-10-29 at 6 05 04 PM

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

@dwisiswant0
Copy link
Member

By design, users won’t really know how the analyzer_matched variable is defined. It would be better to use the name already set on the analyzer object (ex. time_delay in this case).

Another key point to ensure is that the output type is boolean. So, instead of doing it like this:

    matchers:
      - type: word
        # Also, DSL part analyzer_details contains detailed analysis
        # from the time delay analyzer.
        part: analyzer_matched
        words:
          - "true"

We could go with a more straightforward approach by defining the matcher as:

    matchers:
      - type: dsl
        dsl:
          - time_delay # shorthand: time_delay == true

This is clearer and easier to follow.

@dwisiswant0
Copy link
Member

dwisiswant0 commented Nov 3, 2024

Is time_delay a predefined type? I mean, if it's indeed set up as a specific kind of analyzer, it'd be a lot better to design it in a way that matches the style of matchers / extractors objects - so everything stays more aligned and easier to work with.

Here's what I'm thinking:

analyzer:
  - type: time_delay
    name: delayed # exported
    parameters: {...}
  - type: another_analyzer # what if there's no `name`? Defining `analyzer_N`?
    parameters: {...}

matchers:
  - type: dsl
    dsl:
      - delayed == true

@Ice3man543
Copy link
Member Author

@dwisiswant0 Regarding the first point of part: analyzer_matched, it was done like this to keep it similar to the interactsh_protocol which also is done this way as a separate part and feels more uniform. The second one you mentioned can anyway be done with this as well using something like below

matchers:
      - type: dsl
        dsl:
          - analyzer_matched == true

Regarding the second point, only one analyzer is supposed to be used per check. For instance, the user won't combine time and boolean or xss context together. So it doesn't make sense to allow user to configure multiple of them. I don't see a scenario where we might need to combine multiple. Let me know what you think!

@Ice3man543 Ice3man543 marked this pull request as ready for review November 12, 2024 12:29
Comment on lines 59 to 62
// Default unit is second. If we get passed milliseconds, multiply
if unit, ok := params["time_unit"]; ok {
duration = a.handleCustomTimeUnit(unit.(string), duration)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be more reliable to use time.ParseDuration directly and skip having a custom handler for it? So we could remove the "time_unit" param entirely and make "sleep_duration" a string that gets parsed into time.Duration. What do you think, @Ice3man543?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, will make it like so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants