Ns3 Projects for B.E/B.Tech M.E/M.Tech PhD Scholars.  Phone-Number:9790238391   E-mail: ns3simulation@gmail.com

How to Implement SCADA Security in ns3

To implement the Supervisory Control and Data Acquisition (SCADA) security in ns3, we need to conclude to emulate the exchange of packets among the SCADA components like master terminal unit (MTU), remote terminal units (RTUs), and programmable logic controllers (PLCs) and it encompasses to integrate the security mechanisms to protect against potential attacks. Here, we provide the detailed guide to setup the simple SCADA network in ns3 and implementing basic security measures.

Step-by-Step Implementation

Step 1: Set Up the ns3 Environment

Make certain ns3 is installed in the system.

Step 2: Define the Network Topology

Generate a network topology that contains nodes denotes the MTU, RTUs, PLCs, and potentially an attacker.

#include “ns3/core-module.h”

#include “ns3/network-module.h”

#include “ns3/internet-module.h”

#include “ns3/point-to-point-module.h”

#include “ns3/applications-module.h”

using namespace ns3;

NS_LOG_COMPONENT_DEFINE (“ScadaSecurityExample”);

int main (int argc, char *argv[]) {

CommandLine cmd;

cmd.Parse (argc, argv);

// Create nodes

NodeContainer nodes;

nodes.Create (6); // Nodes for MTU, RTUs, PLCs, and attacker

// Create point-to-point links

PointToPointHelper pointToPoint;

pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));

pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));

NetDeviceContainer devices;

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (1))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (2))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (3))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (4))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (5))));

// Install Internet stack

InternetStackHelper stack;

stack.Install (nodes);

// Assign IP addresses

Ipv4AddressHelper address;

address.SetBase (“10.1.1.0”, “255.255.255.0”);

address.Assign (devices);

// Create and configure applications…

Simulator::Run ();

Simulator::Destroy ();

return 0;

}

Step 3: Simulate SCADA Communication

Make applications to simulate message among the MTU, RTUs, and PLCs.

MTU Application:

class MtuApplication : public Application {

public:

MtuApplication () : m_socket (0) {}

virtual ~MtuApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 8080);

m_socket->Bind (local);

m_socket->SetRecvCallback (MakeCallback (&MtuApplication::HandleRead, this));

Simulator::Schedule (Seconds (2.0), &MtuApplication::SendCommand, this);

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void SendCommand () {

Ptr<Packet> packet = Create<Packet> ((uint8_t*)”MTU command”, 11);

m_socket->SendTo (packet, 0, InetSocketAddress (Ipv4Address (“10.1.1.2”), 8080)); // RTU address

Simulator::Schedule (Seconds (5.0), &MtuApplication::SendCommand, this);

}

void HandleRead (Ptr<Socket> socket) {

Ptr<Packet> packet;

Address from;

while ((packet = socket->RecvFrom (from))) {

NS_LOG_INFO (“MTU received: ” << packet->GetSize ());

}

}

Ptr<Socket> m_socket;

};

RTU Application:

class RtuApplication : public Application {

public:

RtuApplication () : m_socket (0) {}

virtual ~RtuApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 8080);

m_socket->Bind (local);

m_socket->SetRecvCallback (MakeCallback (&RtuApplication::HandleRead, this));

Simulator::Schedule (Seconds (2.0), &RtuApplication::SendSensorData, this);

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void SendSensorData () {

Ptr<Packet> packet = Create<Packet> ((uint8_t*)”sensor data”, 11);

m_socket->SendTo (packet, 0, InetSocketAddress (Ipv4Address (“10.1.1.1”), 8080)); // MTU address

Simulator::Schedule (Seconds (5.0), &RtuApplication::SendSensorData, this);

}

void HandleRead (Ptr<Socket> socket) {

Ptr<Packet> packet;

Address from;

while ((packet = socket->RecvFrom (from))) {

NS_LOG_INFO (“RTU received: ” << packet->GetSize ());

}

}

Ptr<Socket> m_socket;

};

Step 4: Implement Security Mechanisms

To emulate the security mechanisms like authentication, encryption, and intrusion detection.

Authentication:

class AuthApplication : public Application {

public:

AuthApplication () : m_socket (0) {}

virtual ~AuthApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 7070);

m_socket->Bind (local);

