-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sniffer.py
150 lines (125 loc) · 5.69 KB
/
Sniffer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import os
import sys
import netifaces
import pyshark
import sqlite3
import pickle
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score
from dictionary import dictionary
from PyQt5 import QtWidgets
class Sniffer:
def __init__(self):
super().__init__()
self.CheckRoot()
self.con = sqlite3.connect('CMShark.db', check_same_thread=False)
self.blacklist = self.ReadBlacklist()
self.inModel = pickle.load(
open("./models/netflow-dataset-in-model.sav", 'rb'))
self.outModel = pickle.load(
open("./models/netflow-dataset-out-model.sav", 'rb'))
self.maxCount = 100
self.ipDictionary = dictionary(self.maxCount)
self.detected = []
def CheckRoot(self):
if not os.geteuid() == 0:
sys.exit("sorry, can\'t sniff. this script must be run as root!")
def GetMyIp(self):
return netifaces.ifaddresses(self.interface)[netifaces.AF_INET][0]["addr"]
def GetInterfaces(self):
return netifaces.interfaces
def SetInterface(self, interface):
self.interface = interface
self.myIp = self.GetMyIp()
def IsPacketMine(self, ipLayer):
if ipLayer.src == self.myIp:
return [1, ipLayer.dst]
elif ipLayer.dst == self.myIp:
return [0, ipLayer.src]
else:
return False
def Sniff(self, detectionTable, scanUrl, scanPayload, scanMLM):
capture = pyshark.LiveCapture(interface=self.interface)
for packet in capture.sniff_continuously():
if hasattr(packet, "ip"):
# on this line we check if packet belong to this PC, if we want to use system for whole PCs on the current network we can remove this condition.
if self.IsPacketMine(packet.ip):
flowDirection, otherIp = self.IsPacketMine(packet.ip)
if self.IsForbiddenIps(otherIp):
# print(otherIp, "is blackliseted")
self.AddDetected(otherIp, "url scanner",
"ip blacklisted", detectionTable, "100%")
payload = self.GetPayload(packet)
if payload != None:
blackword = self.HasForbiddenWord(payload)
if blackword != None:
# print(otherIp, "has a blacklisetd word", blackword)
reason = "has a blacklisetd word " + blackword
self.AddDetected(
otherIp, "payload scanner", reason, detectionTable, "100%")
# print(packet)
predictedType = 0
if self.inModel.predict([[packet.__len__()]])[0] == "cryptojacking":
predictedType = 1
condition = self.ipDictionary.SetProbability(
otherIp, predictedType)
if condition > (self.maxCount/2):
self.AddDetected(otherIp, "ML scanner", "suspicious packet size", detectionTable, str(
(condition*100)/self.maxCount))
def AddDetectedRecored(self, detectionTable, processName, detectedBy, certainty, info):
currentRow = detectionTable.rowCount()
detectionTable.insertRow(currentRow)
detectionTable.setItem(
currentRow, 0, QtWidgets.QTableWidgetItem(processName))
detectionTable.setItem(
currentRow, 1, QtWidgets.QTableWidgetItem(detectedBy))
detectionTable.setItem(
currentRow, 2, QtWidgets.QTableWidgetItem(certainty))
detectionTable.setItem(currentRow, 3, QtWidgets.QTableWidgetItem(info))
def IsForbiddenIps(self, ip):
myCursor = self.con.cursor()
myCursor.execute(
'SELECT COUNT(nsblackword_id) FROM nsblacklist WHERE nsblackword_word="'+ip+'"')
blacklistedCount = myCursor.fetchone()
myCursor.close()
if blacklistedCount[0] == 0:
return False
else:
return True
def ReadBlacklist(self):
blacklist = []
myCursor = self.con.cursor()
myCursor.execute(
"SELECT blackword_word FROM blacklist WHERE blackword_is_on=1")
for blackword in myCursor.fetchall():
blacklist.append(blackword[0])
myCursor.close()
return blacklist
def GetPayload(self, packet):
if hasattr(packet, "tcp"):
if hasattr(packet.tcp, "payload"):
return self.ByteStringToString(packet.tcp.payload)
elif hasattr(packet, "udp"):
if hasattr(packet.udp, "payload"):
return self.ByteStringToString(packet.udp.payload)
else:
return None
def ByteStringToString(self, byteString):
readableString = ""
for byteCode in byteString.split(":"):
readableString += chr(int(byteCode, 16))
return readableString
def HasForbiddenWord(self, payload):
for blackword in self.blacklist:
if payload.find(blackword) >= 0:
return blackword
return None
def AddDetected(self, ip, treatType, reason, detectionTable, certainty):
for row in self.detected:
if row[0] == ip and row[1] == treatType:
return
self.detected.append([ip, treatType, reason])
self.AddDetectedRecored(
detectionTable, ip, treatType, certainty, reason)