Skip to content

Commit abb1719

Browse files
committed
Skip Error Resolution for non-standard HTTP status codes (>511)
Prevents false positive deserialization findings against endpoints like GlobalProtect that use non-standard status codes (e.g. 512).
1 parent 40f6bb9 commit abb1719

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

bbot/modules/lightfuzz/submodules/serial.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ async def fuzz(self):
161161

162162
# if the status code changed to 200, and the response doesn't match our general error exclusions, we have a finding
163163
self.debug(f"Potential finding detected for {payload_type}, needs confirmation")
164+
165+
baseline_status = payload_baseline.baseline.status_code
166+
# Skip Error Resolution if baseline uses a non-standard HTTP status code (>511).
167+
# Non-standard codes (e.g. 512 from GlobalProtect) are application-specific
168+
# and don't reliably indicate an error state that deserialization could "resolve".
169+
if baseline_status > 511:
170+
self.debug(
171+
f"Baseline status {baseline_status} is non-standard (>511), skipping Error Resolution for {payload_type}"
172+
)
173+
continue
174+
164175
if (
165176
status_code == 200
166177
and "code" in diff_reasons

bbot/test/test_step_2/module_tests/test_module_lightfuzz.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,38 @@ def check(self, module_test, events):
13851385
)
13861386

13871387

1388+
class Test_Lightfuzz_serial_errorresolution_nonstandard_status(Test_Lightfuzz_serial_errorresolution):
1389+
"""A baseline with a non-standard status code (>511, e.g. GlobalProtect's 512)
1390+
should not produce an Error Resolution finding even if the probe returns 200."""
1391+
1392+
def request_handler(self, request):
1393+
dotnet_serial_error_resolved = (
1394+
"<html><body>Deserialization successful! Object type: System.String</body></html>"
1395+
)
1396+
post_params = request.form
1397+
1398+
if "TextBox1" not in post_params.keys():
1399+
return Response(self.dotnet_serial_html, status=200)
1400+
1401+
else:
1402+
if post_params["__VIEWSTATE"] != "/wEPDwULLTE5MTI4MzkxNjVkZNt7ICM+GixNryV6ucx+srzhXlwP":
1403+
# Non-standard status code (like GlobalProtect's 512)
1404+
return Response(self.dotnet_serial_error, status=512)
1405+
if post_params["TextBox1"] == "AAEAAAD/////AQAAAAAAAAAGAQAAAAdndXN0YXZvCw==":
1406+
return Response(dotnet_serial_error_resolved, status=200)
1407+
else:
1408+
return Response(self.dotnet_serial_error, status=512)
1409+
1410+
def check(self, module_test, events):
1411+
no_finding_emitted = True
1412+
for e in events:
1413+
if e.type == "FINDING" and "Error Resolution" in e.data.get("description", ""):
1414+
no_finding_emitted = False
1415+
assert no_finding_emitted, (
1416+
"False positive Error Resolution finding was emitted for non-standard baseline status code (>511)"
1417+
)
1418+
1419+
13881420
# CMDi echo canary
13891421
class Test_Lightfuzz_cmdi(ModuleTestBase):
13901422
targets = ["http://127.0.0.1:8888"]

0 commit comments

Comments
 (0)