m_socket->SetRecvCallback (MakeCallback (&AuthApplication::HandleRead, this));

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void HandleRead (Ptr<Socket> socket) {

Ptr<Packet> packet;

Address from;

while ((packet = socket->RecvFrom (from))) {

std::string data = std::string ((char*) packet->PeekData ());

if (Authenticate (data)) {

NS_LOG_INFO (“Authentication successful from”<< InetSocketAddress::ConvertFrom (from).GetIpv4 ());

ForwardPacket (packet);

} else {

NS_LOG_WARN (“Authentication failed from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());

}

}

}

bool Authenticate (const std::string& data) {

// Simplified authentication logic

return data == “valid-credentials”;

}

void ForwardPacket (Ptr<Packet> packet) {

Ptr<Socket> socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress remote = InetSocketAddress (Ipv4Address (“10.1.1.2”), 8080); // Forward to RTU

socket->Connect (remote);

socket->Send (packet);

socket->Close ();

}

Ptr<Socket> m_socket;

};

Encryption:

class EncryptionApplication : public Application {

public:

EncryptionApplication () : m_socket (0) {}

virtual ~EncryptionApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 6060);

m_socket->Bind (local);

m_socket->SetRecvCallback (MakeCallback (&EncryptionApplication::HandleRead, this));

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void HandleRead (Ptr<Socket> socket) {

Ptr<Packet> packet;

Address from;

while ((packet = socket->RecvFrom (from))) {

std::string data = std::string ((char*) packet->PeekData ());

std::string decryptedData = Decrypt (data);

NS_LOG_INFO (“Received encrypted data: ” << data << “, decrypted data: ” << decryptedData);

}

}

std::string Decrypt (const std::string& data) {

// Simplified decryption logic

return data; // Assume data is already decrypted for simplicity

}

Ptr<Socket> m_socket;

};

Intrusion Detection System (IDS):

class IDSApplication : public Application {

public:

IDSApplication () : m_socket (0) {}

virtual ~IDSApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 5050);

m_socket->Bind (local);

m_socket->SetRecvCallback (MakeCallback (&IDSApplication::HandleRead, this));

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void HandleRead (Ptr<Socket> socket) {

Ptr<Packet> packet;

Address from;

while ((packet = socket->RecvFrom (from))) {

std::string data = std::string ((char*) packet->PeekData ());

if (DetectIntrusion (data)) {

NS_LOG_WARN (“Intrusion detected from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());

} else {

NS_LOG_INFO (“Normal traffic from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());

}

}

}

bool DetectIntrusion (const std::string& data) {

// Simplified intrusion detection logic

return data == “malicious-pattern”;

}

Ptr<Socket> m_socket;

};

Step 5: Deploy Applications

Instantiate and deploy the applications on the appropriate nodes in your network:

int main (int argc, char *argv[]) {

CommandLine cmd;

cmd.Parse (argc, argv);

// Create nodes

NodeContainer nodes;

nodes.Create (6); // Nodes for MTU, RTUs, PLCs, and attacker

// Create point-to-point links

PointToPointHelper pointToPoint;

pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));

pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));

NetDeviceContainer devices;

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (1))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (2))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (3))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (4))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (5))));

// Install Internet stack

InternetStackHelper stack;

stack.Install (nodes);

// Assign IP addresses

Ipv4AddressHelper address;

address.SetBase (“10.1.1.0”, “255.255.255.0”);

address.Assign (devices);

// Create and configure the MTU application

Ptr<MtuApplication> mtuApp = CreateObject<MtuApplication> ();

nodes.Get (0)->AddApplication (mtuApp);

mtuApp->SetStartTime (Seconds (1.0));

mtuApp->SetStopTime (Seconds (20.0));

// Create and configure the RTU application

Ptr<RtuApplication> rtuApp = CreateObject<RtuApplication> ();

nodes.Get (1)->AddApplication (rtuApp);

rtuApp->SetStartTime (Seconds (1.0));

rtuApp->SetStopTime (Seconds (20.0));

// Create and configure the Auth application

Ptr<AuthApplication> authApp = CreateObject<AuthApplication> ();

nodes.Get (2)->AddApplication (authApp);

authApp->SetStartTime (Seconds (1.0));

authApp->SetStopTime (Seconds (20.0));

// Create and configure the Encryption application

