antikythera package¶
Subpackages¶
Submodules¶
antikythera.Logfile module¶
antikythera.antikythera module¶
antikythera.py
The main program manager.
-
class
antikythera.antikythera.
Anti
(num_processes, headless, interface=None, capturefile=None, max_qsize=100000, *args, **kwargs)[source]¶ Bases:
multiprocessing.context.Process
Start and monitor the worker processes.
-
antikythera.antikythera.
create_parser
()[source]¶ Parse command line parameters.
Returns: command line parameters as argparse.Namespace
Parameters: args ([str]) – List of strings representing the command line arguments. Returns: Simple object with a readable string representation of the argument list. Return type: argparse.Namespace
antikythera.capture module¶
capture.py
Interface to the radio and Pcap files.
antikythera.cli module¶
cli.py
This is the Antikythera console script. It provides the
entry points that are used to run the program when it is
installed. To install the program run python setup.py install
and it will be installed on the system.
-
antikythera.cli.
main
(args)[source]¶ Main entry point allowing external calls.
Collects command line arguments, sets up the logs, and logs information about them. Then it starts the program loop.
Parameters: args ([str]) – command line parameter list
-
antikythera.cli.
setup_logs
(loglevel)[source]¶ Set up logger to be used between all modules.
Set logging root and file handler configuration to default to
INFO
and write output tomain.log
. Set console handler to default toINFO
.Parameters: str (loglevel) – A string of one of the Default Python logging levels. See the Python logging level documentation for more information.
antikythera.conditions module¶
Pull variables from db, if any variable contains data then set corresponding variable equal to one. follow through till all
antikythera.decoder module¶
decoder.py
Unwrap the pyshark packets and put the needed data into the database.
Abbreviations:
RXLEV: Reception Level (GSM).
NCELL: neighboring cell.
- BSIC-NCELL: Abbreviation for Base Station Identity Code of
- an adjacent CELL. Identifies and decode the BCCH (Broadcast Control Channel) of neighbouring cells so that the MS (Mobile Station) may take measuring reports to facilitate handover, or to allow the MS to make cell selection and reselection calculations.
- NO-NCELL-M: No neighbour cell measurement result. One byte
- unsigned integer representing the number of neighbour cells.
- FULL vs. SUB Values:
In GSM, there are two types of values presented for RxQual, namely RxQual Full and RxQual Sub. RxLev, the parameter representing the signal strength, also has similar Full and Sub values. The FULL values are based upon all frames on the SACCH multiframe, whether they have been transmitted from the base station or not. This means that if DTX DL has been used, the FULL values will be invalid for that period since they include bit-error measurements at periods when nothing has been sent resulting in very high BER. In total, 100 bursts (25 blocks) will be used for the FULL values.
The SUB values are based on the mandatory frames on the SACCH multiframe. These frames must always be transmitted. There are two frames fulfilling that criteria and that is the SACCH block (A bursts in Figure 7) and the block holding the SID frame. If DTX DL is not in use, the SID frame will contain an ordinary speech frame and then this is included instead. In total, 12 bursts (two blocks) will be used for the SUB values (four bursts SACCH and eight half bursts [or speech] information).
Further Reference:
-
class
antikythera.decoder.
Decoder
(process_id, queue, *args, **kwargs)[source]¶ Bases:
multiprocessing.context.Process
Decode and store the packets for analysis.
The
run()
function is the process main loop. It first sets up the tables needed by thePacketManager
to sort the packets into withcreate_tables()
. Then until the Multiprocessing eventexit
is set by the manager process it continually pulls packets out of the sharedqueue
and hands them off to thePacketManager
for processing.-
create_tables
()[source]¶ Create packet tables.
Create all tables required by the
PacketManager
if they do not exist. Data that is in the GSMTAP layer of the packets is common between all packets and is therefore present in all tables. It includes:- HASH
- UnixTime
- PeopleTime
- CHANNEL
- DBM
- ARFCN
- FrameNumber
Everything else is information that is specific to the Packet(s) that are inserted in the given table. Tables are created for each group of packets data important to a given query.
-
-
class
antikythera.decoder.
LACPacket
(packet)[source]¶ Bases:
antikythera.decoder.Packet
Location Area Code (LAC) Packet.
A packet with LAC, CID, and ARFCN data.
-
class
antikythera.decoder.
Packet
(packet)[source]¶ Bases:
object
Gather packet generic GSMTAP information.
-
class
antikythera.decoder.
PacketManager
(process_id, data_dir)[source]¶ Bases:
object
Manage operations on packets.
-
process_id
¶ str – Process identifier.
-
data_dir
¶ str – Where the database is stored.
-
packet_types
¶ dict – Implemented packet types. Keys are packet major types and value is a list of implemented subtypes.
-
packet_metrics
¶ dict – Returns the table the packet should be sorted into given (MAJOR_TYPE + _ + MINOR_TYPE) for example, “GSM_A.DTAP_30” representing the system message subtype 30 which contains LAC and CID information.
-
get_packet_info
(data_layer, _type, _subtype, implemented)[source]¶ Attempt to get a brief description of the packet.
Parameters: Returns: - A brief description of the contents
of the packet. Empty string if not available.
Return type: packet_info (str)
-
get_packet_type
()[source]¶ Get the packet type and subtype information.
-
_type
¶ str – The name of the unique packet data layer.
-
data_layer
¶ The actual packet data layer object.
-
attributes
¶ list – A list of strings with the names of all valid attributes and methods for the data layer object.
-
index
¶ int – The zero indexed location of the packet. For a live capture it would represent the number of packets received. For a
.pcap
file it is the index that the packet is found at if the file is read into a Pyshark object usingFileCapture
.
-
no_type
¶ str – An error message used when the packet type is not implemented.
-
no_subtype
¶ str – An error message used when the packet type is implemented but not the subtype.
Returns: packet type string and subtype int tuple.
-
-
-
class
antikythera.decoder.
PagePacket
(packet)[source]¶ Bases:
antikythera.decoder.Packet
Location Area Code (LAC) Packet.
A packet with LAC data.
antikythera.gui module¶
antikythera.kivylogs module¶
kivylogs.py
Fix Kivy’s logger so it is compatible with modules using the standard python logger, this must remain in the same order and be at the top of the entry point module for the application.
This code is extremely fragile and must be declared and executed in this exact order.
antikythera.metrics module¶
metrics.py
Implementation of the metrics that detect IMSI Catchers
Acronyms:
- ARFCN: Absolute Radio Frequency Channel Number, a unique number
- given to each radio channel in GSM. The ARFCN can be used to calculate the exact frequency of the radio channel.
IMSI: International Subscriber Identity LAC: Location Area Code CID: Cell Identification Code N-CELL-LAC: Neighboring Cell Location Area Code
Reference:
- SnoopSnitch Metrics:
- https://opensource.srlabs.de/projects/snoopsnitch/wiki/IMSI_Catcher_Score
-
class
antikythera.metrics.
Metrics
(process_id, sharedMemory=None, *args, **kwargs)[source]¶ Bases:
multiprocessing.context.Process
The metrics
-
imposter_cell
()[source]¶ Same LAC/CID on different ARFCNs
A cell is received on different ARFCNs (frequencies) within a short time.
Rationale:
To avoid leaving traces of a new, non-existent cell, an IMSI catcher may choose to reuse the cell ID and LAC of an existing cell in an area, but using a different frequency. The IMSI catcher must have a location area different from the current serving cell, such that the MS performs a location update once it close enough. The use of the cell ID on different frequencies may be detected by the analysis if system information of the original cell was received earlier.False Positives:
A cell may be reconfigured to use a different frequency, but this should happen very rarely.Example
A simple example would be a single two identical CID and LAC pairs advertising different ARFCNs.
- Good Cell
- LAC 1
- CID 7
- ARFCN 42
- Evil Cell
- LAC 1
- CID 7
- ARFCN 1337
The evil cell is pretending to be in the location area code to not trigger a lonely LAC metric, and to not leave a trace of a strange cell wandering all over town.
Reference:
The following SQL query will find packets that share the same Location Area Code and Cell ID, but have different ARFCNs.
-
inconsistent_lac
()[source]¶ Inconsistent LAC
The LAC of the current base station differs from the LAC of many neighboring cells.
Rationale:
A mobile will only perform a normal location update when changing to a different area, i.e. a base station with a different LAC. An IMSI catcher needs to force a location update to be able to interact with the phone and derive the desired information. Therefore, it must span a cell with a LAC different to all neighboring cells, but with a much better signal strength than the other cells. For an IMSI catcher announcing realistic neighboring cells, this difference between the LAC of the serving cell and all neighboring cell can be detected.False Positives:
Femto cells may or may not announce a LAC different from all their neighboring cells. Their may be other special situations, like in-house cells where this is the case.Example
A simple example would be a LAC being the only observed LAC.
- Evil IMSI Catcher Reports:
- CID 1337
- LAC 13
- All neighboring cells reported by Evil IMSI Catcher are:
- LAC 7
The evil cell is pretending to be in the location area code to not trigger a lonely LAC metric, and to not leave a trace of a strange cell wandering all over town. It is detected by all cells it advertises having a different LAC.
The information must be obtained form the Evil Cells reporting of neighboring cells.
Reference:
The following sql query pull the area code that differs by datetime minus 5 minutes and places it into a seperate table INCONSISTENT_AREA_CODE.
-
lonely_cell_id
()[source]¶ Lonesome LAC.
A cell is the only cell observed in its location area.
Rationale:
A mobile will only perform a normal location update when changing to a different area, i.e. a base station with a different LAC. An IMSI catcher needs to force a location update to be able to interact with the phone and derive the desired information. Therefore, it must span a cell with a LAC different to all neighboring cells, but with a much better signal strength than the other cells. An IMSI catcher creating a new LAC for its fake cell will be the only cell operating in this location area. The lack of system information for other cells of this location area can be detected.False Positives:
When traveling at high speeds or in areas with poor coverage the mobile may record system information for only a single cell of location area.
“Unexpected neighbors also do happen often with subway cells. In some cases the BTS is in a central place, and the RF heads are far away, connected with optical fiber. In these cases cell IDs and LACs are carried over many kilometers into places where they usually do not belong, and often not all neighbors are set correctly, due to restrictions in neighbor list size. I can imagine that such circumstances could trigger a false positive.”
Example
A simple example would be a group or two of cells sharing a LAC and another LAC detected with only a single CID belonging to it.
- LAC 1 contains CIDs: 1, 2, 3
- LAC 2 contains CIDs: 4, 5, 6, 6, 8
- LAC 3 contains CIDs: 9
Here LAC 3, containing only a single CID is suspicious.
Reference:
-
antikythera.pysharkpatch module¶
pysharkpatch.py
Patch the pyshark
class LayerFieldsContainer
using
inheritance to override its __new__
method so that it
is pickleable.