├── Ekoparty - Workshop Wardriving 2017.pdf ├── README.md ├── import_dns_pcap.py ├── import_wardriving_pcap.py └── import_wigle.py /Ekoparty - Workshop Wardriving 2017.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infobyte/wardriving/5b1cb8bda931844503649a765b140a5210498f39/Ekoparty - Workshop Wardriving 2017.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wardriving 2 | 3 | Here you can find all the data about the Wardriving Workshop from [Ekoparty 2017](http://ekoparty.org). 4 | 5 | ## Faraday Plugins 6 | 7 | The files starting with `import_` are all modules to be used with the Faraday Plugin. In order to run them, download and copy to you `{faraday_installation}/bin/`. 8 | 9 | For more info on the Faraday Plugin read the [official documentation](https://github.com/infobyte/faraday/wiki/Faraday-Plugin). 10 | 11 | ### import_dns_pcap.py 12 | 13 | The file import_dns_pcap.py will read all packets saved from Open WiFi networks. It will create vulnerabilities for non-encrypted cookies or authorization data. To run: 14 | 15 | ``` 16 | ./fplugin import_dns_pcap wardriving.cap -w eko_wardriving 17 | ``` 18 | 19 | ### import_wigle.py 20 | 21 | The file import_wigle.py will create a vulnerability with Informational severity and attach a map as evidence. This plugin uses the Android SQLite database as input. 22 | 23 | To run first copy the .sqlite in your smartphone to your computer. Then import .sqlite to eko_wardiring using the command: 24 | 25 | ``` 26 | ./fplugin import_wigle /home/lcubo/wigle/wiglewifi.sqlite -w eko_wardriving 27 | ``` 28 | 29 | ### import_wardriving_pcap.py 30 | 31 | The file import_wardriving_pcap.py creates objects in Faraday according to the security settings of the networks found in a PCAP. 32 | 33 | Users will be able to see statistics in the Faraday Dashboard including how many networks are using wpa, wpa2, wep and open. It will create vulnerabilities for open and wep. If any of the PCAP files contain a 4way handshake it will also create a vuln with the keys as evidence. 34 | 35 | Also, a vulnerability containing the top 10 probe requests found and an XLS file with the vendor frequency will be added. 36 | 37 | If you want to load wardriving statistics from a PCAP file to the eko_wardring workspace use the following command: 38 | 39 | ``` 40 | ./fplugin import_wardriving_pcap wardriving.cap -w eko_wardriving 41 | ``` 42 | -------------------------------------------------------------------------------- /import_dns_pcap.py: -------------------------------------------------------------------------------- 1 | import os 2 | from model.common import factory 3 | from persistence.server import models 4 | from scapy.all import DNSRR 5 | 6 | 7 | def get_domain_resolutions(cap): 8 | for packet in cap: 9 | if packet.haslayer(DNSRR): 10 | layer = packet.getlayer(DNSRR) 11 | while True: 12 | layer = layer.payload 13 | if not isinstance(layer, DNSRR): 14 | break 15 | if layer.type != 1: # A 16 | continue 17 | domain = layer.rrname 18 | if domain.endswith('.'): 19 | # remove trailing dot 20 | domain = domain[:-1] 21 | yield (domain, layer.rdata) 22 | 23 | def main(workspace='', args=None, parser=None): 24 | 25 | parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output from the pcapfile library.') 26 | parser.add_argument('pcap', help='Path to the PCAP file'), 27 | 28 | parsed_args = parser.parse_args(args) 29 | 30 | try: 31 | from scapy.all import PcapReader 32 | except ImportError: 33 | print 'capfile not found, please install it to use this plugin.' \ 34 | ' You can do install it by executing pip2 install scapy in a shell.' 35 | return 1, None 36 | 37 | if not os.path.isfile(parsed_args.pcap): 38 | print "pcap file not found: " % parsed_args.pcap 39 | return 2, None 40 | 41 | pcap = PcapReader(parsed_args.pcap) 42 | for (domain, ip) in get_domain_resolutions(pcap): 43 | obj = factory.createModelObject(models.Host.class_signature, ip, 44 | workspace, parent_id=None) 45 | 46 | old = models.get_host(workspace, obj.getID()) 47 | if old is None: 48 | models.create_host(workspace, obj) 49 | 50 | interface = factory.createModelObject( 51 | models.Interface.class_signature, 52 | '', 53 | workspace, 54 | # mac=bssid, 55 | ipv4_address=ip, 56 | ipv4_gateway='', 57 | ipv4_mask='', 58 | ipv4_dns='', 59 | ipv6_address='', 60 | ipv6_gateway='', 61 | ipv6_prefix='', 62 | ipv6_dns='', 63 | network_segment='', 64 | hostnames=[domain], 65 | parent_id=obj.getID()) 66 | old = models.get_interface(workspace, obj.getID()) 67 | if old is None: 68 | try: 69 | models.create_interface(workspace, interface) 70 | except: 71 | pass 72 | 73 | return 0, None 74 | -------------------------------------------------------------------------------- /import_wardriving_pcap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Faraday Penetration Test IDE 6 | Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) 7 | See the file 'doc/LICENSE' for the license information 8 | """ 9 | 10 | import os 11 | import time 12 | from base64 import b64encode 13 | from tempfile import NamedTemporaryFile 14 | from collections import defaultdict 15 | 16 | from scapy.all import ( 17 | Dot11, 18 | Dot11Elt, 19 | Dot11Beacon, 20 | EAP, 21 | 22 | ) 23 | from scapy.contrib.wpa_eapol import WPA_key 24 | from scapy.layers.dot11 import Dot11 25 | 26 | from persistence.server import models 27 | from persistence.server.server_io_exceptions import ConflictInDatabase, CantCommunicateWithServerError, ResourceDoesNotExist 28 | from model.common import factory 29 | 30 | factory.register(models.Host) 31 | factory.register(models.Vuln) 32 | factory.register(models.Service) 33 | factory.register(models.Interface) 34 | 35 | __description__ = 'Import every AP found in a PCAP file' 36 | __prettyname__ = 'Import Wardriving PCAP' 37 | 38 | access_point_data = defaultdict(dict) 39 | created_objs = defaultdict(set) 40 | 41 | 42 | def save_objs(workspace_name): 43 | """ 44 | This function uses a set to avoid hitting too much couchdb. 45 | Wifi packets usually are repeated, for example for beacons. 46 | :param workspace_name: 47 | :return: 48 | """ 49 | order = ['Host', 'Interface', 'Service', 'Vulnerability'] 50 | saved_ids = set() 51 | 52 | tmp = created_objs 53 | iterable = tmp.items() 54 | 55 | for type in order: 56 | for key, objs in iterable: 57 | if key == type: 58 | try: 59 | if key == 'Host': 60 | print('Total {0}: {1}'.format(key, len(objs))) 61 | for obj in objs: 62 | if obj.id in saved_ids: 63 | models.update_host(workspace_name, obj) 64 | else: 65 | models.create_host(workspace_name, obj) 66 | saved_ids.add(obj.id) 67 | if key == 'Service': 68 | print('Total {0}: {1}'.format(key, len(objs))) 69 | for obj in objs: 70 | if obj.id in saved_ids: 71 | models.update_service(workspace_name, obj) 72 | else: 73 | models.create_service(workspace_name, obj) 74 | saved_ids.add(obj.id) 75 | if key == 'Vulnerability': 76 | print('Total {0}: {1}'.format(key, len(objs))) 77 | for obj in objs: 78 | if obj.id in saved_ids: 79 | models.update_vuln(workspace_name, obj) 80 | else: 81 | models.create_vuln(workspace_name, obj) 82 | if key == 'Interface': 83 | print('Total {0}: {1}'.format(key, len(objs))) 84 | for obj in objs: 85 | if obj.id in saved_ids: 86 | models.update_interface(workspace_name, obj) 87 | else: 88 | models.create_interface(workspace_name, obj) 89 | saved_ids.add(obj.id) 90 | except ConflictInDatabase as e: 91 | print('Document already exists skipping.') 92 | print(e) 93 | continue 94 | except CantCommunicateWithServerError as e: 95 | print('error') 96 | print(e) 97 | except ResourceDoesNotExist as e: 98 | print('Missing DB {0}'.format(workspace_name)) 99 | print(e) 100 | continue 101 | except Exception as e: 102 | print(e) 103 | 104 | 105 | def extract_encryption(packet): 106 | elt = packet[Dot11Elt] 107 | while isinstance(elt, Dot11Elt): 108 | if elt.ID == 48: 109 | return 'wpa2' 110 | elif elt.ID == 221 and elt.info.startswith(b'\x00P\xf2\x01\x01\x00'): 111 | return 'wpa' 112 | elt = elt.payload 113 | capability = packet.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\ 114 | {Dot11ProbeResp:%Dot11ProbeResp.cap%}").strip() 115 | if 'privacy' in capability: 116 | return 'wep' 117 | else: 118 | return 'open' 119 | 120 | 121 | def process_wpa_key(workspace_name, packet): 122 | access_point = access_point_data[packet.addr3] 123 | if not access_point: 124 | return 125 | vuln = factory.createModelObject( 126 | models.Vuln.class_signature, 127 | 'WPA Key for {0} found'.format(access_point.get('essid', '')), 128 | workspace_name, 129 | severity='info', 130 | status='open', 131 | confirmed='true', 132 | desc='WPA was found for the access point. Ensure you are using a secure password.', 133 | parent_id=access_point['host'].id 134 | ) 135 | if vuln.id not in map(lambda vuln: vuln.id, created_objs['Vulnerability']): 136 | created_objs['Vulnerability'].add(vuln) 137 | 138 | 139 | def process_beacon(workspace_name, packet): 140 | dot11_packet = packet[Dot11] 141 | essid = packet.info 142 | bssid = dot11_packet.addr3 143 | encryption = extract_encryption(packet) 144 | access_point = access_point_data[bssid] 145 | if not essid: 146 | essid = 'Hidden' 147 | access_point['essid'] = essid 148 | access_point['bssid'] = bssid 149 | access_point['encryption'] = encryption 150 | create_host_interface_and_vuln(workspace_name, access_point) 151 | 152 | 153 | def create_host_interface_and_vuln(workspace_name, access_point): 154 | bssid = access_point['bssid'] 155 | try: 156 | essid = access_point['essid'].encode('utf8') 157 | except Exception: 158 | return 159 | encryption = access_point['encryption'] 160 | host = factory.createModelObject( 161 | models.Host.class_signature, 162 | essid, 163 | workspace_name=workspace_name, 164 | os=encryption, 165 | mac=bssid, 166 | parent_id=None) 167 | access_point['host'] = host 168 | if host.id not in map(lambda host: host.id, created_objs['Host']): 169 | created_objs['Host'].add(host) 170 | 171 | interface = factory.createModelObject( 172 | models.Interface.class_signature, 173 | '', 174 | workspace_name, 175 | mac=bssid, 176 | ipv4_address='', 177 | ipv4_gateway='', 178 | ipv4_mask='', 179 | ipv4_dns='', 180 | ipv6_address='', 181 | ipv6_gateway='', 182 | ipv6_prefix='', 183 | ipv6_dns='', 184 | network_segment='', 185 | parent_id=host.id) 186 | 187 | if interface.id not in map(lambda interface: interface.id, created_objs['Interface']): 188 | created_objs['Interface'].add(interface) 189 | access_point['interface'] = interface 190 | 191 | service = factory.createModelObject( 192 | models.Service.class_signature, 193 | encryption, 194 | workspace_name, 195 | protocol='802.11', 196 | status='open', 197 | description='Access point encryption', 198 | ports=[0], 199 | version='', 200 | service='open', 201 | parent_id=interface.id 202 | ) 203 | if service.id not in map(lambda service: service.id, created_objs['Service']): 204 | created_objs['Service'].add(service) 205 | 206 | if encryption in ['open', 'wep']: 207 | vuln = factory.createModelObject( 208 | models.Vuln.class_signature, 209 | 'Insecure WiFi {0} found'.format(essid), 210 | workspace_name, 211 | severity='critical', 212 | confirmed='true', 213 | status='open', 214 | desc='WiFi using {0} was found. Please change your router configuration.'.format(encryption), 215 | parent_id=host.id 216 | ) 217 | if vuln.id not in map(lambda vuln: vuln.id, created_objs['Vulnerability']): 218 | created_objs['Vulnerability'].add(vuln) 219 | 220 | 221 | def parse_wifi_pcaps(workspace_name, wifi_packets): 222 | for packet in wifi_packets: 223 | if packet.haslayer(Dot11): 224 | if packet.haslayer(Dot11Beacon): 225 | process_beacon(workspace_name, packet) 226 | if packet.haslayer(WPA_key): 227 | process_wpa_key(workspace_name, packet) 228 | 229 | return 0, None 230 | 231 | 232 | def main(workspace='', args=None, parser=None): 233 | 234 | parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID') 235 | parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output from the pcapfile library.') 236 | parser.add_argument('pcap', help='Path to the PCAP file'), 237 | parsed_args = parser.parse_args(args) 238 | 239 | try: 240 | from scapy.all import PcapReader 241 | except ImportError: 242 | print('capfile not found, please install it to use this plugin.' \ 243 | ' You can do install it by executing pip2 install scapy in a shell.') 244 | return 1, None 245 | 246 | if not os.path.isfile(parsed_args.pcap): 247 | print("pcap file not found: " % parsed_args.pcap) 248 | return 2, None 249 | 250 | wifi_pcaps = PcapReader(parsed_args.pcap) 251 | parse_wifi_pcaps(workspace, wifi_pcaps) 252 | 253 | if not parsed_args.dry_run: 254 | save_objs(workspace) 255 | 256 | return 0, None -------------------------------------------------------------------------------- /import_wigle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Faraday Penetration Test IDE 6 | Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) 7 | See the file 'doc/LICENSE' for the license information 8 | """ 9 | 10 | import os 11 | import time 12 | from base64 import b64encode 13 | from tempfile import NamedTemporaryFile 14 | from collections import defaultdict 15 | 16 | try: 17 | from staticmap import StaticMap, CircleMarker 18 | except ImportError: 19 | print('Please install staticmap with: pip install staticmap') 20 | 21 | 22 | from persistence.server import models 23 | from persistence.server.server import _save_to_couch 24 | from persistence.server.server_io_exceptions import ConflictInDatabase, CantCommunicateWithServerError, ResourceDoesNotExist 25 | from model.common import factory 26 | from math import radians, cos, sin, asin, sqrt 27 | 28 | 29 | factory.register(models.Host) 30 | factory.register(models.Vuln) 31 | factory.register(models.Service) 32 | factory.register(models.Interface) 33 | 34 | __description__ = 'Import every AP found in a PCAP file' 35 | __prettyname__ = 'Import Wardriving PCAP' 36 | 37 | access_point_data = defaultdict(dict) 38 | created_objs = defaultdict(set) 39 | 40 | 41 | def haversine(lon1, lat1, lon2, lat2): 42 | """ 43 | Calculate the great circle distance between two points 44 | on the earth (specified in decimal degrees) 45 | """ 46 | # convert decimal degrees to radians 47 | lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) 48 | 49 | # haversine formula 50 | dlon = lon2 - lon1 51 | dlat = lat2 - lat1 52 | try: 53 | a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 54 | except ValueError: 55 | return 9999 56 | c = 2 * asin(sqrt(a)) 57 | r = 6371 # Radius of earth in kilometers. Use 3956 for miles 58 | return c * r 59 | 60 | 61 | def save_objs(workspace_name): 62 | """ 63 | This function uses a set to avoid hitting too much couchdb. 64 | Wifi packets usually are repeated, for example for beacons. 65 | :param workspace_name: 66 | :return: 67 | """ 68 | order = ['Host', 'Interface', 'Service', 'Vulnerability'] 69 | saved_ids = set() 70 | 71 | tmp = created_objs 72 | iterable = tmp.items() 73 | 74 | for type in order: 75 | for key, objs in iterable: 76 | if key == type: 77 | try: 78 | if key == 'Host': 79 | print('Total {0}: {1}'.format(key, len(objs))) 80 | for obj in objs: 81 | if obj.id in saved_ids: 82 | models.update_host(workspace_name, obj) 83 | else: 84 | models.create_host(workspace_name, obj) 85 | saved_ids.add(obj.id) 86 | if key == 'Service': 87 | print('Total {0}: {1}'.format(key, len(objs))) 88 | for obj in objs: 89 | if obj.id in saved_ids: 90 | models.update_service(workspace_name, obj) 91 | else: 92 | models.create_service(workspace_name, obj) 93 | saved_ids.add(obj.id) 94 | if key == 'Vulnerability': 95 | print('Total {0}: {1}'.format(key, len(objs))) 96 | for obj in objs: 97 | if obj.id in saved_ids: 98 | models.update_vuln(workspace_name, obj) 99 | else: 100 | models.create_vuln(workspace_name, obj) 101 | if key == 'Interface': 102 | print('Total {0}: {1}'.format(key, len(objs))) 103 | for obj in objs: 104 | if obj.id in saved_ids: 105 | models.update_interface(workspace_name, obj) 106 | else: 107 | models.create_interface(workspace_name, obj) 108 | saved_ids.add(obj.id) 109 | except ConflictInDatabase as e: 110 | print('Document already exists skipping.') 111 | print(e) 112 | continue 113 | except CantCommunicateWithServerError as e: 114 | print('error') 115 | print(e) 116 | except ResourceDoesNotExist as e: 117 | print('Missing DB {0}'.format(workspace_name)) 118 | print(e) 119 | continue 120 | except Exception as e: 121 | print(e) 122 | 123 | 124 | def draw_map(): 125 | m = StaticMap(4000, 4000) 126 | for key, access_point in access_point_data.items(): 127 | if not ('lat' in access_point and 'lng' in access_point): 128 | continue 129 | coords = (access_point['lat'], access_point['lng']) 130 | if access_point['lng'] - -34.611944444444 > 0.1: 131 | continue 132 | if access_point['lat'] - -58.364722222222 > 0.1: 133 | continue 134 | 135 | colors = { 136 | 'open': 'red', 137 | 'wep': 'red', 138 | 'wpa': 'yellow', 139 | 'wpa2': 'green' 140 | } 141 | marker_outline = CircleMarker(coords, colors[access_point['encryption']], 18) 142 | marker = CircleMarker(coords, colors[access_point['encryption']], 12) 143 | 144 | m.add_marker(marker_outline) 145 | m.add_marker(marker) 146 | 147 | image = m.render(zoom=15) 148 | temp_file = NamedTemporaryFile(suffix='.png') 149 | image.save(temp_file.name) 150 | image.save('/home/lcubo/test1.png') 151 | return temp_file 152 | 153 | 154 | def create_host_interface_and_vuln(workspace_name, access_point): 155 | bssid = access_point['bssid'] 156 | try: 157 | essid = access_point['essid'].encode('utf8') 158 | except Exception: 159 | return 160 | encryption = access_point['encryption'] 161 | host = factory.createModelObject( 162 | models.Host.class_signature, 163 | essid, 164 | workspace_name=workspace_name, 165 | os=encryption, 166 | mac=bssid, 167 | parent_id=None) 168 | access_point['host'] = host 169 | if host.id not in map(lambda host: host.id, created_objs['Host']): 170 | created_objs['Host'].add(host) 171 | 172 | interface = factory.createModelObject( 173 | models.Interface.class_signature, 174 | '', 175 | workspace_name, 176 | mac=bssid, 177 | ipv4_address='', 178 | ipv4_gateway='', 179 | ipv4_mask='', 180 | ipv4_dns='', 181 | ipv6_address='', 182 | ipv6_gateway='', 183 | ipv6_prefix='', 184 | ipv6_dns='', 185 | network_segment='', 186 | parent_id=host.id) 187 | 188 | if interface.id not in map(lambda interface: interface.id, created_objs['Interface']): 189 | created_objs['Interface'].add(interface) 190 | access_point['interface'] = interface 191 | 192 | service = factory.createModelObject( 193 | models.Service.class_signature, 194 | encryption, 195 | workspace_name, 196 | protocol='802.11', 197 | status='open', 198 | description='Access point encryption', 199 | ports=[0], 200 | version='', 201 | service='open', 202 | parent_id=interface.id 203 | ) 204 | if service.id not in map(lambda service: service.id, created_objs['Service']): 205 | created_objs['Service'].add(service) 206 | 207 | if encryption in ['open', 'wep']: 208 | vuln = factory.createModelObject( 209 | models.Vuln.class_signature, 210 | 'Insecure WiFi {0} found'.format(essid), 211 | workspace_name, 212 | severity='critical', 213 | confirmed='true', 214 | status='open', 215 | desc='WiFi using {0} was found. Please change your router configuration.'.format(encryption), 216 | parent_id=host.id 217 | ) 218 | if vuln.id not in map(lambda vuln: vuln.id, created_objs['Vulnerability']): 219 | created_objs['Vulnerability'].add(vuln) 220 | 221 | 222 | def process_wigle_sqlite(workspace_name, wigle_filename): 223 | try: 224 | import sqlite3 225 | except ImportError: 226 | print('For using wigle import, sqlite3 is required. Please install it with: pip install sqlite3') 227 | conn = sqlite3.connect(wigle_filename) 228 | cursor = conn.execute('SELECT bssid, ssid, capabilities, bestlat, bestlon from network') 229 | for network in cursor: 230 | bssid = network[0] 231 | essid = network[1] 232 | capability = network[2].lower() 233 | lat = network[4] 234 | lng = network[3] 235 | access_point = access_point_data[bssid] 236 | if 'wpa' in capability and 'wpa2' not in capability: 237 | encryption = 'wpa' 238 | if 'wpa2' in capability: 239 | encryption = 'wpa2' 240 | if 'wep' in capability: 241 | encryption = 'wep' 242 | if 'open' in capability: 243 | encryption = 'open' 244 | 245 | access_point['essid'] = essid 246 | access_point['bssid'] = bssid 247 | access_point['encryption'] = encryption 248 | access_point['lat'] = lat 249 | access_point['lng'] = lng 250 | create_host_interface_and_vuln(workspace_name, access_point) 251 | map_file = draw_map() 252 | map_file.seek(0) 253 | now_timestamp = time.time() 254 | 255 | host = factory.createModelObject( 256 | models.Host.class_signature, 257 | 'War driving results', 258 | workspace_name=workspace_name, 259 | parent_id=None) 260 | 261 | interface = factory.createModelObject( 262 | models.Interface.class_signature, 263 | '', 264 | workspace_name, 265 | mac=bssid, 266 | ipv4_address='', 267 | ipv4_gateway='', 268 | ipv4_mask='', 269 | ipv4_dns='', 270 | ipv6_address='', 271 | ipv6_gateway='', 272 | ipv6_prefix='', 273 | ipv6_dns='', 274 | network_segment='', 275 | parent_id=host.id) 276 | 277 | service = factory.createModelObject( 278 | models.Service.class_signature, 279 | encryption, 280 | workspace_name, 281 | protocol='802.11', 282 | status='open', 283 | description='Access point encryption', 284 | ports=[0], 285 | version='', 286 | service='open', 287 | parent_id=interface.id 288 | ) 289 | try: 290 | models.create_host(workspace_name, host) 291 | except ConflictInDatabase: 292 | pass 293 | try: 294 | models.create_interface(workspace_name, interface) 295 | except ConflictInDatabase: 296 | pass 297 | try: 298 | models.create_service(workspace_name, service) 299 | except ConflictInDatabase: 300 | pass 301 | 302 | name = 'Wardriving Map' 303 | description = 'See evidence for war driving map.' 304 | parent_id = host.id 305 | 306 | raw_obj = { 307 | "metadata": {"update_time": now_timestamp, "update_user": "", "update_action": 0, "creator": "UI Web", 308 | "create_time": now_timestamp, "update_controller_action": "UI Web New", "owner": ""}, 309 | "obj_id": "0c41d85f6dc71044518eea211bfbd12f2bad6f73", "owner": "", 310 | "parent": parent_id, "type": "Vulnerability", "ws": "wifi", "confirmed": True, 311 | "data": "", "desc": description, "easeofresolution": "", 312 | "impact": {"accountability": False, "availability": False, "confidentiality": False, "integrity": False}, 313 | "name": name, "owned": False, "policyviolations": [], "refs": [], "resolution": "", "severity": "info", 314 | "status": "opened", 315 | "_attachments": { 316 | "map.png": { 317 | "content_type": "image/png", 318 | "data": b64encode(map_file.read())}}, 319 | "protocol": "", "version": ""} 320 | obj = models.ModelBase(raw_obj, workspace_name) 321 | obj.setID(parent_id, name, description) 322 | vuln_id = obj.id 323 | raw_obj.update({"_id": vuln_id}) 324 | try: 325 | _save_to_couch(workspace_name, vuln_id, **raw_obj) 326 | except ConflictInDatabase: 327 | pass 328 | map_file.close() 329 | 330 | 331 | def main(workspace='', args=None, parser=None): 332 | 333 | parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID') 334 | parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output from the pcapfile library.') 335 | parser.add_argument('wigle_sqlite', help='Wigle sqlite for gps coordinates'), 336 | 337 | parsed_args = parser.parse_args(args) 338 | 339 | if not os.path.isfile(parsed_args.wigle_sqlite): 340 | print("wigle sqlite file not found: %s" % parsed_args.wigle_sqlite) 341 | return 2, None 342 | 343 | process_wigle_sqlite(workspace, parsed_args.wigle_sqlite) 344 | 345 | if not parsed_args.dry_run: 346 | save_objs(workspace) 347 | 348 | return 0, None --------------------------------------------------------------------------------