From 2a0b83e6e8c14ea89c9f64c9d3b95e27a1ac396e Mon Sep 17 00:00:00 2001 From: Aarush Date: Tue, 10 Feb 2026 17:23:23 +0530 Subject: [PATCH 01/10] Add FortiWeb authentication bypass vulnerability check Signed-off-by: Aarush --- docs/Modules.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Modules.md b/docs/Modules.md index 3c66a26f2..5ec85db5b 100644 --- a/docs/Modules.md +++ b/docs/Modules.md @@ -151,6 +151,7 @@ If you want to scan all ports please define -g 1-65535 range. Otherwise Nettacke - '**exponent_cms_cve_2021_38751_vuln**' – check the target for Exponent CMS CVE-2021-38751 - '**f5_cve_2020_5902_vuln**' – check the target for F5 RCE CVE-2020-5902 vulnerability - '**forgerock_am_cve_2021_35464_vuln**' – check the target for ForgeRock AM CVE-2021-35464 +- '**fortiweb_auth_bypass_cve_2025_64446_vuln** - check for FortiWeb authentication bypass vulnerability - '**galera_webtemp_cve_2021_40960_vuln**' – check the target for Galera WebTemplate CVE-2021-40960 - '**grafana_cve_2021_43798_vuln**' – check the target for Grafana CVE-2021-43798 vulnerability - '**graphql_vuln**' – check the target for exposed GraphQL introspection endpoint From b1ffe4e499e1fb1f301286e19bdd423b8932ddf6 Mon Sep 17 00:00:00 2001 From: Aarush Date: Tue, 10 Feb 2026 17:29:23 +0530 Subject: [PATCH 02/10] Remove FortiWeb auth bypass vulnerability entry Removed entry for FortiWeb authentication bypass vulnerability. Signed-off-by: Aarush --- docs/Modules.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/Modules.md b/docs/Modules.md index 5ec85db5b..3c66a26f2 100644 --- a/docs/Modules.md +++ b/docs/Modules.md @@ -151,7 +151,6 @@ If you want to scan all ports please define -g 1-65535 range. Otherwise Nettacke - '**exponent_cms_cve_2021_38751_vuln**' – check the target for Exponent CMS CVE-2021-38751 - '**f5_cve_2020_5902_vuln**' – check the target for F5 RCE CVE-2020-5902 vulnerability - '**forgerock_am_cve_2021_35464_vuln**' – check the target for ForgeRock AM CVE-2021-35464 -- '**fortiweb_auth_bypass_cve_2025_64446_vuln** - check for FortiWeb authentication bypass vulnerability - '**galera_webtemp_cve_2021_40960_vuln**' – check the target for Galera WebTemplate CVE-2021-40960 - '**grafana_cve_2021_43798_vuln**' – check the target for Grafana CVE-2021-43798 vulnerability - '**graphql_vuln**' – check the target for exposed GraphQL introspection endpoint From 6db5ee7a84b8d3fe34529bfb5983aca0ceffc334 Mon Sep 17 00:00:00 2001 From: Aarush Date: Tue, 10 Feb 2026 17:45:01 +0530 Subject: [PATCH 03/10] Fix vulnerability name in wp_plugin_cve_2021_38314.yaml Signed-off-by: Aarush --- nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml b/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml index 6b2c22f46..88df2b91a 100644 --- a/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml +++ b/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml @@ -1,5 +1,5 @@ info: - name: CVE_2021_39320_vuln + name: CVE_2021_39314_vuln author: OWASP Nettacker Team severity: 7 description: Sensitive Information Leakage - The Gutenberg Template Library & Redux Framework plugin <= 4.2.11 for WordPress From 6fd226a7ac69c0796a408ff136f2a1ea69398386 Mon Sep 17 00:00:00 2001 From: Aarush Date: Tue, 10 Feb 2026 17:45:59 +0530 Subject: [PATCH 04/10] Rename CVE identifier from 39314 to 39320 Signed-off-by: Aarush --- nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml b/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml index 88df2b91a..6b2c22f46 100644 --- a/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml +++ b/nettacker/modules/vuln/wp_plugin_cve_2021_38314.yaml @@ -1,5 +1,5 @@ info: - name: CVE_2021_39314_vuln + name: CVE_2021_39320_vuln author: OWASP Nettacker Team severity: 7 description: Sensitive Information Leakage - The Gutenberg Template Library & Redux Framework plugin <= 4.2.11 for WordPress From f0df79b704475f34549a0d5ba313f57719bbd68c Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Sat, 7 Mar 2026 23:06:05 +0530 Subject: [PATCH 05/10] Stop_at_first_match feature added --- nettacker/core/lib/base.py | 24 ++++++++++++++++++++++++ nettacker/modules/scan/waf.yaml | 1 + 2 files changed, 25 insertions(+) diff --git a/nettacker/core/lib/base.py b/nettacker/core/lib/base.py index 7af4ee53e..108ca1cfb 100644 --- a/nettacker/core/lib/base.py +++ b/nettacker/core/lib/base.py @@ -122,6 +122,11 @@ def process_conditions( ): # Remove sensitive keys from headers before submitting to DB event = remove_sensitive_header_keys(event) + if "stop_at_first_success" in event["response"]: + event_name = event["response"]["stop_at_first_success"] + existing = find_temp_events(target, module_name, scan_id, event_name) + if existing: + return False if "save_to_temp_events_only" in event.get("response", ""): submit_temp_logs_to_db( { @@ -135,6 +140,19 @@ def process_conditions( "data": response, } ) + if "stop_at_first_success" in event.get("response", ""): + submit_temp_logs_to_db( + { + "date": datetime.now(), + "target": target, + "module_name": module_name, + "scan_id": scan_id, + "event_name": event["response"]["stop_at_first_success"], + "port": event.get("ports", ""), + "event": event, + "data": response, + } + ) if event["response"]["conditions_results"] and "save_to_temp_events_only" not in event.get( "response", "" ): @@ -273,6 +291,12 @@ def run( del sub_step["method"] del sub_step["response"] + if "stop_at_first_success" in backup_response: + event_name = backup_response["stop_at_first_success"] + existing = find_temp_events(target, module_name, scan_id, event_name) + if existing: + return False + for attr_name in ("ports", "usernames", "passwords"): if attr_name in sub_step: value = sub_step.pop(attr_name) diff --git a/nettacker/modules/scan/waf.yaml b/nettacker/modules/scan/waf.yaml index 0a5776202..43615c403 100644 --- a/nettacker/modules/scan/waf.yaml +++ b/nettacker/modules/scan/waf.yaml @@ -80,6 +80,7 @@ payloads: # - ../../../../etc/passwd #lfi response: dependent_on_temp_event: valid_request_status + stop_at_first_success: waf_detect condition_type: or log: WAF detected, Got differenet response from original request status code dependent_on_temp_event[0]['status_code'][0] conditions: From 14b19489c7a05dab89e4ce06fe34ad36bf62a2bf Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Sat, 7 Mar 2026 23:12:48 +0530 Subject: [PATCH 06/10] stop removedfrom waf module --- nettacker/modules/scan/waf.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/nettacker/modules/scan/waf.yaml b/nettacker/modules/scan/waf.yaml index 43615c403..0a5776202 100644 --- a/nettacker/modules/scan/waf.yaml +++ b/nettacker/modules/scan/waf.yaml @@ -80,7 +80,6 @@ payloads: # - ../../../../etc/passwd #lfi response: dependent_on_temp_event: valid_request_status - stop_at_first_success: waf_detect condition_type: or log: WAF detected, Got differenet response from original request status code dependent_on_temp_event[0]['status_code'][0] conditions: From 02fd3cd034d1ce5288acbbea59433c685cea777b Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Tue, 14 Apr 2026 15:42:47 +0530 Subject: [PATCH 07/10] added feature --- nettacker/core/lib/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nettacker/core/lib/base.py b/nettacker/core/lib/base.py index 108ca1cfb..3d6a3e9c0 100644 --- a/nettacker/core/lib/base.py +++ b/nettacker/core/lib/base.py @@ -334,4 +334,4 @@ def run( total_module_thread_number, request_number_counter, total_number_of_requests, - ) + ) \ No newline at end of file From c49eaad2be267775e64cb058601dd3ec36e18510 Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Tue, 14 Apr 2026 16:47:57 +0530 Subject: [PATCH 08/10] pre-commit done --- nettacker/core/lib/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nettacker/core/lib/base.py b/nettacker/core/lib/base.py index 3d6a3e9c0..a3b15400b 100644 --- a/nettacker/core/lib/base.py +++ b/nettacker/core/lib/base.py @@ -296,7 +296,7 @@ def run( existing = find_temp_events(target, module_name, scan_id, event_name) if existing: return False - + for attr_name in ("ports", "usernames", "passwords"): if attr_name in sub_step: value = sub_step.pop(attr_name) @@ -334,4 +334,4 @@ def run( total_module_thread_number, request_number_counter, total_number_of_requests, - ) \ No newline at end of file + ) From cb3053850a08ed5589ff3de2dfbe2a91ec52bfd8 Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Tue, 14 Apr 2026 17:08:39 +0530 Subject: [PATCH 09/10] Coderabbit concerns addressed --- nettacker/core/lib/base.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nettacker/core/lib/base.py b/nettacker/core/lib/base.py index a3b15400b..61ff3705d 100644 --- a/nettacker/core/lib/base.py +++ b/nettacker/core/lib/base.py @@ -140,7 +140,9 @@ def process_conditions( "data": response, } ) - if "stop_at_first_success" in event.get("response", ""): + if event["response"]["conditions_results"] and "stop_at_first_success" in event.get( + "response", "" + ): submit_temp_logs_to_db( { "date": datetime.now(), @@ -288,14 +290,13 @@ def run( """Engine entry point.""" backup_method = copy.deepcopy(sub_step["method"]) backup_response = copy.deepcopy(sub_step["response"]) - del sub_step["method"] - del sub_step["response"] - if "stop_at_first_success" in backup_response: event_name = backup_response["stop_at_first_success"] existing = find_temp_events(target, module_name, scan_id, event_name) if existing: return False + del sub_step["method"] + del sub_step["response"] for attr_name in ("ports", "usernames", "passwords"): if attr_name in sub_step: From 8e7df0bbef45acc45639573f587b3bbd3be31797 Mon Sep 17 00:00:00 2001 From: Aarush289 Date: Tue, 14 Apr 2026 17:34:06 +0530 Subject: [PATCH 10/10] Port added to query database --- nettacker/core/lib/base.py | 8 +++++-- nettacker/database/db.py | 48 +++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/nettacker/core/lib/base.py b/nettacker/core/lib/base.py index 61ff3705d..312726edf 100644 --- a/nettacker/core/lib/base.py +++ b/nettacker/core/lib/base.py @@ -124,7 +124,9 @@ def process_conditions( event = remove_sensitive_header_keys(event) if "stop_at_first_success" in event["response"]: event_name = event["response"]["stop_at_first_success"] - existing = find_temp_events(target, module_name, scan_id, event_name) + existing = find_temp_events( + target, module_name, scan_id, event_name, port=event.get("ports", "") + ) if existing: return False if "save_to_temp_events_only" in event.get("response", ""): @@ -292,7 +294,9 @@ def run( backup_response = copy.deepcopy(sub_step["response"]) if "stop_at_first_success" in backup_response: event_name = backup_response["stop_at_first_success"] - existing = find_temp_events(target, module_name, scan_id, event_name) + existing = find_temp_events( + target, module_name, scan_id, event_name, port=sub_step.get("ports", "") + ) if existing: return False del sub_step["method"] diff --git a/nettacker/database/db.py b/nettacker/database/db.py index 3444db72f..c5d461902 100644 --- a/nettacker/database/db.py +++ b/nettacker/database/db.py @@ -403,7 +403,7 @@ def submit_temp_logs_to_db(log): return False -def find_temp_events(target, module_name, scan_id, event_name): +def find_temp_events(target, module_name, scan_id, event_name, port=None): """ select all events by scan_unique id, target, module_name @@ -420,16 +420,24 @@ def find_temp_events(target, module_name, scan_id, event_name): if isinstance(session, tuple): connection, cursor = session try: - cursor.execute( - """ - SELECT event - FROM temp_events - WHERE target = ? AND module_name = ? AND scan_unique_id = ? AND event_name = ? - LIMIT 1 - """, - (target, module_name, scan_id, event_name), - ) - + if port is not None: + cursor.execute( + """ + SELECT event FROM temp_events + WHERE target = ? AND module_name = ? AND scan_unique_id = ? AND event_name = ? AND port = ? + LIMIT 1 + """, + (target, module_name, scan_id, event_name, json.dumps(port)), + ) + else: + cursor.execute( + """ + SELECT event FROM temp_events + WHERE target = ? AND module_name = ? AND scan_unique_id = ? AND event_name = ? + LIMIT 1 + """, + (target, module_name, scan_id, event_name), + ) row = cursor.fetchone() if row: return row[0] @@ -444,17 +452,15 @@ def find_temp_events(target, module_name, scan_id, event_name): except Exception: pass else: - result = ( - session.query(TempEvents) - .filter( - TempEvents.target == target, - TempEvents.module_name == module_name, - TempEvents.scan_unique_id == scan_id, - TempEvents.event_name == event_name, - ) - .first() + query = session.query(TempEvents).filter( + TempEvents.target == target, + TempEvents.module_name == module_name, + TempEvents.scan_unique_id == scan_id, + TempEvents.event_name == event_name, ) - + if port is not None: + query = query.filter(TempEvents.port == json.dumps(port)) + result = query.first() return result.event if result else []