Mentions légales du service

Skip to content
Snippets Groups Projects
Commit f16b3aef authored by MOLANO ORTIZ Fernando's avatar MOLANO ORTIZ Fernando
Browse files

Update 13 files

- /ansible/tasks/playbook_GPS_sync
- /ansible/tasks/playbook_hostname
- /ansible/tasks/playbook_hosts
- /ansible/tasks/playbook_NIC_config
- /ansible/tasks/playbook_SSH_keygen
- /ansible/tasks/playbook_scapy-sniffer
- /ansible/tasks/playbook_GPS_sync.yml
- /ansible/tasks/playbook_hostname.yml
- /ansible/tasks/playbook_hosts.yml
- /ansible/tasks/playbook_NIC_config.yml
- /ansible/tasks/playbook_SSH_keygen.yml
- /ansible/tasks/playbook_scapy-sniffer_GPS.yml
- /utils/sniffer_GPS.py
parent c81e4147
No related branches found
No related tags found
No related merge requests found
...@@ -19,17 +19,9 @@ ...@@ -19,17 +19,9 @@
- name: pps-tools installation - name: pps-tools installation
command: sudo apt install pps-tools -y command: sudo apt install pps-tools -y
#- name: python-gps installation
# command: sudo apt install python-gps -y
- name: systemctl enable gpsd - name: systemctl enable gpsd
command: sudo systemctl enable gpsd.socket command: sudo systemctl enable gpsd.socket
#- name: Copy a new config gpsd device functionality
# copy:
# src: /home/pi/ansible/config.txt
# dest: /boot/config.txt
- name: Copy a new config gpsd device functionality - name: Copy a new config gpsd device functionality
blockinfile: | blockinfile: |
dest=/boot/config.txt dest=/boot/config.txt
...@@ -61,7 +53,6 @@ ...@@ -61,7 +53,6 @@
- name: ntp uninstall - name: ntp uninstall
command: sudo apt remove ntp -y command: sudo apt remove ntp -y
- name: chrony installation - name: chrony installation
command: sudo apt install chrony -y command: sudo apt install chrony -y
......
- name: host file update - Local DNS setup across all the servers - name: host file update - Local DNS setup across all the servers
hosts: sniffers hosts: sniffers
gather_facts: yes gather_facts: yes
#become: yes
#become_user: root
#become_exe: sudo su -
tasks: tasks:
- name: Update the /etc/hosts file with node name - name: Update the /etc/hosts file with node name
...@@ -14,9 +11,7 @@ ...@@ -14,9 +11,7 @@
dest: "/etc/hosts" dest: "/etc/hosts"
regexp: ".*\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" regexp: ".*\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}"
line: "{{ hostvars[item]['ansible_default_ipv4']['address'] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}" line: "{{ hostvars[item]['ansible_default_ipv4']['address'] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}"
#line: "{{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}"
state: present state: present
#backup: yes
register: etchostsupdate register: etchostsupdate
when: when:
ansible_hostname != "item" or ansible_hostname == "item" ansible_hostname != "item" or ansible_hostname == "item"
......
- hosts: sniffers - hosts: sniffers
ignore_unreachable: true user: gta
#become: yes
#become_user: root
vars: vars_prompt:
cap_file: packet_capture_{{ansible_hostname}}_{{ ansible_date_time['epoch'] }}.pcap
- name: _file
prompt: Enter the folder name to save traces in the sniffer
private: no
vars_prompt: - name: _location
prompt: Enter the location of the experiments
private: no
- name: _hour - name: _hour
prompt: Enter an hour to start the experiment prompt: Enter an hour to start the experiment
...@@ -31,7 +37,7 @@ ...@@ -31,7 +37,7 @@
- name: _channel - name: _channel
prompt: Please specify the channel (integer between 1-11, default=system). For default just press enter prompt: Please specify the channel (integer between 1-11, default=system). For default just press enter
default: '' default: 1
private: no private: no
- name: _hash_function - name: _hash_function
...@@ -44,23 +50,20 @@ ...@@ -44,23 +50,20 @@
default: 15 default: 15
private: no private: no
- name: dest_folder tasks:
prompt: Please specify the destination folder (location on remote server e.g. /var/tmp/)
private: no
#- name: filter
# prompt: Please specify the tcpdump filter (e.g. host 10.10.10.10). For no filter just press enter
# default: ""
# private: no
- name: Create Folder
file:
path: "{{ _file }}"
owner: gta
group: gta
#mode: 0755
state: directory
tasks:
- name: start scapy-sniffer - name: start scapy-sniffer
cron: cron:
name: "ansible_scapy-sniffer" name: "ansible_scapy-sniffer {{ _hour }} {{ _minute }} {{ _channel }}"
#state: present
minute: "{{ _minute }}" minute: "{{ _minute }}"
hour: "{{ _hour }}" hour: "{{ _hour }}"
job: "sudo python3 sniffers/scapy-sniffer/sniffer.py -i {{ _interface }} -c {{ _channel }} -e {{ _hash_function}} -p {{ _hash_pattern }} -t {{ _timeout }} -w {{ dest_folder}}/{{ cap_file }}" job: "sudo python3 /home/gta/sniffers/scapy-sniffer/sniffer_GPS.py -F {{ _file }} -L {{ _location }} -i {{ _interface }} -c {{ _channel }} -f {{ _filter }} -e {{ _hash_function}} -p {{ _hash_pattern }} -t {{ _timeout }}"
#user: root \ No newline at end of file
#become: true
#!/usr/bin/env python3
#
# sniffer.py
#
# Description:
# Passive wi-fi sniffer using scapy library. Usage requires interface in Monitor mode and root permissions.
# To see options type './sniffer -h' or './sniffer.py --help'
import sys
import logging
from datetime import datetime
import argparse
import hashlib
from pathlib import Path
import Utils
import platform
# Libraries GPS
#import serial
import time
import string
#import pynmea2
from gps import *
import inspect
# Libraries Scapy
import scapy.all as scapy
dev_name = platform.node()
# GPS variables
GPS_lat = ['NO_GPS']
GPS_lon = ['NO_GPS']
gpsd=gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
# GPS function
def GPS_coords():
while True:
report=gpsd.next()
if report['class']=='TPV':
lat=str(getattr(report,'lat',0.0))
lon=str(getattr(report,'lon',0.0))
return lat,lon
# Encryption functions
# Functions that define possible encryption operations with the source address
def MD5Hash(data):
return hashlib.md5(data).hexdigest()[:12] if not data is None else None
def SHA256Hash(data):
return hashlib.sha256(data).hexdigest()[:12] if not data is None else None
# Function handler for each captured packet
def PacketHandler(packet):
global hashPattern, HashFunction, logger, pcapWriter#, stopCapture
global fieldControlMAC1, fieldControlMAC2, fieldControlMAC3, fieldControlSSID
srcMac = packet.addr2
srcSSID = packet[3].info
# Writes the hash result received in python to a format that directly relates to the MAC address ouput
# Output MAC address is weird when set as bytes, must convert to string format prior to assignment
# The same does not happen to the SSID
if HashFunction:
if (hashPattern & fieldControlMAC1) and packet.addr1 and packet.addr1 != "ff:ff:ff:ff:ff:ff":
packet.addr1 = str(HashFunction(packet.addr1.encode('utf-8')))
packet.addr1 = packet.addr1[0:] + ":" +packet.addr1[2:4] + ":" +packet.addr1[4:6] + ":" +packet.addr1[6:8] + ":" +packet.addr1[8:10] + ":" +packet.addr1[10:]
if (hashPattern & fieldControlMAC2) and packet.addr2 and packet.addr2 != "ff:ff:ff:ff:ff:ff":
packet.addr2 = str(HashFunction(packet.addr2.encode('utf-8')))
packet.addr2 = packet.addr2[0:] + ":" +packet.addr2[2:4] + ":" +packet.addr2[4:6] + ":" +packet.addr2[6:8] + ":" +packet.addr2[8:10] + ":" +packet.addr2[10:]
if (hashPattern & fieldControlMAC3) and packet.addr3 and packet.addr3 != "ff:ff:ff:ff:ff:ff":
packet.addr3 = str(HashFunction(packet.addr3.encode('utf-8')))
packet.addr3 = packet.addr3[0:] + ":" +packet.addr3[2:4] + ":" +packet.addr3[4:6] + ":" +packet.addr3[6:8] + ":" +packet.addr3[8:10] + ":" +packet.addr3[10:]
# Hashes SSID
if (hashPattern & fieldControlSSID):
packet[3].info = HashFunction(packet[3].info) # Gets to the SSID Value
packet[3].len = len(packet[3].info)
pcapWriter.write(packet)
# Global variables
#stopCapture = False # Variable that stores the signal state
logger = None # Stores the logger object
availableHashFunctions = ['None','MD5','SHA256']
hashFunctions = [None,MD5Hash,SHA256Hash]
hashPattern = 15
time_out = None # Variable to define stop sniffing after a given time
# Field control for hashing
fieldControlMAC1 = 8
fieldControlMAC2 = 4
fieldControlMAC3 = 2
fieldControlSSID = 1
#
GPS_parsed = GPS_coords()
GPS_lat=GPS_parsed[0]
GPS_lon=GPS_parsed[1]
def int_range(mini,maxi):
"""Return function handle of an argument type function for
ArgumentParser checking an integer range: mini <= arg <= maxi
mini - minimum acceptable argument
maxi - maximum acceptable argument"""
# Define the function with default arguments
def int_range_checker(arg):
"""New Type function for argparse - a float within predefined range."""
try:
f = int(arg)
except ValueError:
raise argparse.ArgumentTypeError("must be a floating point number")
if f < mini or f > maxi:
raise argparse.ArgumentTypeError("must be in range [" + str(mini) + ", " + str(maxi)+"]")
return f
return int_range_checker
if __name__ == "__main__":
# Argument parser
parser = argparse.ArgumentParser(description="Passive wi-fi sniffer for the MAC Anonymization project. More info at README.md")
# Options for sniffer
parser.add_argument("-L","--location",type=str,default=None,help="Defines the location of experiments.")
parser.add_argument("-i","--interface",type=str,default='wlan1',help="Chooses interface to listen to. Wireless interface must be on Monitor mode.")
parser.add_argument("-f","--filter",type=str,default='type mgt and (subtype probe-req or subtype probe-resp or subtype beacon)',help="Chooses filter to apply to packet capture. This is a string that follows the tcpdump conventions.")
parser.add_argument("-F","--folder",type=str,default=None,help="Folder to save traces in the remote nodes")
parser.add_argument('-v','--verbose',action='count',default=0,help='Increase verbosity level.')
parser.add_argument('-e','--hash-function',choices=availableHashFunctions,default='MD5',help="Chooses the desired function for hashing the MAC addresses (or no hash at all)")
parser.add_argument('-c','--channel',default=None,type=int,help="Set specific channel for capture (Default behaviour is not to change the current one)")
parser.add_argument("-o","--offline",default=None,type=Path,help="Reads from a pcap file instead of actually sniffing")
parser.add_argument('-m',"--memory",action="store_true",help="Writes pcap file into /dev/shm when capturing and moves from there to the default location when exiting. See README for more info")
parser.add_argument("-l","--logs",action="store_true",help="Saves the debug logs on a file")
parser.add_argument('-p','--hash-pattern',type=int_range(0,15),default=15,help="Integer defining bitmask that enables the hashing of MAC1, MAC2, MAC3 and SSID respectively. It's a binary value in the format 0b<MAC1><MAC2><MAC3><SSID> where each can be 1 or 0. Can be written as its respective integer as well.")
parser.add_argument('-t','--timeout',default=None,type=int,help="Time for capture packets on the interface specificied")
logger = logging.getLogger('sniffer')
# Setting logs
# log instance
logger = logging.getLogger(name="ReplayFileCreator")
logger.setLevel(logging.DEBUG)
# Parses arguments
args = parser.parse_args(sys.argv[1:])
# Saves debug log to file
if args.logs:
fileHandler = logging.FileHandler(f".sniffer.log")
fileHandler.setFormatter(logging.Formatter("%(asctime)s - %(funcName)s (%(lineno)s) - [%(levelname)s]: %(message)s"))
fileHandler.setLevel(logging.DEBUG)
logger.addHandler(fileHandler)
# Prints with desired level
logHandler = logging.StreamHandler()
if args.verbose == 0:
logHandler.setLevel(logging.ERROR)
elif args.verbose == 1:
logHandler.setLevel(logging.WARNING)
elif args.verbose == 2:
logHandler.setLevel(logging.INFO)
else:
logHandler.setLevel(logging.DEBUG)
logHandler.setFormatter(logging.Formatter("%(asctime)s - [%(levelname)s]: %(message)s"))
logger.addHandler(logHandler)
# Arguments
verboseLevel = args.verbose
outputFile = f"{args.folder}/{dev_name}_{args.location}_tmsp{time.strftime('%Y%m%d-%H%M%S')}_lat{GPS_lat}_lon{GPS_lon}_ch{args.channel}.pcap"
sniffingFilter = args.filter # Defines a BPF filter to use with, defaults to only capture Probe requests, responses and beacons
listeningInterface = args.interface
HashFunction = hashFunctions[availableHashFunctions.index(args.hash_function)]
hashPattern = args.hash_pattern
time_out = args.timeout
#Sets verbosity level
if verboseLevel == 0:
logger.setLevel(logging.ERROR)
if verboseLevel == 1:
logger.setLevel(logging.WARNING)
if verboseLevel == 2:
logger.setLevel(logging.INFO)
if verboseLevel >= 3:
logger.setLevel(logging.DEBUG)
logger.info(f"Current working interfaces: {(cwIfaces := scapy.get_working_ifaces())}")
# Checks if interface name is valid
if not listeningInterface in cwIfaces:
logger.critical(f"No interface named '{listeningInterface}' was found ")
exit(1)
# Configures interface to be on monitor mode (no need if on offline mode)
if not args.offline:
try:
Utils.ConfigureInterface(listeningInterface)
if args.channel:
Utils.ChangeChannel(listeningInterface,args.channel)
except Exception as err:
logger.critical(f"Error when changing interface to monitor mode. ({err})")
exit(1)
# Creates an PcapWriter object
# If --memory was selected, saves file into /dev/shm/ before saving it to CWD
if args.memory:
tempFileLocation = "/dev/shm/" + outputFile + ".tmp"
pcapWriter = scapy.PcapWriter(open(tempFileLocation,'wb'), append=True, sync=True)
else:
pcapWriter = scapy.PcapWriter(open(outputFile,'wb'), append=True, sync=True)
# Starts sniffing process
logger.info(f"Started sniffing @ {listeningInterface} {datetime.now()} ")
# If to read from file, reads with no filters, closes and exits the process
if args.offline:
sniffed = scapy.sniff(offline=args.offline.open(mode="rb"),prn=PacketHandler)
pcapWriter.close()
logger.info("Read from file")
exit(0)
# If no offline option is given, proceeds to capture as normal
sniffed = scapy.sniff(filter=sniffingFilter,store=True,prn=PacketHandler,iface=listeningInterface,timeout=time_out)
logger.info(f"Written {len(sniffed)} captured packets")
# Closes file
pcapWriter.close()
# Copies content from shm to device
if args.memory:
with open(tempFileLocation,'rb') as filRead:
with open(outputFile,'wb') as filWrite:
filWrite.write(filRead.read())
logger.info("Success on exiting sniffer.")
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment