Python写的嗅探器——Pyside,Scapy

时间:2022-05-08
本文章向大家介绍Python写的嗅探器——Pyside,Scapy,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

使用Python的Pyside和Scapy写的嗅探器原型,拥有基本框架,但是功能并不十分完善,供参考。

  1 import sys
  2 import time
  3 import binascii
  4 from PySide.QtCore import *
  5 from PySide.QtGui import *
  6 from scapy.all import *
  7 
  8 # Every Qt application must have one and only one QApplication object;
  9 # it receives the command line arguments passed to the script, as they
 10 # can be used to customize the application's appearance and behavior
 11 qt_app = QApplication(sys.argv)
 12 global_pkt_list = []
 13 
 14 # Try to redirect hexdump()'s output, but failed!Why? T_T
 15 class redirect_output:
 16     def __init__(self):
 17         self.str = ''
 18     def write(self, s):
 19         self.str += s
 20     def show(self):
 21         return self.str
 22 
 23 class Sniffer(QThread):
 24     pkt_arrive = Signal(str)
 25     bGo = True
 26     filter = None
 27     iface = 'eth0'
 28 
 29     def __init__(self, parent=None):
 30         QThread.__init__(self, parent)
 31         # self.pkt_arrive.connect(OnPktArrive)
 32 
 33     def run(self):
 34         # self.emit(SIGNAL("pkt_arrive(str)"), "pkt")
 35         while (self.bGo):
 36             p = sniff(count=1, filter = self.filter)
 37             global_pkt_list.append(p[0])
 38             self.pkt_arrive.emit((p[0].summary()))
 39 
 40     def go(self):
 41         self.bGo = True
 42         self.start()
 43 
 44     def stop(self):
 45         print 'Sniffer got exit message'
 46         self.bGo = False
 47 
 48 class PktListItem(QListWidgetItem):
 49     def __init__(self, pkt=None, num=None):
 50         QListWidgetItem.__init__(self)
 51         self.pkt = pkt
 52         self.num = num
 53 
 54 class MainWindow(QWidget):
 55     ''' An example of PySide absolute positioning; the main window
 56         inherits from QWidget, a convenient widget for an empty window. '''
 57     number = 0
 58     def __init__(self):
 59         QWidget.__init__(self)
 60         self.setWindowTitle('J_Sniffer')
 61         self.setMinimumSize(800, 500)
 62 
 63         # set layout
 64         self.main_layout = QVBoxLayout()
 65         # edit and btn
 66         self.layout1 = QHBoxLayout()
 67 
 68         self.Label_Iface = QLabel("Iface", self)
 69         self.layout1.addWidget(self.Label_Iface)
 70         self.TextBox_Iface = QLineEdit(self)
 71         self.TextBox_Iface.setPlaceholderText("Choose network interface")
 72         self.layout1.addWidget(self.TextBox_Iface)
 73 
 74         self.Label_Fliter = QLabel("Filter", self)
 75         self.layout1.addWidget(self.Label_Fliter)
 76         self.TextBox_Filter = QLineEdit(self)
 77         self.layout1.addWidget(self.TextBox_Filter)
 78 
 79         self.layout1.addStretch(1)
 80         self.Btn_Start = QPushButton("&Start", self)
 81         self.layout1.addWidget(self.Btn_Start)
 82 
 83         self.main_layout.addLayout(self.layout1)
 84 
 85         # List to show packets
 86         self.List_Pkt = QListWidget(self)
 87         self.main_layout.addWidget(self.List_Pkt)
 88 
 89         # Tree to see pkt's detail
 90         self.Tree = QTreeWidget(self)
 91         self.main_layout.addWidget(self.Tree)
 92         self.Tree.setColumnCount(2)
 93         self.Tree.setHeaderLabels(['Key', 'Value'])
 94 
 95         self.setLayout(self.main_layout)
 96 
 97         # create signal and sniff thread
 98         self.thread = Sniffer()
 99         self.connect(self.Btn_Start, SIGNAL("clicked()"), self.Sniff)