Ptr<EncryptionApplication> encryptionApp = CreateObject<EncryptionApplication> ();

nodes.Get (3)->AddApplication (encryptionApp);

encryptionApp->SetStartTime (Seconds (1.0));

encryptionApp->SetStopTime (Seconds (20.0));

// Create and configure the IDS application

Ptr<IDSApplication> idsApp = CreateObject<IDSApplication> ();

nodes.Get (4)->AddApplication (idsApp);

idsApp->SetStartTime (Seconds (1.0));

idsApp->SetStopTime (Seconds (20.0));

Simulator::Run ();

Simulator::Destroy ();

return 0;

}

Step 6: Simulate an Attack

To test the security mechanisms, simulate an attack from the attacker node:

class AttackerApplication : public Application {

public:

AttackerApplication () : m_socket (0) {}

virtual ~AttackerApplication () {}

protected:

virtual void StartApplication () {

m_socket = Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());

m_peer = InetSocketAddress (Ipv4Address (“10.1.1.2”), 8080); // Target RTU node

m_socket->Connect (m_peer);

Simulator::Schedule (Seconds (3.0), &AttackerApplication::SendMaliciousPacket, this);

}

virtual void StopApplication () {

if (m_socket) {

m_socket->Close ();

m_socket = 0;

}

}

private:

void SendMaliciousPacket () {

std::string maliciousData = “malicious-pattern”; // Simplified malicious pattern

Ptr<Packet> packet = Create<Packet> ((uint8_t*)maliciousData.c_str (), maliciousData.size ());

m_socket->Send (packet);

}

Ptr<Socket> m_socket;

Address m_peer;

};

int main (int argc, char *argv[]) {

CommandLine cmd;

cmd.Parse (argc, argv);

// Create nodes

NodeContainer nodes;

nodes.Create (6); // Nodes for MTU, RTUs, PLCs, attacker, and IDS

// Create point-to-point links

PointToPointHelper pointToPoint;

pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));

pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));

NetDeviceContainer devices;

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (1))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (2))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (3))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (4))));

devices.Add (pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (5))));

// Install Internet stack

InternetStackHelper stack;

stack.Install (nodes);

// Assign IP addresses

Ipv4AddressHelper address;

address.SetBase (“10.1.1.0”, “255.255.255.0”);

address.Assign (devices);

// Create and configure the MTU application

Ptr<MtuApplication> mtuApp = CreateObject<MtuApplication> ();

nodes.Get (0)->AddApplication (mtuApp);

mtuApp->SetStartTime (Seconds (1.0));

mtuApp->SetStopTime (Seconds (20.0));

// Create and configure the RTU application

Ptr<RtuApplication> rtuApp = CreateObject<RtuApplication> ();

nodes.Get (1)->AddApplication (rtuApp);

rtuApp->SetStartTime (Seconds (1.0));

rtuApp->SetStopTime (Seconds (20.0));

// Create and configure the Auth application

Ptr<AuthApplication> authApp = CreateObject<AuthApplication> ();

nodes.Get (2)->AddApplication (authApp);

authApp->SetStartTime (Seconds (1.0));

authApp->SetStopTime (Seconds (20.0));

// Create and configure the Encryption application

Ptr<EncryptionApplication> encryptionApp = CreateObject<EncryptionApplication> ();

nodes.Get (3)->AddApplication (encryptionApp);

encryptionApp->SetStartTime (Seconds (1.0));

encryptionApp->SetStopTime (Seconds (20.0));

// Create and configure the IDS application

Ptr<IDSApplication> idsApp = CreateObject<IDSApplication> ();

nodes.Get (4)->AddApplication (idsApp);

idsApp->SetStartTime (Seconds (1.0));

idsApp->SetStopTime (Seconds (20.0));

// Create and configure the Attacker application

Ptr<AttackerApplication> attackerApp = CreateObject<AttackerApplication> ();

nodes.Get (5)->AddApplication (attackerApp);

attackerApp->SetStartTime (Seconds (3.0));

attackerApp->SetStopTime (Seconds (4.0));

Simulator::Run ();

Simulator::Destroy ();

return 0;

}

In the end, we discussed earlier about how the SCADA security communicate and protect the communication against the attacks using the ns3 tool. If you have any doubts regarding this we will help and provide it so connect with us for more project execution ideas.