Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions examples/honeypot/honeypot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
swat-s1 run.py
"""

from mininet.net import Mininet
from mininet.cli import CLI
from minicps.mcps import MiniCPS

from topo import Topom

import sys


class Honeypot(MiniCPS):

"""Main container used to run the simulation."""

def __init__(self, name, net):

self.name = name
self.net = net

net.start()

net.pingAll()

# start devices
for node_class in Topom.NODES:
node = self.net.get(node_class.NAME)
node.cmd(sys.executable + ' {}.py &'.format(node_class.NAME))

CLI(self.net)

net.stop()

if __name__ == "__main__":

topo = Topom()
net = Mininet(topo=topo)

honeypot = Honeypot(
name='swat_s1',
net=net)
19 changes: 19 additions & 0 deletions examples/honeypot/pinger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import subprocess
from time import sleep


class Pinger:
NAME = 'pinger'
IP = '192.168.1.30'
MAC = '00:1D:9C:C7:B0:03'

def __init__(self):
print("Hello world")
f = open("/home/ubuntu/minicps/examples/honeypot/demofile2.txt", "w")
f.write("Now the file has more content!")
f.close()
subprocess.Popen(['ip', 'addr'])
sleep(3600)

if __name__ == "__main__":
plc1 = Pinger()
71 changes: 71 additions & 0 deletions examples/honeypot/plc1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
swat-s1 plc1.py
"""

from minicps.devices import PLC

import time

# TODO: real value tag where to read/write flow sensor
class Plc1(PLC):
NAME = 'plc1'
IP = '192.168.1.10'
MAC = '00:1D:9C:C7:B0:01'
STATE = {
'name': 'swat_s1',
'path': 'swat_s1_db.sqlite'
}
TAGS = (
('FIT101', 1, 'REAL'),
('MV101', 1, 'INT'),
('LIT101', 1, 'REAL'),
('P101', 1, 'INT'),
# interlocks does NOT go to the statedb
('FIT201', 1, 'REAL'),
('MV201', 1, 'INT'),
('LIT301', 1, 'REAL'),
)

SERVER = {
'address': IP,
'tags': TAGS
}
PROTOCOL = {
'name': 'enip',
'mode': 1,
'server': SERVER
}
DATA = {
'TODO': 'TODO',
}

def __init__(self):
PLC.__init__(self,
name=Plc1.NAME,
state= Plc1.STATE,
protocol=Plc1.PROTOCOL,
memory=Plc1.DATA,
disk=Plc1.DATA)


def pre_loop(self, sleep=1000):
print 'DEBUG: swat-s1 plc1 enters pre_loop'
print

time.sleep(sleep)

def main_loop(self):
print 'DEBUG: swat-s1 plc1 enters main_loop.'
print

LIT101 = ('LIT101', 1)
lit101 = float(self.get(LIT101))
self.send(LIT101, lit101, Plc1.IP)

print 'DEBUG swat plc1 shutdown'


if __name__ == "__main__":

# notice that memory init is different form disk init
plc1 = Plc1()
58 changes: 58 additions & 0 deletions examples/honeypot/plc2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from datetime import time

from minicps.devices import PLC


class Plc2(PLC):
NAME = 'plc2'
IP = '192.168.1.20'
MAC = '00:1D:9C:C7:B0:02'
STATE = {
'name': 'honeypot',
'path': 'honeypot_db.sqlite'
}
TAGS = (
('FIT101', 1, 'REAL'),
('MV101', 1, 'INT'),
('LIT101', 1, 'REAL'),
('P101', 1, 'INT'),
# interlocks does NOT go to the statedb
('FIT201', 1, 'REAL'),
('MV201', 1, 'INT'),
('LIT301', 1, 'REAL'),
)

SERVER = {
'address': IP,
'tags': TAGS
}
PROTOCOL = {
'name': 'enip',
'mode': 1,
'server': SERVER
}
DATA = {
'TODO': 'TODO',
}
def __init__(self):
PLC.__init__(self,
name=self.name,
state= Plc2.STATE,
protocol=Plc2.PROTOCOL,
memory=Plc2.DATA,
disk=Plc2.DATA)