100         # self.connect(self.thread, SIGNAL("pkt_arrive(str)"), self.OnPktArrive) Connot work!
101         self.thread.pkt_arrive.connect(self.OnPktArrive)
102         self.List_Pkt.currentItemChanged.connect(self.On_ItemChanged)
103 
104     @Slot(str)
105     def OnPktArrive(self, pkt):
106         print 'received pkt arrive signal'
107 
108         #p = Ether(pkt) #only Ethernet now, 802.11 may be crash!
109         item = PktListItem(num = self.number)
110         item.setText(str(self.number) + 't' + pkt)
111         self.List_Pkt.addItem(item)
112         self.number += 1
113 
114     @Slot()
115     def Sniff(self):
116         print self.Btn_Start.text()
117         if self.Btn_Start.text() == '&Start':
118             self.Btn_Start.setText("&Stop")
119             self.thread.filter = self.TextBox_Filter.text()
120             self.thread.iface = self.TextBox_Iface.text()
121             self.thread.go()
122         else:
123             self.Btn_Start.setText("&Start")
124             self.thread.stop()
125 
126     def On_ItemChanged(self, curr, prev):
127         print curr.num
128         self.Tree.clear()
129         p = global_pkt_list[curr.num]
130         root1 = QTreeWidgetItem(self.Tree)
131         if (p.haslayer(Ether)):
132             root1.setText(0, 'Ethernet:')
133             child1_1 = QTreeWidgetItem(root1)
134             child1_1.setText(0, 'dst')
135             child1_1.setText(1, p.dst)
136             child1_2 = QTreeWidgetItem(root1)
137             child1_2.setText(0, 'src')
138             child1_2.setText(1, p.src)
139             child1_3 = QTreeWidgetItem(root1)
140             child1_3.setText(0, 'type')
141             child1_3.setText(1, hex(p.type))
142             p = p.getlayer(1)
143             if (p.haslayer(IP)):
144                 self._SetIPTree(p)
145                 p = p.getlayer(1)
146                 if (p.haslayer(ICMP)):
147                     self._SetICMPTree(p)
148                 elif (p.haslayer(TCP)):
149                     pass
150                 else:
151                     pass
152             elif (p.haslayer(IPv6)):
153                 pass
154         else:
155             root1.setText(0, 'Not Ethernet')
156             root1.setText(1, hexdump(p))
157 
158     def _SetIPTree(self, p):
159         root2 = QTreeWidgetItem(self.Tree)
160         root2.setText(0, 'IPv4')
161         child2_1 = QTreeWidgetItem(root2)
162         child2_1.setText(0, 'Version')
163         child2_1.setText(1, str(p.version))
164         child2_2 = QTreeWidgetItem(root2)
165         child2_2.setText(0, 'ihl(Header Length)')
166         child2_2.setText(1, str(p.ihl))
167         child2_3 = QTreeWidgetItem(root2)
168         child2_3.setText(0, 'tos')
169         child2_3.setText(1, str(p.tos))
170         child2_4 = QTreeWidgetItem(root2)
171         child2_4.setText(0, 'len')
172         child2_4.setText(1, str(p.len))
173         child2_5 = QTreeWidgetItem(root2)
174         child2_5.setText(0, 'id')
175         child2_5.setText(1, str(p.id))
176         child2_6 = QTreeWidgetItem(root2)
177         child2_6.setText(0, 'flags')
178         child2_6.setText(1, str(p.flags))
179         child2_7 = QTreeWidgetItem(root2)
180         child2_7.setText(0, 'frag')
181         child2_7.setText(1, str(p.frag))
182         child2_8 = QTreeWidgetItem(root2)
183         child2_8.setText(0, 'TTL')
184         child2_8.setText(1, str(p.ttl))
185         child2_9 = QTreeWidgetItem(root2)
186         child2_9.setText(0, 'protocol')
187         child2_9.setText(1, str(p.proto))
188         child2_10 = QTreeWidgetItem(root2)
189         child2_10.setText(0, 'checksum')
190         child2_10.setText(1, str(p.chksum))
191         child2_11 = QTreeWidgetItem(root2)
192         child2_11.setText(0, 'src')
193         child2_11.setText(1, str(p.src))
194         child2_12 = QTreeWidgetItem(root2)
195         child2_12.setText(0, 'dst')
196         child2_12.setText(1, str(p.dst))
197 
198     def _SetICMPTree(self, p):
199         root3 = QTreeWidgetItem(self.Tree)
200         root3.setText(0, 'ICMP')
201         child3_1 = QTreeWidgetItem(root3)
202         child3_1.setText(0, 'Type')
203         if (p.type == 8):
204             child3_1.setText(1, 'echo request')
205         elif (p.type == 0):
206             child3_1.setText(1, 'echo reply')
207         else:
208             child3_1.setText(1, str(p.type))
209         child3_2 = QTreeWidgetItem(root3)
210         child3_2.setText(0, 'Code')
211         child3_2.setText(1, str(p.code))
212         child3_3 = QTreeWidgetItem(root3)
213         child3_3.setText(0, 'Checksum')
214         child3_3.setText(1, str(p.chksum))
215         child3_4 = QTreeWidgetItem(root3)
216         child3_4.setText(0, 'ID')
217         child3_4.setText(1, str(p.id))
218         child3_5 = QTreeWidgetItem(root3)
219         child3_5.setText(0, 'Sequence number')
220         child3_5.setText(1, str(p.seq))
221         child3_6 = QTreeWidgetItem(root3)
222         child3_6.setText(0, 'Data')
223         child3_6.setText(1, binascii.b2a_hex(str(p.load)))
224 
225     def run(self):
226         self.show()
227 
228 if __name__ == '__main__':
229     # Create an instance of the application window and run it
230     win = MainWindow()
231     win.run()
232     qt_app.exec_()