'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