Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bbot/core/helpers/interactsh.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ async def poll(self):

try:
r = await self.parent_helper.request(
f"https://{self.server}/poll?id={self.correlation_id}&secret={self.secret}", headers=headers
f"https://{self.server}/poll?id={self.correlation_id}&secret={self.secret}",
headers=headers,
timeout=15,
)
if r is None:
raise InteractshError("Error polling interact.sh: No response from server")
Expand Down
13 changes: 12 additions & 1 deletion bbot/modules/lightfuzz/lightfuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ class lightfuzz(BaseModule):
"force_common_headers": False,
"enabled_submodules": ["sqli", "cmdi", "xss", "path", "ssti", "crypto", "serial", "esi"],
"disable_post": False,
"avoid_wafs": True,
}
options_desc = {
"force_common_headers": "Force emit commonly exploitable parameters that may be difficult to detect",
"enabled_submodules": "A list of submodules to enable. Empty list enabled all modules.",
"disable_post": "Disable processing of POST parameters, avoiding form submissions.",
"avoid_wafs": "Avoid running against confirmed WAFs, which are likely to block lightfuzz requests",
}

meta = {
Expand All @@ -38,6 +40,7 @@ async def setup(self):
self.disable_post = self.config.get("disable_post", False)
self.enabled_submodules = self.config.get("enabled_submodules")
self.interactsh_disable = self.scan.config.get("interactsh_disable", False)
self.avoid_wafs = self.scan.config.get("avoid_wafs", True)
self.submodules = {}

if not self.enabled_submodules:
Expand Down Expand Up @@ -167,8 +170,16 @@ async def finish(self):
except InteractshError as e:
self.debug(f"Error in interact.sh: {e}")

# If we've disabled fuzzing POST parameters, back out of POSTPARAM WEB_PARAMETER events as quickly as possible
async def filter_event(self, event):
# Unless configured specifically to do so, avoid running against confirmed WAFs
if self.avoid_wafs and "waf" in event.tags:
# Use parsed_url.geturl() for both URL and WEB_PARAMETER events
parsed_url = getattr(event, "parsed_url", None)
url = parsed_url.geturl() if parsed_url else "unknown"
self.debug(f"Skipping {event.type} because it is likely to be blocked by a WAF. URL: {url}")
return False

# If we've disabled fuzzing POST parameters, back out of POSTPARAM WEB_PARAMETER events as quickly as possible
if event.type == "WEB_PARAMETER" and self.disable_post and event.data["type"] == "POSTPARAM":
return False, "POST parameter disabled in lightfuzz module"
return True
Expand Down
2 changes: 1 addition & 1 deletion bbot/presets/web/lightfuzz-heavy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
description: Discover web parameters and lightly fuzz them for vulnerabilities, with more intense discovery techniques, including POST parameters, which are more invasive. Uses all lightfuzz modules, and adds paramminer modules for parameter discovery.
description: Discover web parameters and lightly fuzz them for vulnerabilities, with more intense discovery techniques, including POST parameters, which are more invasive. Uses all lightfuzz modules, and adds paramminer modules for parameter discovery. Avoids running against confirmed WAFs.

include:
- lightfuzz-medium
Expand Down
1 change: 1 addition & 0 deletions bbot/presets/web/lightfuzz-light.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ config:
lightfuzz:
enabled_submodules: [path,sqli,xss] # only look for the most common vulnerabilities
disable_post: True # don't send POST requests (less aggressive)
avoid_wafs: True

conditions:
- |
Expand Down
2 changes: 1 addition & 1 deletion bbot/presets/web/lightfuzz-medium.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
description: Discover web parameters and lightly fuzz them for vulnerabilities. Uses all lightfuzz modules, without some of the more intense discovery techniques. Does not send POST requests. This is the default lightfuzz preset; if you're not sure which one to use, this is a good starting point.
description: Discover web parameters and lightly fuzz them for vulnerabilities. Uses all lightfuzz modules, without some of the more intense discovery techniques. Does not send POST requests. This is the default lightfuzz preset; if you're not sure which one to use, this is a good starting point. Avoids running against confirmed WAFs.

include:
- lightfuzz-light
Expand Down
1 change: 1 addition & 0 deletions bbot/presets/web/lightfuzz-superheavy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ config:
lightfuzz:
force_common_headers: True # Fuzz common headers like X-Forwarded-For even if they're not observed on the target
enabled_submodules: [cmdi,crypto,path,serial,sqli,ssti,xss,esi]
avoid_wafs: False
excavate:
speculate_params: True # speculate potential parameters extracted from JSON/XML web responses
2 changes: 1 addition & 1 deletion bbot/presets/web/lightfuzz-xss.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
description: Discover web parameters and lightly fuzz them, limited to just GET-based xss vulnerabilities. This is an example of a custom lightfuzz preset, selectively enabling a single lightfuzz module.
description: Discover web parameters and lightly fuzz them, limited to just GET-based xss vulnerabilities. Avoids running against confirmed WAFs. This is an example of a custom lightfuzz preset, selectively enabling a single lightfuzz module.

modules:
- httpx
Expand Down
86 changes: 86 additions & 0 deletions bbot/test/test_step_2/module_tests/test_module_lightfuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -2060,3 +2060,89 @@ class Test_Lightfuzz_envelope_isolation_paddingoracle_reflecting(Test_Lightfuzz_
}
},
}


