summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom2012-03-09 14:08:36 +0100
committerTom2012-03-09 14:08:36 +0100
commit9053916b9c696fe1a6a82746e7b954701f416f52 (patch)
tree1958f36794b372c2a0eab2423ffdbb669aec6755
parentcleaning up git (diff)
downloadimsi-catcher-detection-9053916b9c696fe1a6a82746e7b954701f416f52.tar.gz
imsi-catcher-detection-9053916b9c696fe1a6a82746e7b954701f416f52.tar.xz
imsi-catcher-detection-9053916b9c696fe1a6a82746e7b954701f416f52.zip
implemented rules and evaluators
-rw-r--r--.gitignore1
-rw-r--r--Src/PyCatcher/GUI/catcher_main.glade85
-rw-r--r--Src/PyCatcher/GUI/mainWindow.glade293
-rw-r--r--Src/PyCatcher/src/driverConnector.py30
-rw-r--r--Src/PyCatcher/src/evaluators.py31
-rw-r--r--Src/PyCatcher/src/pyCatcherController.py55
-rw-r--r--Src/PyCatcher/src/pyCatcherModel.py59
-rw-r--r--Src/PyCatcher/src/pyCatcherView.py121
-rw-r--r--Src/PyCatcher/src/rules.py49
-rw-r--r--Src/PyCatcher/src/settings.py42
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/catcher.c20
11 files changed, 398 insertions, 388 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43dc42d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+Src/PyCatcher/.idea/*
diff --git a/Src/PyCatcher/GUI/catcher_main.glade b/Src/PyCatcher/GUI/catcher_main.glade
index 5efb309..3aec4cb 100644
--- a/Src/PyCatcher/GUI/catcher_main.glade
+++ b/Src/PyCatcher/GUI/catcher_main.glade
@@ -3,9 +3,11 @@
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkWindow" id="detail_view">
<property name="can_focus">False</property>
- <property name="type">popup</property>
- <property name="destroy_with_parent">True</property>
+ <property name="title" translatable="yes">Details</property>
+ <property name="default_width">500</property>
+ <property name="default_height">500</property>
<property name="has_resize_grip">False</property>
+ <signal name="delete-event" handler="_on_details_delete" swapped="no"/>
<child>
<object class="GtkTextView" id="te_detail_view">
<property name="visible">True</property>
@@ -81,12 +83,19 @@
</packing>
</child>
<child>
- <object class="GtkHSeparator" id="separator1">
+ <object class="GtkRadioButton" id="rb_weighted_evaluator">
+ <property name="label" translatable="yes">Weighted Evaluator</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rb_conservative_evaluator</property>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
@@ -331,20 +340,7 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="cb_only_scanned_bs">
- <property name="label" translatable="yes">Show only BS, that have been found</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">7</property>
- </packing>
+ <placeholder/>
</child>
</object>
<packing>
@@ -449,6 +445,36 @@
<property name="homogeneous">True</property>
</packing>
</child>
+ <child>
+ <object class="GtkToolButton" id="btn_save_project">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">Save Project</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">document-save</property>
+ <signal name="clicked" handler="_on_save_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="btn_load_project">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">Load Project</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">document-open</property>
+ <signal name="clicked" handler="_on_load_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -591,6 +617,7 @@
<object class="GtkTreeView" id="tv_stations">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <signal name="select-cursor-row" handler="_on_tv_stations_clicked" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection"/>
</child>
@@ -739,8 +766,8 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="cb_cell_id">
- <property name="label" translatable="yes">Unique Cell ID</property>
+ <object class="GtkCheckButton" id="cb_uniqueness">
+ <property name="label" translatable="yes">Uniqueness</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -896,6 +923,22 @@
<property name="position">9</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="cb_arfcn">
+ <property name="label" translatable="yes">ARFCN/Provider Mapping</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">10</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/Src/PyCatcher/GUI/mainWindow.glade b/Src/PyCatcher/GUI/mainWindow.glade
deleted file mode 100644
index 1b7da70..0000000
--- a/Src/PyCatcher/GUI/mainWindow.glade
+++ /dev/null
@@ -1,293 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<glade-interface>
- <!-- interface-requires gtk+ 2.24 -->
- <!-- interface-naming-policy project-wide -->
- <widget class="GtkWindow" id="main_window">
- <property name="can_focus">False</property>
- <property name="title" translatable="yes">IMSI Catcher Detector</property>
- <property name="default_width">1024</property>
- <property name="default_height">700</property>
- <signal name="destroy" handler="on_main_window_destroy" swapped="no"/>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <widget class="GtkToolbar" id="main_toolbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="toolbar_style">both</property>
- <child>
- <widget class="GtkToggleToolButton" id="firmware_toggle">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Toggle Firmware</property>
- <property name="use_underline">True</property>
- <property name="icon_name">modem</property>
- <signal name="toggled" handler="on_firmware_toggle_toggled" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToggleToolButton" id="scan_toggle">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Toggle Scanning</property>
- <property name="use_underline">True</property>
- <property name="icon_name">network-wireless</property>
- <signal name="toggled" handler="on_scan_toggle_toggled" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="open_file">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Open File</property>
- <property name="use_underline">True</property>
- <property name="icon_name">document-open</property>
- <signal name="clicked" handler="on_open_file_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="save_project">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Save Project</property>
- <property name="use_underline">True</property>
- <property name="icon_name">document-save</property>
- <signal name="clicked" handler="on_save_project_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <widget class="GtkToolbar" id="graph_control">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <widget class="GtkToolButton" id="graph_zoom_in">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Zoom In</property>
- <property name="use_underline">True</property>
- <property name="icon_name">zoom-in</property>
- <signal name="clicked" handler="on_graph_zoom_in_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="graph_zoom_out">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Zoom Out</property>
- <property name="use_underline">True</property>
- <property name="icon_name">zoom-out</property>
- <signal name="clicked" handler="on_graph_zoom_out_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="graph_fit">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">Fit To Screen</property>
- <property name="use_underline">True</property>
- <property name="icon_name">zoom-best-fit</property>
- <signal name="clicked" handler="on_graph_fit_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="graph_zoom_default">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_action_appearance">False</property>
- <property name="label" translatable="yes">100%</property>
- <property name="use_underline">True</property>
- <property name="icon_name">zoom-original</property>
- <signal name="clicked" handler="on_graph_zoom_default_clicked" swapped="no"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVSeparator" id="vseparator1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <widget class="GtkTreeView" id="bs_table">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <child>
- <widget class="GtkTextView" id="log_output">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkStatusbar" id="statusbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <widget class="GtkLabel" id="status_firmware">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Firmware: Not Loaded</property>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="status_scanner">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Scanner: Not scanning</property>
- </widget>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
-</glade-interface>
diff --git a/Src/PyCatcher/src/driverConnector.py b/Src/PyCatcher/src/driverConnector.py
index 20791dd..0b0703b 100644
--- a/Src/PyCatcher/src/driverConnector.py
+++ b/Src/PyCatcher/src/driverConnector.py
@@ -2,7 +2,7 @@ from pyCatcherModel import BaseStationInformation
import subprocess
import threading
import re
-from pyCatcherSettings import Commands
+from settings import Commands
import time
import gtk
@@ -61,7 +61,6 @@ class FirmwareThread(threading.Thread):
if line.strip() == 'Finishing download phase':
self._firmware_loaded_callback()
#time.sleep(0.5)
- print 'killing firmware'
loader_process_object.terminate()
class ScanThread(threading.Thread):
@@ -95,49 +94,48 @@ class ScanThread(threading.Thread):
if match:
base_station.provider = match.group(1)
#get arfcn
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'ARFCN:\s(\d+)',line)
if match:
base_station.arfcn = int(match.group(1))
#get cell id
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'Cell ID:\s(\d+)',line)
if match:
- base_station.arfcn = int(match.group(1))
+ base_station.cell = int(match.group(1))
#get lac
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'LAC:\s(\d+)',line)
if match:
base_station.lac = int(match.group(1))
#get bsic
- line = line = scan_process.stdout.readline()
- match = re.search(r'BSIC:\s(\.+)\s',line)
+ line = scan_process.stdout.readline()
+ match = re.search(r'BSIC:\s(\d+,\d+)',line)
if match:
- base_station.bsic = int(match.group(1))
+ base_station.bsic = match.group(1)
#get rxlev
- line = line = scan_process.stdout.readline()
- match = re.search(r'rxlev\s(.\d+)',line)
+ line = scan_process.stdout.readline()
+ match = re.search(r'rxlev:\s(.\d+)',line)
if match:
base_station.rxlev = match.group(1)
#get si2
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'si2\s(.+)',line)
if match:
base_station.system_info_t2 = match.group(1).split(' ')
#get si2bis
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'si2bis\s(.+)',line)
if match:
base_station.system_info_t2bis = match.group(1).split(' ')
#get si2ter
- line = line = scan_process.stdout.readline()
+ line = scan_process.stdout.readline()
match = re.search(r'si2ter\s(.+)',line)
if match:
base_station.system_info_t2ter = match.group(1).split(' ')
#endinfo
- line = line = scan_process.stdout.readline()
+ scan_process.stdout.readline()
self._base_station_found_callback(base_station)
- print 'killing scan'
scan_process.terminate()
\ No newline at end of file
diff --git a/Src/PyCatcher/src/evaluators.py b/Src/PyCatcher/src/evaluators.py
new file mode 100644
index 0000000..3170f4a
--- /dev/null
+++ b/Src/PyCatcher/src/evaluators.py
@@ -0,0 +1,31 @@
+from rules import RuleResult
+
+class EvaluatorSelect:
+ CONSERVATIVE = 0
+ WEIGHTED = 1
+ BAYES = 2
+
+class Evaluator:
+
+ return_type = type(RuleResult)
+
+ def evaluate(self, result_list):
+ return RuleResult.CRITICAL
+
+class ConservativeEvaluator(Evaluator):
+
+ def evaluate(self, result_list):
+ final_result = RuleResult.OK
+ for key in result_list.keys():
+ if result_list[key] == RuleResult.WARNING:
+ final_result = RuleResult.WARNING
+ if result_list[key] == RuleResult.CRITICAL:
+ final_result = RuleResult.CRITICAL
+ break
+ return final_result
+
+class BayesEvaluator(Evaluator):
+ return_type = type(int)
+
+class WeightedEvaluator(Evaluator):
+ return_type = type(int) \ No newline at end of file
diff --git a/Src/PyCatcher/src/pyCatcherController.py b/Src/PyCatcher/src/pyCatcherController.py
index ce8c938..af2e0a5 100644
--- a/Src/PyCatcher/src/pyCatcherController.py
+++ b/Src/PyCatcher/src/pyCatcherController.py
@@ -1,11 +1,12 @@
-import sys
-import pygtk
-import gtk
+import gtk
import gtk.glade
from driverConnector import DriverConnector
from pyCatcherModel import BaseStationInformation, BaseStationInformationList
from pyCatcherView import PyCatcherGUI
from filters import ARFCNFilter,FoundFilter,ProviderFilter
+from evaluators import EvaluatorSelect, BayesEvaluator, ConservativeEvaluator, WeightedEvaluator
+from rules import ProviderRule
+import pickle
class PyCatcherController:
def __init__(self):
@@ -15,14 +16,23 @@ class PyCatcherController:
self.bs_tree_list_data = store
self._gui = PyCatcherGUI(self)
self._driver_connector = DriverConnector()
- self._gui.log_line("GUI initialized")
+ self._gui.log_line('GUI initialized')
self.arfcn_filter = ARFCNFilter()
self.provider_filter = ProviderFilter()
self.found_filter = FoundFilter()
self._filters = [self.arfcn_filter, self.provider_filter]
-
+
+ self._conservative_evaluator = ConservativeEvaluator()
+ self._bayes_evaluator = BayesEvaluator()
+ self._weighted_evaluator = WeightedEvaluator()
+ self._active_evaluator = self._conservative_evaluator
+
+ self.provider_rule = ProviderRule()
+ self.provider_rule.is_active = True
+ self._rules = [self.provider_rule]
+
gtk.main()
def log_message(self, message):
@@ -42,7 +52,6 @@ class PyCatcherController:
def stop_firmware(self):
self._gui.log_line("stop firmware")
- print 'stop firmwares'
self._driver_connector.stop_firmware()
def shutdown(self):
@@ -50,9 +59,10 @@ class PyCatcherController:
def _found_base_station_callback(self, base_station):
self._gui.log_line("found " + base_station.provider + ' (' + str(base_station.arfcn) + ')')
- self._base_station_list.add_station(base_station)
+ self._base_station_list.add_station(base_station)
+ self._base_station_list.evaluate(self._rules, self._active_evaluator)
self._base_station_list.refill_store(self.bs_tree_list_data)
- dotcode = self._base_station_list.get_dot_code(self._filters,self.found_filter)
+ dotcode = self._base_station_list.get_dot_code(self._filters, self.found_filter)
self._gui.load_dot(dotcode)
def trigger_redraw(self):
@@ -67,4 +77,31 @@ class PyCatcherController:
def _firmware_done_callback(self):
self._gui.log_line("firmware loaded, ready for scanning")
self._gui.show_info('Firmware load completed', 'Firmware')
- \ No newline at end of file
+
+ def fetch_report(self, arfcn):
+ return self._base_station_list.create_report(arfcn)
+
+ def set_evaluator (self, evaluator):
+ if evaluator == EvaluatorSelect.CONSERVATIVE:
+ self._active_evaluator = self._conservative_evaluator
+ elif evaluator == EvaluatorSelect.BAYES:
+ self._active_evaluator = self._bayes_evaluator
+ elif evaluator == EvaluatorSelect.WEIGHTED:
+ self._active_evaluator = self._weighted_evaluator
+
+ def save_project(self, path):
+ filehandler = open(path, 'w')
+ pickle.dump(self._base_station_list, filehandler)
+ filehandler.close()
+ self._gui.log_line('Project saved to ' + path)
+
+ def load_project(self, path):
+ filehandler = open(path, 'r')
+ base_station_list = pickle.load(filehandler)
+ self._base_station_list = base_station_list
+ self._base_station_list.evaluate(self._rules, self._active_evaluator)
+ self._base_station_list.refill_store(self.bs_tree_list_data)
+ dotcode = self._base_station_list.get_dot_code(self._filters, self.found_filter)
+ self._gui.load_dot(dotcode)
+ filehandler.close()
+ self._gui.log_line('Project leaded from ' + path) \ No newline at end of file
diff --git a/Src/PyCatcher/src/pyCatcherModel.py b/Src/PyCatcher/src/pyCatcherModel.py
index 5de6234..0d5fb91 100644
--- a/Src/PyCatcher/src/pyCatcherModel.py
+++ b/Src/PyCatcher/src/pyCatcherModel.py
@@ -21,7 +21,7 @@ class BaseStationInformation:
self.evaluation = 'NYE'
def get_list_model(self):
- return (self.provider, str(self.arfcn), str(self.rxlev), self.evaluation, self.discovery_time)
+ return self.provider, str(self.arfcn), str(self.rxlev), self.evaluation, self.discovery_time
def get_neighbour_arfcn(self):
neighbours = self.system_info_t2[3:19]
@@ -31,11 +31,11 @@ class BaseStationInformation:
for value in neighbours:
bin_representation += str(bin(int(value, 16))[2:].zfill(8))
- '''
- >>> for i, bit in enumerate(reversed(a)):
-... if bit == '1':
-... print i
- '''
+
+ # for i, bit in enumerate(reversed(a)):
+ # if bit == '1':
+ # print i
+
for x in xrange(1,125):
index = 0-x
bit = bin_representation[index]
@@ -48,9 +48,30 @@ class BaseStationInformation:
def get_neighbour_arfcn_bis(self):
pass
-
- def create_lof(self):
- pass
+
+ def create_report(self):
+ report_params = '''------- Base Station Parameters -----------
+Country: %s
+Provider: %s
+ARFCN: %s
+rxlev: %s
+BSIC: %s
+LAC: %s
+Cell ID: %s
+Neighbours: %s
+Evaluation: %s\n
+'''%(self.country,self.provider, self.arfcn, self.rxlev, self.bsic, self.lac, self.cell, ', '.join(map(str,self.get_neighbour_arfcn())),self.evaluation)
+
+ report_rules ='------- Rule Results -----------\n'
+ for key in self.rules_report.keys():
+ report_rules += str(key) + ': ' + str(self.rules_report[key])
+ report_rules +='\n\n'
+ report_raw = '''------- Raw Information -----------
+SystemInfo_2: %s
+SystemInfo_2ter: %s
+SystemInfo_2bis: %s
+'''%(' '.join(self.system_info_t2), ' '.join(self.system_info_t2ter), ' '.join(self.system_info_t2bis))
+ return report_params + report_rules + report_raw
class BaseStationInformationList:
def __init__(self):
@@ -70,19 +91,19 @@ class BaseStationInformationList:
code = ''
filtered_list = self._base_station_list
- if found_filter == None:
+ if found_filter is None:
print_neighbours = True
else:
print_neighbours = not found_filter.is_active
- if filters != None:
+ if filters is not None:
for filter in filters:
if filter.is_active:
filtered_list = filter.execute(filtered_list)
for station in filtered_list:
code += str(station.arfcn) + r' [color=red]; '
- if(print_neighbours):
+ if print_neighbours:
for neighbour in station.get_neighbour_arfcn():
code += str(station.arfcn) + r' -> ' + str(neighbour) + r'; '
#TODO: make printing the source a fixed option
@@ -93,4 +114,18 @@ class BaseStationInformationList:
store.clear()
for item in self._base_station_list:
store.append(item.get_list_model())
+
+ def create_report(self, arfcn):
+ for item in self._base_station_list:
+ if item.arfcn == int(arfcn):
+ return item.create_report()
+
+ def evaluate(self, rules, evaluator):
+ for station in self._base_station_list:
+ rule_results = {}
+ for rule in rules:
+ if rule.is_active:
+ rule_results[rule.identifier] = rule.check(station.arfcn, self._base_station_list)
+ station.rules_report = rule_results.copy()
+ station.evaluation = evaluator.evaluate(rule_results)
\ No newline at end of file
diff --git a/Src/PyCatcher/src/pyCatcherView.py b/Src/PyCatcher/src/pyCatcherView.py
index 399ef6e..b9613f0 100644
--- a/Src/PyCatcher/src/pyCatcherView.py
+++ b/Src/PyCatcher/src/pyCatcherView.py
@@ -27,7 +27,8 @@ class PyCatcherGUI:
self._add_column("Provider", 0)
self._add_column("ARFCN", 1)
self._add_column("Strength",2)
- self._add_column("Last seen", 3)
+ self._add_column("Evaluation",3)
+ self._add_column("Last seen", 4)
self._bs_tree_view.set_model(self._catcher_controller.bs_tree_list_data)
self._horizontal_container = self._builder.get_object('vbox2')
@@ -36,9 +37,12 @@ class PyCatcherGUI:
self._dot_widget.set_filter('neato')
self._dot_widget.show()
self._dot_widget.connect('clicked', self._on_graph_node_clicked)
-
+
self._builder.connect_signals(self)
+ detail_view_text = self._builder.get_object('te_detail_view')
+ self._detail_buffer = detail_view_text.get_buffer()
+
log_view = self._builder.get_object('te_log')
self._log_buffer = log_view.get_buffer()
self._log_buffer.insert(self._log_buffer.get_end_iter(),self._utf8conv("-- Log execution on " + datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M %p") + " --\n\n"))
@@ -55,28 +59,43 @@ class PyCatcherGUI:
if self._builder.get_object('cb_filter_by_provider').get_active():
self._catcher_controller.provider_filter.params = {'providers': self._builder.get_object('te_filter_provider').get_text()}
self._catcher_controller.provider_filter.is_active = True
- print 'provider active'
else:
- self._catcher_controller.provider_filter.is_active = False
- print 'provider off'
+ self._catcher_controller.provider_filter.is_active = False
if self._builder.get_object('cb_filter_by_arfcn').get_active():
self._catcher_controller.arfcn_filter.params = {'from':int(self._builder.get_object('te_filter_arfcn_from').get_text()),
'to':int(self._builder.get_object('te_filter_arfcn_to').get_text())}
self._catcher_controller.arfcn_filter.is_active = True
- print 'arfcn active'
else:
self._catcher_controller.arfcn_filter.is_active = False
- print 'arfcn off'
if self._builder.get_object('cb_only_scanned_bs').get_active():
self._catcher_controller.found_filter.is_active = True
- print 'scanned active'
else:
self._catcher_controller.found_filter.is_active = False
- print 'scanned off'
-
+
self._catcher_controller.trigger_redraw()
+
+ def _update_rules(self):
+ pass
+
+ def _update_evaluators(self):
+ pass
+
+ def show_info(self, message, title='PyCatcher', time_to_sleep=3, type='INFO'):
+ gtk_type = {'INFO' : gtk.MESSAGE_INFO,
+ 'ERROR': gtk.MESSAGE_ERROR}
+
+ dlg = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
+ message_format=str(message)
+ )
+ dlg.set_title(title)
+ dlg.show()
+ time.sleep(time_to_sleep)
+ dlg.destroy()
+
+ def log_line(self, line):
+ self._log_buffer.insert(self._log_buffer.get_end_iter(),self._utf8conv(datetime.datetime.now().strftime("%I:%M:%S %p")+ ": " + line + "\n"))
def _on_graph_node_clicked (self, widget, url, event):
print 'NODE CLICKED'
@@ -86,13 +105,13 @@ class PyCatcherGUI:
gtk.main_quit()
def _on_scan_toggled(self, widget):
- if(widget.get_active()):
+ if widget.get_active():
self._catcher_controller.start_scan()
else:
self._catcher_controller.stop_scan()
def _on_firmware_toggled(self, widget):
- if(widget.get_active()):
+ if widget.get_active():
self._catcher_controller.start_firmware()
else:
self._catcher_controller.stop_firmware()
@@ -105,6 +124,7 @@ class PyCatcherGUI:
self._filter_window.hide()
def _on_rules_close_clicked(self, widget):
+ self._update_rules()
self._rules_window.hide()
def _on_evaluators_clicked(self, widget):
@@ -114,8 +134,69 @@ class PyCatcherGUI:
self._rules_window.show()
def _on_evaluators_close_clicked(self, widget):
+ self._update_evaluators()
self._evaluators_window.hide()
+ def _on_tv_stations_clicked(self, widget, unecessary_parameter_just_for_signature):
+ selection = widget.get_selection()
+ model, treeiter = selection.get_selected()
+ if treeiter is not None:
+ arfcn = model[treeiter][1]
+ report = self._catcher_controller.fetch_report(arfcn)
+ self._detail_buffer.set_text(self._utf8conv(report))
+ self._detail_window.show()
+
+ def _on_details_delete(self, widget, dunno_what_this_param_does):
+ self._detail_window.hide()
+ return True
+
+ def _on_save_clicked(self, widget):
+ chooser = gtk.FileChooserDialog(title="Save Project",
+ action=gtk.FILE_CHOOSER_ACTION_SAVE,
+ buttons=(gtk.STOCK_CANCEL,
+ gtk.RESPONSE_CANCEL,
+ gtk.STOCK_SAVE,
+ gtk.RESPONSE_OK))
+ chooser.set_default_response(gtk.RESPONSE_OK)
+ filter = gtk.FileFilter()
+ filter.set_name("Catcher Project Files")
+ filter.add_pattern("*.cpf")
+ chooser.add_filter(filter)
+ filter = gtk.FileFilter()
+ filter.set_name("All files")
+ filter.add_pattern("*")
+ chooser.add_filter(filter)
+ if chooser.run() == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ chooser.destroy()
+ self._catcher_controller.save_project(filename)
+ else:
+ chooser.destroy()
+
+ def _on_load_clicked(self, widget):
+ chooser = gtk.FileChooserDialog(title="Open Project",
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL,
+ gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN,
+ gtk.RESPONSE_OK))
+ chooser.set_default_response(gtk.RESPONSE_OK)
+ filter = gtk.FileFilter()
+ filter.set_name("Catcher Project Files")
+ filter.add_pattern("*.cpf")
+ chooser.add_filter(filter)
+ filter = gtk.FileFilter()
+ filter.set_name("All files")
+ filter.add_pattern("*")
+ chooser.add_filter(filter)
+ if chooser.run() == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ chooser.destroy()
+ self._catcher_controller.load_project(filename)
+ else:
+ chooser.destroy()
+
+ #---------------- Viewer Bindings ----------------------------------------------------#
def _on_open_file_clicked(self, widget):
chooser = gtk.FileChooserDialog(title="Open dot File",
action=gtk.FILE_CHOOSER_ACTION_OPEN,
@@ -161,20 +242,6 @@ class PyCatcherGUI:
def load_dot(self, dotcode, filename="<stdin>"):
if self._dot_widget.set_dotcode(dotcode, filename):
- #self._dot_widget.zoom_to_fit()
+ #self._dot_widget.zoom_to_fit()
pass
- def show_info(self, message, title='PyCatcher', time_to_sleep=3, type='INFO'):
- gtk_type = {'INFO' : gtk.MESSAGE_INFO,
- 'ERROR': gtk.MESSAGE_ERROR}
-
- dlg = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
- message_format=str(message)
- )
- dlg.set_title(title)
- dlg.show()
- time.sleep(time_to_sleep)
- dlg.destroy()
-
- def log_line(self, line):
- self._log_buffer.insert(self._log_buffer.get_end_iter(),self._utf8conv(datetime.datetime.now().strftime("%I:%M:%S %p")+ ": " + line + "\n")) \ No newline at end of file
diff --git a/Src/PyCatcher/src/rules.py b/Src/PyCatcher/src/rules.py
new file mode 100644
index 0000000..8575766
--- /dev/null
+++ b/Src/PyCatcher/src/rules.py
@@ -0,0 +1,49 @@
+import pyCatcherModel
+from settings import Provider_list, Provider_Country_list
+
+class RuleResult:
+ OK = 'Ok'
+ WARNING = 'Warning'
+ CRITICAL = 'Critical'
+
+class Rule:
+
+ is_active = False
+ identifier = 'Rule'
+
+ def check(self, arfcn, base_station_list):
+ return RuleResult.CRITICAL
+
+class ProviderRule (Rule):
+
+ identifier = 'Provider Check'
+
+ def check(self, arfcn, base_station_list):
+ result = RuleResult.CRITICAL
+ for station in base_station_list:
+ if station.arfcn == arfcn:
+ if station.provider in Provider_list:
+ result = RuleResult.OK
+ break
+ return result
+
+class CountryProvider (Rule):
+ pass
+
+class BSICIntegrity (Rule):
+ pass
+
+class Uniqueness (Rule):
+ pass
+
+class NeighbourhoodStructure (Rule):
+ pass
+
+class LACIntegrity (Rule):
+ pass
+
+class CellIDDatabase (Rule):
+ pass
+
+class MachineLearning (Rule):
+ pass \ No newline at end of file
diff --git a/Src/PyCatcher/src/settings.py b/Src/PyCatcher/src/settings.py
new file mode 100644
index 0000000..7ad42fe
--- /dev/null
+++ b/Src/PyCatcher/src/settings.py
@@ -0,0 +1,42 @@
+#Core Configuration ------------------------------------------------------------------------------------------
+
+PyCatcher_settings = {'debug' : False,
+ }
+
+Device_settings = { 'mobile_device' : '/dev/ttyUSB0',
+ 'xor_type' : 'c123xor',
+ 'firmware' : 'compal_e88',
+ }
+
+Osmocon_lib = '/home/tom/imsi-catcher-detection/Src/osmolib/src'
+
+Commands = {'osmocon_command' : [Osmocon_lib + '/host/osmocon/osmocon',
+ '-p', Device_settings['mobile_device'],
+ '-m', Device_settings['xor_type'],
+ Osmocon_lib + '/target/firmware/board/' + Device_settings['firmware'] + '/layer1.compalram.bin'],
+ 'scan_command' : [Osmocon_lib + '/host/layer23/src/misc/catcher'],
+ }
+
+#Rules Configuration -------------------------------------------------------------------------------------------
+
+Provider_list = ['T-Mobile', 'O2']
+
+Provider_Country_list = {
+'T-Mobile':'Germany',
+'O2':'France'
+}
+
+LAC_mappings = {
+
+}
+
+BSIC_database = ''
+
+Cell_ID_database = ''
+
+Home_database = ''
+
+#Evaluator Configuration ---------------------------------------------------------------------------------------
+
+Bayes_probabilities = {}
+Bayes_database = '' \ No newline at end of file
diff --git a/Src/osmolib/src/host/layer23/src/misc/catcher.c b/Src/osmolib/src/host/layer23/src/misc/catcher.c
index a9fe533..f4a69f0 100644
--- a/Src/osmolib/src/host/layer23/src/misc/catcher.c
+++ b/Src/osmolib/src/host/layer23/src/misc/catcher.c
@@ -620,7 +620,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
}
switch (sih->system_information) {
case GSM48_MT_RR_SYSINFO_1:
- LOGFILE("Got Sysinfo 1\n");
+ //LOGFILE("Got Sysinfo 1\n");
if (!memcmp(sih, s->si1_msg, sizeof(s->si1_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
@@ -629,7 +629,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_2:
- LOGFILE("Got Sysinfo 2\n");
+ //LOGFILE("Got Sysinfo 2\n");
if (!memcmp(sih, s->si2_msg, sizeof(s->si2_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
@@ -638,7 +638,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_2bis:
- LOGFILE("Got Sysinfo 2bis\n");
+ //LOGFILE("Got Sysinfo 2bis\n");
if (!memcmp(sih, s->si2b_msg, sizeof(s->si2b_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
@@ -647,7 +647,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_2ter:
- LOGFILE("Got Sysinfo 2ter\n");
+ //LOGFILE("Got Sysinfo 2ter\n");
if (!memcmp(sih, s->si2t_msg, sizeof(s->si2t_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
@@ -656,7 +656,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_3:
- LOGFILE("Got Sysinfo 3\n");
+ //LOGFILE("Got Sysinfo 3\n");
if (!memcmp(sih, s->si3_msg, sizeof(s->si3_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3\n");
@@ -669,7 +669,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
l1ctl_tx_ccch_mode_req(ms, ccch_mode);
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_4:
- LOGFILE("Got Sysinfo 4\n");
+ //LOGFILE("Got Sysinfo 4\n");
if (!memcmp(sih, s->si4_msg, sizeof(s->si4_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
@@ -678,7 +678,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_5:
- LOGFILE("Got Sysinfo 5\n");
+ //LOGFILE("Got Sysinfo 5\n");
if (!memcmp(sih, s->si5_msg, sizeof(s->si5_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5\n");
@@ -687,7 +687,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_5bis:
- LOGFILE("Got Sysinfo 5bis\n");
+ //LOGFILE("Got Sysinfo 5bis\n");
if (!memcmp(sih, s->si5b_msg, sizeof(s->si5b_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5bis\n");
@@ -696,7 +696,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_5ter:
- LOGFILE("Got Sysinfo 5ter\n");
+ //LOGFILE("Got Sysinfo 5ter\n");
if (!memcmp(sih, s->si5t_msg, sizeof(s->si5t_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5ter\n");
@@ -705,7 +705,7 @@ static int bcch(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3len(msg));
return new_sysinfo();
case GSM48_MT_RR_SYSINFO_6:
- LOGFILE("Got Sysinfo 6\n");
+ //LOGFILE("Got Sysinfo 6\n");
if (!memcmp(sih, s->si6_msg, sizeof(s->si6_msg)))
return 0;
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 6\n");