def pre_loop(self, sleep=0.1):
print 'DEBUG: plc2 enters pre_loop'
print

time.sleep(sleep)

def main_loop(self):
print 'DEBUG: plc2 enters main_loop.'
print

if __name__ == "__main__":

# notice that memory init is different form disk init
plc1 = Plc2()
25 changes: 25 additions & 0 deletions examples/honeypot/topo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
swat-s1 topology
"""

from mininet.topo import Topo as TopoBase

from pinger import Pinger
from plc2 import Plc2
from plc1 import Plc1


class Topo(TopoBase):
NETMASK = '/24'
NODES = [Plc1, Plc2, Pinger]

def build(self):

switch = self.addSwitch('s1')

for node in Topo.NODES:
host = self.addHost(
node.NAME,
ip=node.IP + Topo.NETMASK,
mac=node.MAC)
self.addLink(host, switch)
2 changes: 1 addition & 1 deletion examples/swat-s1/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, name, net):

net.start()

net.pingAll()
# net.pingAll()

# start devices
plc1, plc2, plc3, s1 = self.net.get(
Expand Down
2 changes: 2 additions & 0 deletions examples/swat-s1/topo.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ def build(self):
ip=IP['attacker'] + NETMASK,
mac=MAC['attacker'])
self.addLink(attacker, switch)

# We want the virtual nodes to be pingable from host machine and vice versa. How could this be achieved with minicps/mininet?
15 changes: 1 addition & 14 deletions minicps/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,7 @@ def __init__(self, name, protocol, state, disk={}, memory={}):

Device construction example:

>>> device = Device(
>>> name='dev',
>>> protocol={
>>> 'name': 'enip',
>>> 'mode': 1,
>>> 'server': {
>>> 'address': '10.0.0.1',
>>> 'tags': (('SENSOR1', 1), ('SENSOR2', 1)),
>>> }
>>> state={
>>> 'path': '/path/to/db.sqlite',
>>> 'name': 'table_name',
>>> }
>>> )


"""

Expand Down
6 changes: 6 additions & 0 deletions minicps/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ def _start_server_cmd(cls, address='localhost:44818',
passable to subprocess.Popen object
"""


CMD = sys.executable + ' -m cpppo.server.enip '
PRINT_STDOUT = '--print '
HTTP = '--web %s:80 ' % address[0:address.find(':')]
Expand Down Expand Up @@ -565,6 +566,11 @@ def _start_server_cmd(cls, cmd_path, address='localhost:502',
raise OSError

colon_index = address.find(':')





IP = '-i {} '.format(address[:colon_index])
PORT = '-p {} '.format(address[colon_index+1:])
MODE = '-m {} '.format(mode)
Expand Down
8 changes: 4 additions & 4 deletions minicps/pymodbus/servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

# NOTE: https://pymodbus.readthedocs.io/en/latest/examples/asynchronous-server.html

from pymodbus.server.async import StartTcpServer
from pymodbus.server.async import StartUdpServer
from pymodbus.server.async import StartSerialServer
from pymodbus.server.asynchronous import StartTcpServer
from pymodbus.server.asynchronous import StartUdpServer
from pymodbus.server.asynchronous import StartSerialServer

from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
from pymodbus.server.async import StartTcpServer
from pymodbus.server.asynchronous import StartTcpServer

import argparse

Expand Down
1 change: 1 addition & 0 deletions scripts/ToSend/honeypotnew/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/hlog.txt
13 changes: 13 additions & 0 deletions scripts/ToSend/honeypotnew/Logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#logger
from datetime import datetime

# It is hard to debug scripts running in mininet. We were not able to read
# stdout from them so we made them to log into a file by this function.
def hlog(message):
f = open("/home/ubuntu/minicps/scripts/honeypot/hlog.txt", "a")
#dateTimeObj = datetime.now()
now = datetime.now()
date_time = now.strftime(" %m/%d%Y , %H:%M:%S")
f.write(message + date_time + "\n")
f.close()

Loading