# Test filter_event method with WAF tags
class Test_Lightfuzz_filter_event(ModuleTestBase):
targets = ["http://127.0.0.1:8888"]
modules_overrides = ["httpx", "lightfuzz"]
config_overrides = {
"interactsh_disable": True,
"modules": {
"lightfuzz": {
"enabled_submodules": ["xss"],
"avoid_wafs": True,
}
},
}

async def setup_after_prep(self, module_test):
# Create test events with WAF tags
self.url_event_with_waf = module_test.scan.make_event(
"http://127.0.0.1:8888/",
"URL",
module_test.scan.root_event,
module="httpx",
tags=["status-200", "distance-0", "waf"],
)

self.web_param_event_with_waf = module_test.scan.make_event(
{
"host": "127.0.0.1",
"type": "GETPARAM",
"name": "test",
"original_value": "value",
"url": "http://127.0.0.1:8888/",
"description": "Test parameter",
},
"WEB_PARAMETER",
module_test.scan.root_event,
module="excavate",
tags=["distance-0", "waf"],
)

self.url_event_without_waf = module_test.scan.make_event(
"http://127.0.0.1:8888/",
"URL",
module_test.scan.root_event,
module="httpx",
tags=["status-200", "distance-0"],
)

self.web_param_event_without_waf = module_test.scan.make_event(
{
"host": "127.0.0.1",
"type": "GETPARAM",
"name": "test",
"original_value": "value",
"url": "http://127.0.0.1:8888/",
"description": "Test parameter",
},
"WEB_PARAMETER",
module_test.scan.root_event,
module="excavate",
tags=["distance-0"],
)

async def test_filter_event(self, module_test):
lightfuzz_module = module_test.scan.modules["lightfuzz"]

# Test URL event with WAF tag - should be filtered out
result = await lightfuzz_module.filter_event(self.url_event_with_waf)
assert result is False, "URL event with waf tag should be filtered out"

# Test WEB_PARAMETER event with WAF tag - should be filtered out
result = await lightfuzz_module.filter_event(self.web_param_event_with_waf)
assert result is False, "WEB_PARAMETER event with waf tag should be filtered out"

# Test URL event without WAF tag - should not be filtered
result = await lightfuzz_module.filter_event(self.url_event_without_waf)
assert result is True, "URL event without WAF tag should not be filtered"

# Test WEB_PARAMETER event without WAF tag - should not be filtered
result = await lightfuzz_module.filter_event(self.web_param_event_without_waf)
assert result is True, "WEB_PARAMETER event without WAF tag should not be filtered"

def check(self, module_test, events):
# This test doesn't need to check events since it's testing the filter method directly
pass