':''),d=this.__meta__=new JS.Module(c?c+'.':'',{},{_1:this});d.include(this.klass.__mod__,false);return d},equals:function(a){return this===a},extend:function(a,b){return this.__eigen__().include(a,b,{_2:this})},hash:function(){return this.__hashcode__=this.__hashcode__||JS.Kernel.getHashCode()},isA:function(a){return this.__eigen__().includes(a)},method:function(a){var b=this,c=b.__mcache__=b.__mcache__||{};if((c[a]||{}).fn===b[a])return c[a].bd;return(c[a]={fn:b[a],bd:JS.bind(b[a],b)}).bd},methods:function(){return this.__eigen__().instanceMethods(true)},tap:function(a,b){a.call(b||null,this);return this}}),{__hashIndex__:0,getHashCode:function(){this.__hashIndex__+=1;return(Math.floor(new Date().getTime()/1000)+this.__hashIndex__).toString(16)}});JS.Module.include(JS.Kernel);JS.extend(JS.Module,JS.Kernel.__fns__);JS.Class.include(JS.Kernel);JS.extend(JS.Class,JS.Kernel.__fns__);JS.Interface=new JS.Class({initialize:function(d){this.test=function(a,b){var c=d.length;while(c--){if(!JS.isFn(a[d[c]]))return b?d[c]:false}return true}},extend:{ensure:function(){var a=JS.array(arguments),b=a.shift(),c,d;while(c=a.shift()){d=c.test(b,true);if(d!==true)throw new Error('object does not implement '+d+'()');}}}});JS.Singleton=new JS.Class({initialize:function(a,b,c){return new(new JS.Class(a,b,c))}});
2 |
--------------------------------------------------------------------------------
/security_ssid/static/locate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GISDev01/security-ssid-abi/e8e9825a764322c8dfb021c1d4665c5b2d0d8662/security_ssid/static/locate.png
--------------------------------------------------------------------------------
/security_ssid/static/wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GISDev01/security-ssid-abi/e8e9825a764322c8dfb021c1d4665c5b2d0d8662/security_ssid/static/wifi.png
--------------------------------------------------------------------------------
/security_ssid/templates/ap_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
8 | {% endblock %}
9 |
10 | {% block content %}
11 | Clients probing for network {{ object|safe }} ({{ object.manufacturer }})
12 | {% if object.name %}
13 | Name: {{ object.name }}
14 |
{% endif %}
15 |
16 |
17 |
18 | MAC |
19 | Name |
20 |
21 |
22 | {% for c in Clients %}
23 |
24 | {{ c.mac }} |
25 | {{ c.name }} |
26 |
27 | {% endfor %}
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/security_ssid/templates/ap_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load dict_lookup %}
3 | {% load tz %}
4 |
5 | {% block head %}
6 |
10 | {% endblock %}
11 |
12 | {% block content %}
13 | {{ devicecount }} devices probing for {{ apcount }} networks detected
14 |
15 |
16 |
17 | SSID / BSSID |
18 | Probed for by |
19 | Last probed for |
20 |
21 |
22 | {% for ap in object_list %}
23 |
24 |
25 | {% url "network" ap.BSSID as bssidurl %}
26 | {% url "network" ap.SSID as ssidurl %}
27 |
28 | {% if ap.BSSID %}{{ ap.BSSID }}{% else %}{{ ap.SSID }}{% endif %}{% if ap.BSSID %} (
29 | {{ ap.manufacturer }}){% endif %}
30 | |
31 | {{ ap.client.all|length }} |
32 | {% for c in ap.client.all %}
33 | {% if forloop.counter < 6 %}{{ c.mac }}{% endif %}
34 | {% if forloop.counter == 6 %}...{% endif %}
35 | {% endfor %} |
36 | {% localtime on %}
37 | {{ ap.lastprobed_date }} |
38 | {% endlocaltime %}
39 |
40 | {% endfor %}
41 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/security_ssid/templates/apple-mobile-ajax.js:
--------------------------------------------------------------------------------
1 | {%
2 | load
3 | dict_lookup %
4 | }
5 | {%
6 | load
7 | dot_colour %
8 | }
9 |
10 | {%
11 | for b in bssids %}
12 | var myLatLng = new google.maps.LatLng
13 | {
14 | {
15 | apdict | key
16 | :
17 | b
18 | }
19 | }
20 | ;
21 | apData.push(myLatLng);
22 | var marker = new google.maps.Marker({
23 | position: myLatLng,
24 | map: map,
25 | title: '{{manufdict|key:b}}',
26 | icon: { %
27 | if b == bssid %
28 | }
29 | bigRedDot
30 | {%else%
31 | }
32 | {
33 | {
34 | manufdict | key
35 | :
36 | b | dot_colour
37 | }
38 | }
39 | {%
40 | endif %
41 | }
42 | })
43 | ;
44 | google.maps.event.addListener(marker, "click", function () {
45 | loadAjax("{{b}}")
46 | });
47 | markersArray.push(marker);
48 | {%
49 | endfor %
50 | }
51 |
52 | pointArray = new google.maps.MVCArray(apData);
53 |
54 | if (heatmap.getMap()) {
55 | heatmap.setMap(null);
56 | heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray});
57 | heatmap.setMap(map);
58 | }
59 |
60 | document.getElementById('bssid').innerHTML = 'Cell {{bssid}}';
61 | document.getElementById('results').innerHTML = markersArray.length + ' cells (' + {
62 | {
63 | hits
64 | }
65 | }
66 | +' added)';
--------------------------------------------------------------------------------
/security_ssid/templates/apple-mobile.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load dict_lookup %}
3 | {% load dot_colour %}
4 |
5 | {% block head %}
6 |
7 |
8 |
15 |
16 |
17 |
228 | {% endblock %}
229 |
230 | {% block content %}
231 |
232 |
Cell {{ bssid }}
233 |
234 |
237 |
238 |
{% if hits %}{{ hits }} cells shown.{% endif %}
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 | {% endblock %}
251 |
--------------------------------------------------------------------------------
/security_ssid/templates/apple-wloc-ajax.js:
--------------------------------------------------------------------------------
1 | {%
2 | load
3 | dict_lookup %
4 | }
5 |
6 | {%
7 | for b in bssids %}
8 | var myLatLng = new google.maps.LatLng
9 | {
10 | {
11 | apdict | key
12 | :
13 | b
14 | }
15 | }
16 | ;
17 | apData.push(myLatLng);
18 | var marker = new google.maps.Marker({
19 | position: myLatLng,
20 | map: map,
21 | title: '{{b}} - {{manufdict|key:b}}',
22 | icon: { %
23 | if b == bssid %
24 | }
25 | redDot
26 | {%else%
27 | }
28 | blueDot
29 | {%
30 | endif %
31 | }
32 | })
33 | ;
34 | google.maps.event.addListener(marker, "click", function () {
35 | loadAjax("{{b}}")
36 | });
37 | markersArray.push(marker);
38 | {%
39 | endfor %
40 | }
41 |
42 | pointArray = new google.maps.MVCArray(apData);
43 |
44 | if (heatmap.getMap()) {
45 | heatmap.setMap(null);
46 | heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray});
47 | heatmap.setMap(map);
48 | }
49 |
50 | document.getElementById('bssid').innerHTML = 'BSSID {{bssid}}';
51 | document.getElementById('results').innerHTML = markersArray.length + ' APs (' + {
52 | {
53 | hits
54 | }
55 | }
56 | +' added)';
--------------------------------------------------------------------------------
/security_ssid/templates/apple-wloc.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load dict_lookup %}
3 |
4 | {% block head %}
5 |
6 |
7 |
14 |
15 |
16 |
185 | {% endblock %}
186 |
187 | {% block content %}
188 |
189 |
BSSID {{ bssid }}
190 |
191 |
194 |
195 |
{% if hits %}{{ hits }} APs shown.{% endif %}
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 | {% endblock %}
210 |
--------------------------------------------------------------------------------
/security_ssid/templates/base.html:
--------------------------------------------------------------------------------
1 | {% load urldecode %}
2 |
3 |
4 |
5 | {% block title %}SSID ABI v2.0{% endblock %}
6 | {% block css %}
7 |
8 | {% endblock %}
9 | {% block head %}{% endblock %}
10 |
11 |
12 |
13 |
22 | {% block content %}{% endblock %}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/security_ssid/templates/client_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
8 | {% endblock %}
9 |
10 | {% block content %}
11 | Client {{ object.mac }} ({{ object.manufacturer }})
12 | {% if object.name %}
13 | Name: {{ object.name }}
14 |
{% endif %}
15 | Probed for:
16 | {% load tz %}
17 |
18 |
19 |
20 | SSID |
21 | BSSID |
22 | Lat |
23 | Lon |
24 | Comment |
25 | Last probe observed |
26 | Locate |
27 |
28 |
29 | {% for ap in APs %}
30 |
31 | {% if ap.SSID %}{{ ap.SSID }}{% endif %} |
32 | {% if ap.BSSID %}{{ ap.BSSID }}{% endif %} |
33 | {% if ap.lat %} {{ ap.lat }} {% endif %} |
34 | {% if ap.lon %} {{ ap.lon }} {% endif %} |
35 | {{ ap.comment }} |
36 | {% localtime on %}
37 | {{ ap.lastprobed_date }} |
38 | {% endlocaltime %}
39 |
40 |
41 | {% if ap.SSID %}{% endif %}
42 | {% if ap.BSSID %}{% endif %}
43 |
44 | |
45 |
46 | {% endfor %}
47 |
48 | {% endblock %}
49 |
--------------------------------------------------------------------------------
/security_ssid/templates/client_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load dict_lookup %}
3 |
4 | {% block head %}
5 |
9 | {% endblock %}
10 |
11 | {% block content %}
12 |
13 | {{ devicecount }} devices probing for {{ apcount }} networks detected (Client List)
14 |
15 |
16 |
17 | MAC | Name |
18 | Manufacturer |
19 | Probed for |
20 | Last detected |
21 |
22 |
23 | {% for client in object_list %}
24 |
25 | {{ client.mac }}{% if client.name %} {{ client.name }}{% endif %} |
26 | {{ client.manufacturer }} |
27 | {% for ap in probedict|key:client %}
28 | {{ ap.SSID|safe }}{% if probedict|key:client|length > 1 and forloop.last == False %};{% endif %}
29 | {% endfor %}
30 | |
31 | {{ client.lastseen_date }} |
32 |
33 | {% endfor %}
34 |
35 |
36 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/security_ssid/templates/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
8 | {% endblock %}
9 |
10 | {% block content %}
11 | Hi
12 | {% if devicecount %}Total: {{ devicecount }}
{% endif %}
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/security_ssid/templates/stats.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
5 |
6 |
32 | {% endblock %}
33 |
34 | {% block content %}
35 | Top 10 Device Manufacturers
36 | Total Devices: {{ devicecount }}
37 |
38 |
39 | {% endblock %}
40 |
--------------------------------------------------------------------------------
/security_ssid/templates/wigle-wloc.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load dict_lookup %}
3 |
4 | {% block head %}
5 |
6 |
7 |
14 |
15 |
16 |
52 | {% endblock %}
53 |
54 | {% block content %}
55 | SSID
56 |
57 |
59 | {% if hits %}{{ hits }} APs returned.{% endif %}
60 |
61 | {% endblock %}
62 |
--------------------------------------------------------------------------------
/security_ssid/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GISDev01/security-ssid-abi/e8e9825a764322c8dfb021c1d4665c5b2d0d8662/security_ssid/templatetags/__init__.py
--------------------------------------------------------------------------------
/security_ssid/templatetags/dict_lookup.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def key(d, key):
8 | return d[key]
9 |
--------------------------------------------------------------------------------
/security_ssid/templatetags/dot_colour.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | register = template.Library()
4 |
5 |
6 | @register.filter
7 | def dot_colour(operator):
8 | d = 'blue'
9 | if 'Optus' in operator:
10 | d = 'yellow'
11 | if 'Vodafone' in operator:
12 | d = 'red'
13 | if 'Three' in operator:
14 | d = 'red'
15 |
16 | if 'CID:-1' in operator:
17 | return d + 'LAC'
18 |
19 | return d + 'Cell'
20 |
--------------------------------------------------------------------------------
/security_ssid/templatetags/urldecode.py:
--------------------------------------------------------------------------------
1 | from urllib.parse import unquote
2 |
3 | from django import template
4 |
5 | register = template.Library()
6 |
7 |
8 | @register.filter
9 | def urldecode(value):
10 | return unquote(value)
11 |
--------------------------------------------------------------------------------
/security_ssid/urls.py:
--------------------------------------------------------------------------------
1 | """security_ssid URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.urls import re_path as url
17 | from django.contrib import admin
18 | from django.urls import path
19 |
20 | from .views import APDetail, APList, AppleMobile, AppleWloc, ClientDetail, \
21 | ClientList, LoadDB, SaveDB, locateSSID, stats, updateSSID
22 |
23 | urlpatterns = [
24 | path('admin/', admin.site.urls),
25 | url(r'^$', ClientList.as_view(), name="clientlist"),
26 | url(r'^client/(?P[:\w]+)$', ClientDetail.as_view(), name="client"),
27 | url(r'^clients/?$', ClientList.as_view()),
28 | url(r'^network/(?P.+)$', APDetail.as_view(), name="network"),
29 | url(r'^networks/?$', APList.as_view(), name="networks"),
30 | url(r'^apple-wloc/?$', AppleWloc, name="applewloc-base"),
31 | url(r'^savedb/(?P[:\w]*)$', SaveDB, name="savedb"),
32 | url(r'^loaddb/(?P[:\w]*)$', LoadDB, name="loaddb"),
33 | url(r'^apple-wloc/(?P[:\w]+)$', AppleWloc, name="applewloc"),
34 | url(r'^apple-mobile/(?P[:\w-]*)$', AppleMobile, name="apple-mobile"),
35 | url(r'^apple-mobile-lte/(?P[:\w-]*)$', AppleMobile, {'LTE': True},
36 | name="apple-mobile-lte"),
37 | url(r'^updateSSID$', updateSSID, name="updatessid"),
38 | url(r'^locateSSID/?$', locateSSID, name="locatessid-base"),
39 | url(r'^locateSSID/(?P[\w\W]+)$', locateSSID, name="locatessid"),
40 | url(r'^stats/?$', stats.as_view(), name="stats"),
41 | ]
42 |
--------------------------------------------------------------------------------
/security_ssid/views.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from django.core.exceptions import *
4 | from django.db.models import Count
5 | from django.http import HttpResponse
6 | from django.shortcuts import render
7 | from django.views.generic import *
8 |
9 | from netaddr import EUI
10 |
11 | from location_utils import wigle_query, wloc
12 | from security_ssid.models import AP, Client, PointDB
13 |
14 |
15 | def get_manuf(apdict):
16 | manufdict = {}
17 | for m in apdict.keys():
18 | try:
19 | mac = EUI(m)
20 | manufdict[m] = mac.oui.records[0]['org']
21 | # .split(' ')[0].replace(',','')
22 | # .replace(', Inc','').replace(' Inc.','')
23 | except:
24 | manufdict[m] = 'unknown'
25 | return manufdict
26 |
27 |
28 | class ClientList(ListView):
29 | model = Client
30 | template_name = 'client_list.html'
31 |
32 | def get_queryset(self):
33 | return Client.objects.order_by('manufacturer', 'mac')
34 |
35 | def get_context_data(self, **kwargs):
36 | context = super(ClientList, self).get_context_data(**kwargs)
37 | probedict = {}
38 | for client in Client.objects.all():
39 | probedict[client] = AP.objects.filter(client=client)
40 | context['probedict'] = probedict
41 | context['apcount'] = len(AP.objects.all())
42 | context['devicecount'] = len(Client.objects.all())
43 | return context
44 |
45 |
46 | class ClientDetail(DetailView):
47 | model = Client
48 | slug_field = 'mac'
49 | template_name = 'client_detail.html'
50 |
51 | def get_context_data(self, **kwargs):
52 | context = super(ClientDetail, self).get_context_data(**kwargs)
53 | context['APs'] = AP.objects.filter(client=self.object)
54 | return context
55 |
56 |
57 | class APList(ListView):
58 | model = AP
59 | template_name = 'ap_list.html'
60 |
61 | def get_queryset(self):
62 | return AP.objects.annotate(num_clients=Count('client')).order_by('-num_clients')
63 |
64 | def get_context_data(self, **kwargs):
65 | context = super(APList, self).get_context_data(**kwargs)
66 | context['apcount'] = len(AP.objects.all())
67 | context['devicecount'] = len(Client.objects.all())
68 | # context['Clients'] = self.object.client
69 | return context
70 |
71 |
72 | class APDetail(DetailView):
73 | model = AP
74 | template_name = 'ap_detail.html'
75 |
76 | def get_object(self):
77 | lookup = self.kwargs['ssid_or_bssid']
78 | if re.match(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', lookup):
79 | a = AP.objects.get(BSSID=lookup)
80 | else:
81 | a = AP.objects.get(SSID=lookup)
82 | return a
83 |
84 | def get_context_data(self, **kwargs):
85 | print(self.kwargs)
86 | context = super(APDetail, self).get_context_data(**kwargs)
87 | context['Clients'] = self.object.client.all()
88 | return context
89 |
90 |
91 | class Home(TemplateView):
92 | template_name = "home.html"
93 |
94 |
95 | class stats(TemplateView):
96 | template_name = "stats.html"
97 |
98 | def get_context_data(self, **kwargs):
99 | from operator import itemgetter
100 | context = super(stats, self).get_context_data(**kwargs)
101 | manuf = {}
102 | for m in Client.objects.values_list('manufacturer', flat=True).distinct():
103 | m = m[0].upper() + (m[1:].lower())
104 | manuf[m] = len(Client.objects.filter(manufacturer__iexact=m))
105 | l = []
106 | for m in manuf.items():
107 | l.append(m)
108 | context['mac_db'] = sorted(l, key=itemgetter(1), reverse=True)[:10]
109 | context['devicecount'] = len(Client.objects.all())
110 | return context
111 |
112 |
113 | def getCenter(apdict):
114 | numresults = len(apdict)
115 | latCenter = 0.0
116 | lonCenter = 0.0
117 | for (lat, lon) in apdict.values():
118 | latCenter += lat
119 | lonCenter += lon
120 | try:
121 | return (((latCenter / numresults), (lonCenter / numresults)))
122 | except ZeroDivisionError:
123 | return ((0, 0))
124 |
125 |
126 | def AppleWloc(request, bssid=None):
127 | if not bssid:
128 | print("Setting to Default BSSID")
129 | bssid = '00:1e:52:7a:ae:ad'
130 |
131 | print('Apple WLOC request for BSSID: {}'.format(bssid))
132 |
133 | if request.GET.get('ajax'):
134 | template = 'apple-wloc-ajax.js'
135 | else:
136 | template = 'apple-wloc.html'
137 | request.session['apdict'] = {}
138 | # Reset server-side cache of unique bssids if we load page normally
139 | request.session['apset'] = []
140 |
141 | bssid = bssid.lower()
142 | apdict = wloc.QueryBSSID(bssid)
143 |
144 | dupes = 0
145 | for ap in apdict.keys():
146 | if ap in request.session['apset']:
147 | dupes += 1
148 | del apdict[ap]
149 | request.session['apset'].append(ap)
150 |
151 | numresults = len(apdict)
152 |
153 | print('%s dupes excluded' % dupes)
154 | print('%s in set post filter' % len(request.session['apset']))
155 | print('%s returned to browser post filter' % numresults)
156 |
157 | if numresults == 0 or (-180.0, -180.0) in apdict.values():
158 | print('0 WLOC results.')
159 | return HttpResponse('No valid WLOC results for BSSID: {}'.format(bssid))
160 | else:
161 | print('Not 0 WLOC results')
162 |
163 | if bssid in apdict.keys():
164 | try:
165 | a = AP.objects.get(BSSID=bssid) # original design - only save ap to db if it's one that has been probed for
166 | (a.lat, a.lon) = apdict[bssid]
167 | a.save() # if Apple returns a match for BSSID we save this as location
168 | print('Updated %s location to %s' % (a, (a.lat, a.lon)))
169 | except ObjectDoesNotExist:
170 | pass
171 | for key in apdict.keys():
172 | request.session['apdict'][key] = apdict[key]
173 | print('Session apdict: %s' % len(request.session['apdict']))
174 | return render(request, template,
175 | {'bssid': bssid, 'hits': len(apdict), 'center': getCenter(apdict), 'bssids': apdict.keys(),
176 | 'apdict': apdict, 'manufdict': get_manuf(apdict)})
177 |
178 |
179 | def LoadDB(request, name=None):
180 | c = PointDB.objects.get(name=name)
181 | request.session['apdict'] = c.pointdict
182 | apdict = request.session['apdict']
183 | request.session['apset'] = set(apdict.keys())
184 | print('Loaded saved DB %s from %s' % (name, c.date_saved))
185 | return render(request, 'apple-wloc.html',
186 | {'bssid': apdict.keys()[0], 'hits': len(apdict), 'center': getCenter(apdict), 'bssids': apdict.keys(),
187 | 'apdict': apdict, 'manufdict': get_manuf(apdict)})
188 |
189 |
190 | def SaveDB(request, name=None):
191 | try:
192 | c = PointDB.objects.get(name=name)
193 | except ObjectDoesNotExist:
194 | c = PointDB(name=name)
195 | c.pointdict = request.session['apdict']
196 | c.save()
197 | return HttpResponse('Saved %s points as %s' % (len(request.session['apdict'].keys()), name)) # xss
198 |
199 |
200 | def AppleMobile(request, cellid=None, LTE=False):
201 | return HttpResponse('This is currently disabled.')
202 |
203 | if 'cellset' not in request.session:
204 | request.session['cellset'] = set()
205 | if request.GET.get('ajax'):
206 | template = 'apple-mobile-ajax.js'
207 | else:
208 | template = 'apple-mobile.html'
209 | request.session['cellset'] = set()
210 | if cellid:
211 | (celldict, celldesc) = wloc.QueryMobile(cellid, LTE)
212 | numresults = len(celldict)
213 | if numresults == 0:
214 | return HttpResponse('0 results.')
215 | dupes = 0
216 | for cell in celldict.keys():
217 | if cell in request.session['cellset']:
218 | dupes += 1
219 | del celldict[cell]
220 | request.session['cellset'].add(cell)
221 | return render(request, template, {'bssid': cellid,
222 | 'hits': len(celldict),
223 | 'center': getCenter(celldict),
224 | 'bssids': celldict.keys(),
225 | 'apdict': celldict,
226 | 'manufdict': celldesc,
227 | 'LTE': LTE})
228 | else:
229 | return render(request, 'wigle-wloc.html', {'ssid': '', 'center': (56.97518158, 24.17274475)})
230 |
231 |
232 | def locateSSID(request, ssid=None):
233 | if ssid:
234 | access_point_wigle_results = wigle_query.get_location(SSID=ssid)
235 | num_results = len(access_point_wigle_results)
236 |
237 | if num_results == 0:
238 | return HttpResponse('0 Wigle results for SSID: {}'.format(ssid))
239 |
240 | return render(request, 'wigle-wloc.html',
241 | {'ssid': ssid,
242 | 'hits': len(access_point_wigle_results),
243 | 'center': getCenter(access_point_wigle_results),
244 | 'bssids': access_point_wigle_results.keys(),
245 | 'apdict': access_point_wigle_results})
246 | else:
247 | return render(request, 'wigle-wloc.html',
248 | {'ssid': '',
249 | 'center': (56.97518158, 24.17274475)})
250 |
251 |
252 | def updateSSID(request):
253 | try:
254 | ssid = request.POST['ssid']
255 | (lat, lon) = request.POST['position'].replace('(', '').replace(')', '').split(',')
256 | lat = float(lat)
257 | lon = float(lon)
258 | a = AP.objects.get(SSID=ssid)
259 | (a.lat, a.lon) = (lat, lon)
260 | a.save()
261 | return HttpResponse('Updated %s location to %s' % (a, (a.lat, a.lon)))
262 | except ObjectDoesNotExist:
263 | return HttpResponse('Not found in db.')
264 |
--------------------------------------------------------------------------------
/security_ssid/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for security_ssid project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'security_ssid.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/tests/influxdb_test.py:
--------------------------------------------------------------------------------
1 | from db.influx import influxdb_client
2 |
3 | mobile_measurement_name = 'mobiledevices'
4 | access_pts_measurement_name = 'accesspoints'
5 |
6 |
7 | mobile_test_data_json = [
8 | {
9 | "measurement": mobile_measurement_name,
10 | "tags": {
11 | "macaddress": "01:ab:03:cd",
12 | "sensor": "001",
13 | "location": "001"
14 | },
15 | "fields": {
16 | "value": -55
17 | }
18 | }
19 | ]
20 | influxdb_client.write_points(mobile_test_data_json)
21 |
22 | # Yes, SQLi vuln introduced with string concatenation temporarily
23 | result = influxdb_client.query('select * from ' + mobile_measurement_name + ';')
24 |
25 | print("Mobile Result: {0}".format(result))
26 |
27 |
28 | ap_test_data_json = [
29 | {
30 | "measurement": access_pts_measurement_name,
31 | "tags": {
32 | "macaddress": "04:ef:06:gh",
33 | "sensor": "001",
34 | "location": "001"
35 | },
36 | "fields": {
37 | "value": -56
38 | }
39 | }
40 | ]
41 | influxdb_client.write_points(ap_test_data_json)
42 |
43 | # Yes, SQLi vuln introduced with string concatenation temporarily
44 | result = influxdb_client.query('select * from ' + access_pts_measurement_name + ';')
45 |
46 | print("Access Points Result: {0}".format(result))
47 |
48 |
49 |
--------------------------------------------------------------------------------
/tests/wigle_test.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | WIGLE_ENDPOINT_API_V2 = 'https://api.wigle.net/api/v2/network/search'
4 |
5 | class WigleSearch():
6 | def __init__(self, user, password):
7 | self.user = user
8 | self.password = password
9 |
10 | def search(self, lat_range=None, long_range=None, variance=None,
11 | bssid=None, ssid=None, ssidlike=None,
12 | last_update=None,
13 | address=None, state=None, zipcode=None,
14 | on_new_page=None, max_results=100):
15 | """
16 | Credit to: https://github.com/viraptor/wigle/blob/master/wigle/__init__.py
17 | Search the Wigle wifi database for matching entries. The following
18 | criteria are supported:
19 | Args:
20 | lat_range ((float, float)): latitude range
21 | long_range ((float, float)): longitude range
22 | variance (float): radius tolerance in degrees
23 | bssid (str): BSSID/MAC of AP
24 | ssid (str): SSID of network
25 | last_update (datetime): when was the AP last seen
26 | address (str): location, address
27 | state (str): location, state
28 | zipcode (str): location, zip code
29 | on_new_page (func(int)): callback to notify when requesting new
30 | page of results
31 | max_results (int): maximum number of results from search query
32 | Returns:
33 | [dict]: list of dicts describing matching wifis
34 | """
35 |
36 | # onlymine=false&freenet=false&paynet=false&ssidlike=starbucks
37 |
38 | params = {
39 | 'latrange1': lat_range[0] if lat_range else "",
40 | 'latrange2': lat_range[1] if lat_range else "",
41 | 'longrange1': long_range[0] if long_range else "",
42 | 'longrange2': long_range[1] if long_range else "",
43 | 'variance': str(variance) if variance else "0.01",
44 | 'netid': bssid or "",
45 | 'ssid': ssid or "",
46 | 'ssidlike': ssidlike or "",
47 | # Filter points by how recently they've been updated, condensed date/time numeric string format 'yyyyMMddhhmmss'
48 | 'lastupdt': last_update.strftime("%Y%m%d%H%M%S") if last_update else "",
49 | 'onlymine': 'false',
50 | 'freenet': 'false',
51 | 'paynet': 'false',
52 | 'addresscode': address or "",
53 | 'statecode': state or "",
54 | 'zipcode': zipcode or "",
55 | }
56 |
57 | result_wifi = []
58 |
59 | while True:
60 | if on_new_page:
61 | on_new_page(params.get('first', 1))
62 | resp = requests.get(WIGLE_ENDPOINT_API_V2, auth=(self.user, self.password), params=params)
63 | data = resp.json()
64 | if not data['success']:
65 | raise_wigle_error(data)
66 |
67 | for result in data['results'][:max_results - len(result_wifi)]:
68 | fix_latlong_nums(result)
69 | result_wifi.append(result)
70 |
71 | if data['resultCount'] < 100 or len(result_wifi) >= max_results:
72 | break
73 |
74 | params['first'] = data['last'] + 1
75 |
76 | print(result_wifi)
77 | return result_wifi
78 |
79 |
80 | def fix_latlong_nums(net):
81 | net['trilat'] = float(net['trilat'])
82 | net['trilong'] = float(net['trilong'])
83 |
84 |
85 | def raise_wigle_error(data):
86 | message = data.get('message')
87 | if message == "too many queries":
88 | raise WigleRatelimitExceeded()
89 | else:
90 | raise WigleRequestFailure(message)
91 |
92 |
93 | class WigleError(Exception):
94 | pass
95 |
96 |
97 | class WigleRequestFailure(WigleError):
98 | pass
99 |
100 |
101 | class WigleRatelimitExceeded(WigleRequestFailure):
102 | pass
103 |
104 |
--------------------------------------------------------------------------------