'how to Drop packet in ryu controller after detecting malware traffic
`
hi I'm working on project to detect and mitigate botnet on sdn using machine learning. the simulation was done by ryu controller and mininet. my question is that i was able to detect the attack but i'm really struggling with mitigation i want to drop the packet after detecting that this is a botnet attack i tried some solutions but it didn't work for me so can anyone here help me to drop these packets just after detecting malware botnet traffic and I'll be thankful for that.
here is detecting module
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.lib import hub
import subprocess
import os
import switch
from datetime import datetime
import copy
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix , classification_report
from sklearn.metrics import accuracy_score
from pickle import dump , load
class SimpleMonitor13(switch.SimpleSwitch13):
def __init__(self, *args, **kwargs):
super(SimpleMonitor13, self).__init__(*args, **kwargs)
self.datapaths = {}
self.monitor_thread = hub.spawn(self._monitor)
start = datetime.now()
#self.flow_training()
end = datetime.now()
print("Training time: ", (end-start))
@set_ev_cls(ofp_event.EventOFPStateChange,
[MAIN_DISPATCHER, DEAD_DISPATCHER])
def _state_change_handler(self, ev):
datapath = ev.datapath
if ev.state == MAIN_DISPATCHER:
if datapath.id not in self.datapaths:
self.logger.debug('register datapath: %016x', datapath.id)
self.datapaths[datapath.id] = datapath
elif ev.state == DEAD_DISPATCHER:
if datapath.id in self.datapaths:
self.logger.debug('unregister datapath: %016x', datapath.id)
del self.datapaths[datapath.id]
def _monitor(self):
while True:
for dp in self.datapaths.values():
self._request_stats(dp)
hub.sleep(10)
self.flow_predict()
def _request_stats(self, datapath):
self.logger.debug('send stats request: %016x', datapath.id)
parser = datapath.ofproto_parser
req = parser.OFPFlowStatsRequest(datapath)
datapath.send_msg(req)
@set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
def _flow_stats_reply_handler(self, ev):
timestamp = datetime.now()
timestamp = timestamp.timestamp()
file0 = open("PredictFlowStatsfile.csv","w")
file0.write('ip_src,tp_src,ip_dst,tp_dst,ip_proto,flow_duration_sec,flags,packet_count,byte_count,packet_count_per_second,byte_count_per_second\n')
body = ev.msg.body
#icmp_code = -1
#icmp_type = -1
tp_src = 0
tp_dst = 0
for stat in sorted([flow for flow in body if (flow.priority == 1) ], key=lambda flow:
(flow.match['eth_type'],flow.match['ipv4_src'],flow.match['ipv4_dst'],flow.match['ip_proto'])):
ip_src = stat.match['ipv4_src']
ip_dst = stat.match['ipv4_dst']
ip_proto = stat.match['ip_proto']
if stat.match['ip_proto'] == 1:
icmp_code = stat.match['icmpv4_code']
icmp_type = stat.match['icmpv4_type']
elif stat.match['ip_proto'] == 6:
tp_src = stat.match['tcp_src']
tp_dst = stat.match['tcp_dst']
elif stat.match['ip_proto'] == 17:
tp_src = stat.match['udp_src']
tp_dst = stat.match['udp_dst']
#flow_id = str(ip_src) + str(tp_src) + str(ip_dst) + str(tp_dst) + str(ip_proto)
try:
packet_count_per_second = stat.packet_count/stat.duration_sec
#packet_count_per_nsecond = stat.packet_count/stat.duration_nsec
except:
packet_count_per_second = 0
#packet_count_per_nsecond = 0
try:
byte_count_per_second = stat.byte_count/stat.duration_sec
#byte_count_per_nsecond = stat.byte_count/stat.duration_nsec
except:
byte_count_per_second = 0
#byte_count_per_nsecond = 0
file0.write("{},{},{},{},{},{},{},{},{},{},{}\n"
.format(ip_src, tp_src,ip_dst, tp_dst,
stat.match['ip_proto'],stat.duration_sec,
stat.flags, stat.packet_count,stat.byte_count,
packet_count_per_second,byte_count_per_second,))
file0.close()
def flow_predict(self):
try:
#print(hosts)
predict_flow_dataset = pd.read_csv('PredictFlowStatsfile.csv')
pdf = copy.deepcopy(predict_flow_dataset)
predict_flow_dataset.iloc[:, 2] = predict_flow_dataset.iloc[:, 2].str.replace('.', '')
predict_flow_dataset.iloc[:, 0] = predict_flow_dataset.iloc[:, 0].str.replace('.', '')
#predict_flow_dataset = predict_flow_dataset.drop(columns='icmp_code', axis=1)
#predict_flow_dataset = predict_flow_dataset.drop(columns='icmp_type', axis=1)
#pdf.iloc[:, 2] = pdf.iloc[:, 2].str.replace('.', '')
#pdf.iloc[:, 0] = pdf.iloc[:, 0].str.replace('.', '')
X_predict_flow = predict_flow_dataset.iloc[:, :].values
X_predict_flow = X_predict_flow.astype('float64')
RFmodel = load(open('modell.pkl', 'rb'))
y_flow_pred = RFmodel.predict(X_predict_flow)
#y_flow_pred = self.flow_model.predict(X_predict_flow)
legitimate_trafic = 0
botnet_trafic = 0
for i in y_flow_pred:
if i == 0:
legitimate_trafic = legitimate_trafic + 1
else:
botnet_trafic = botnet_trafic + 1
victim = pdf.iloc[i, 2]#%20
hosts = ['192.168.122.13','192.168.122.14']
#attacker = pdf.iloc[i, 0]#%20
attacker = pdf.iloc[i]
#attacker = pdf["ip_src"].unique()
#for i in range(len(hosts)):
# if hosts[i] in attacker:
# attacker.remove(hosts[i])
self.logger.info("------------------------------------------------------------------------------")
if (legitimate_trafic/len(y_flow_pred)*100) > 80:
#print("length of y_flow_pdf",len(y_flow_pred))
print("Total Traffic",len(y_flow_pred))
print("legitimate trafic ...",legitimate_trafic/len(y_flow_pred))
#self.logger.info("length of y_flow_pdf",len(y_flow_pred))
#for i in range(len(hosts)):
# if hosts[i] in attacker:
# attacker.remove(hosts[i])
print("botnet trafic ...",botnet_trafic/len(y_flow_pred))
print("Attacker IP: {}".format(attacker))
print("Victim IP: {}".format(victim))
#os.system("sudo", "ufw", "deny", "from", attacker, "to", "any")
#self.os.system("echo 'hell'")
#print("attacker IP blocked {}".format(attacker))
else:
print("botnet trafic ...",botnet_trafic/len(y_flow_pred))
print("Attacker IP: {}".format(attacker))
print("Victim IP: {}".format(victim))
self.logger.info("------------------------------------------------------------------------------")
file0 = open("PredictFlowStatsfile.csv","w")
it woulld be greatfull if someone help me :)
one more thing i am unabel to remove internal host ip from attacket ip , you can see in this block of code
hosts = ['192.168.122.13','192.168.122.14']
#attacker = pdf.iloc[i, 0]#%20
attacker = pdf.iloc[i]
#attacker = pdf["ip_src"].unique()
#for i in range(len(hosts)):
# if hosts[i] in attacker:
# attacker.remove(hosts[i])
i used this block of code for flow drop which is not working !!
def drop_flow(self, datapath,match_eth_type = 0x0800, scrip, dstip):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip)
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, [])]
mod = parser.OFPFlowMod(datapath=datapath,
out_port=ofproto.OFPP_ANY,
out_group=ofproto.OFPG_ANY,
match=match, instructions=inst)
print ("botnet traffic detected : packet droped")
datapath.send_msg(mod)
I am able to detect the attack , able to extract attacker ip , victim ip , but unbale to drop the attacket traffic flow, and i have to detect multiple attack ip but it is 2 way communication so when extracting the attacket ip we also get our host up , which i tried to remove, which is also not working. Thank you so much in advanced .
`
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|