387 lines
20 KiB
HTML
387 lines
20 KiB
HTML
<div class="panel panel-default" ng-controller="SiteSurvey_Controller"><div class="panel-heading"><h4 class="panel-title pull-left">{{title}}</h4><span class="pull-right">{{version}}</span><div class="clearfix"></div></div></div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="panel panel-default" ng-controller="SiteSurvey_ControlsController">
|
|
<div class="panel-heading">
|
|
<h3 class="panel-title">
|
|
Controls
|
|
</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<table style="width:100%">
|
|
<tr>
|
|
<td style="padding-bottom: .5em;" class="text-muted">Dependencies</td>
|
|
<td ng-hide="$root.status.installed" style="text-align:right;padding-bottom: .5em;"><button type="button" style="width: 90px;" class="btn btn-{{installLabel}} btn-xs" data-toggle="modal" data-target="#dependenciesInstallModal" ng-disabled="processing">{{install}}</button></td>
|
|
<td ng-show="$root.status.installed" style="text-align:right;padding-bottom: .5em;"><button type="button" style="width: 90px;" class="btn btn-{{installLabel}} btn-xs" data-toggle="modal" data-target="#dependenciesRemoveModal" ng-disabled="processing">{{install}}</button></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="modal fade" id="dependenciesInstallModal" tabindex="-1" role="dialog" aria-labelledby="dependenciesModalLabel">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title" id="dependenciesInstallModalLabel">Install dependencies</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
All required dependencies have to be installed first. This may take a few minutes.<br /><br />
|
|
Please wait, do not leave or refresh this page. Once the install is complete, this page will refresh automatically.
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-info" ng-click="handleDependencies('internal')" data-dismiss="modal">Internal</button>
|
|
<button type="button" class="btn btn-info" ng-hide="device == 'tetra' || sdAvailable == false" ng-click="handleDependencies('sd')" data-dismiss="modal">SD Card</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="dependenciesRemoveModal" tabindex="-1" role="dialog" aria-labelledby="dependenciesModalLabel">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title" id="dependenciesRemoveModalLabel">Remove dependencies</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
All required dependencies will be removed. This may take a few minutes.<br /><br />
|
|
Please wait, do not leave or refresh this page. Once the remove is complete, this page will refresh automatically.
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-info" ng-click="handleDependencies()" data-dismiss="modal">Confirm</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div ng-controller="SiteSurvey_ScanController">
|
|
|
|
<div class="panel panel-default" ng-show="$root.status.installed && processes.length">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Running Processes</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Process</th>
|
|
<th>Target</th>
|
|
<th>Client</th>
|
|
<th>Actions</th>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat="proc in processes">
|
|
<td>{{ proc.name }}</td>
|
|
<td>{{ proc.target }}</td>
|
|
<td>{{ proc.client }}</td>
|
|
<td>
|
|
<button type="button" class="btn btn-danger btn-xs" ng-show="proc.name == 'aireplay-ng'" ng-click="stopDeauth()">Stop Deauth</button>
|
|
<button type="button" class="btn btn-danger btn-xs" ng-show="proc.name == 'airodump-ng'" ng-click="stopCapture()">Stop Capture</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel panel-default" ng-show="$root.status.installed">
|
|
<div class="panel-heading pointer" data-toggle="collapse" data-target="#Interfaces">
|
|
<h4 class="panel-title">Interfaces</span></h4>
|
|
</div>
|
|
<div id="Interfaces" class="panel-collapse collapse">
|
|
<div class="panel-body">
|
|
<form>
|
|
<div class="form-group">
|
|
<div class="input-group">
|
|
<span class="input-group-addon input-sm">Interface</span>
|
|
<select class="form-control input-sm" ng-disabled="scanning" ng-model="selectedInterface">
|
|
<option ng-repeat="interface in interfaces">{{ interface }}</option>
|
|
</select>
|
|
<span class="input-group-btn">
|
|
<button class="btn btn-{{startMonLabel}} btn-sm" ng-disabled="scanning || startingMon" ng-click="startMonitor()">{{startMon}}</button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="input-group">
|
|
<span class="input-group-addon input-sm">Monitor</span>
|
|
<select class="form-control input-sm" ng-disabled="scanning || monitors.length == 0" ng-model="selectedMonitor">
|
|
<option ng-repeat="monitor in monitors">{{ monitor }}</option>
|
|
</select>
|
|
<span class="input-group-btn">
|
|
<button class="btn btn-{{stopMonLabel}} btn-sm" ng-disabled="scanning || stoppingMon || monitors.length == 0" ng-click="stopMonitor()">{{stopMon}}</button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel panel-default" ng-show="$root.status.installed">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title pull-left">Scan Results <span class="badge">{{accessPoints.length}}</span></h4>
|
|
<div class="pull-right">
|
|
Auto-refresh <div class="btn-group">
|
|
<button ng-click="toggleAutoRefresh()" class="btn btn-xs btn-{{refreshLabelON}}">ON</button>
|
|
<button ng-click="toggleAutoRefresh()" class="btn btn-xs btn-{{refreshLabelOFF}}">OFF</button>
|
|
</div>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<form>
|
|
<div class="form-group form-inline">
|
|
<button class="btn btn-{{scanLabel}} btn-sm" ng-disabled="scanning" ng-click="scanForNetworks()">{{scan}}</button>
|
|
|
|
<label class="radio-inline"><input type="radio" ng-model="scanType" value="apOnly" ng-disabled="scanning">AP Only</label>
|
|
<label class="radio-inline"><input type="radio" ng-model="scanType" value="clientAP" ng-disabled="scanning || monitors.length == 0">AP & Client</label>
|
|
|
|
<select class="form-control input-sm" ng-model="scanDuration" ng-hide="(scanType == 'apOnly')" ng-disabled="scanning">
|
|
<option value="15">15 Seconds</option>
|
|
<option value="30">30 Seconds</option>
|
|
<option value="60">1 Minute</option>
|
|
<option value="120">2 Minute</option>
|
|
<option value="300">5 Minutes</option>
|
|
<option value="600">10 Minutes</option>
|
|
</select>
|
|
|
|
<span ng-show="monitors.length == 0" class="text-danger pull-right" style="padding-top: 5px;">Warning: a monitor interface has to be enabled to display clients information.</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="input-group">
|
|
<span class="input-group-addon input-sm">Search</span>
|
|
<input type="text" class="form-control input-sm" placeholder="Search in scan results" ng-disabled="(accessPoints.length === 0)" ng-model="search">
|
|
<div class="input-group-btn">
|
|
<button class="btn btn-default btn-sm" ng-disabled="(accessPoints.length === 0)" ng-click="clearFilter()">Clear Filter</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table" ng-hide="(accessPoints.length === 0)">
|
|
<thead>
|
|
<tr>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'ssid'; sortReverse = !sortReverse">SSID
|
|
<span ng-show="sortType == 'ssid' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'ssid' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'mac'; sortReverse = !sortReverse">MAC
|
|
<span ng-show="sortType == 'mac' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'mac' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'encryption'; sortReverse = !sortReverse">Encryption
|
|
<span ng-show="sortType == 'encryption' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'encryption' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'cipher'; sortReverse = !sortReverse">Cipher
|
|
<span ng-show="sortType == 'cipher' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'cipher' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'auth'; sortReverse = !sortReverse">Auth
|
|
<span ng-show="sortType == 'auth' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'auth' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'channel'; sortReverse = !sortReverse">Channel
|
|
<span ng-show="sortType == 'channel' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'channel' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'frequency'; sortReverse = !sortReverse">Frequency
|
|
<span ng-show="sortType == 'frequency' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'frequency' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'signal'; sortReverse = !sortReverse">Signal
|
|
<span ng-show="sortType == 'signal' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'signal' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a class="pointer" ng-click="sortType = 'quality'; sortReverse = !sortReverse">Quality
|
|
<span ng-show="sortType == 'quality' && !sortReverse" class="caret pointer"></span>
|
|
<span ng-show="sortType == 'quality' && sortReverse" class="dropup"><span class="caret pointer"></span></span>
|
|
</a>
|
|
</th>
|
|
<th>
|
|
Capture
|
|
<span class="dropdown">
|
|
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="poolDropdown">
|
|
<li ng-click="stopCapture()"><a>Stop current capture</a></li>
|
|
</ul>
|
|
<button ng-disabled="!captureRunning || monitors.length == 0" class="btn btn-xs btn-default dropdown-toggle" type="button" id="poolDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="caret"></span>
|
|
</button>
|
|
</span>
|
|
</th>
|
|
<th>
|
|
Deauth
|
|
<span class="dropdown">
|
|
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="poolDropdown">
|
|
<li ng-click="stopDeauth()"><a>Stop current deauth</a></li>
|
|
</ul>
|
|
<button ng-disabled="!deauthRunning || monitors.length == 0" class="btn btn-xs btn-default dropdown-toggle" type="button" id="poolDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="caret"></span>
|
|
</button>
|
|
</span>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat-start="accessPoint in accessPoints | orderBy:sortType:sortReverse | filter:search">
|
|
<td class="autoselect">
|
|
<span class="text-muted" ng-hide="accessPoint.ssid"><i>Hidden</i></span>
|
|
{{ accessPoint.ssid }}
|
|
<hook-button hook="ssid" content="accessPoint.ssid"></hook-button>
|
|
</td>
|
|
<td class="autoselect">
|
|
<button type="button" class="btn btn-default btn-xs" ng-click="getMACInfo(accessPoint.mac)" data-toggle="modal" data-target="#infoModal">{{accessPoint.mac}}</button>
|
|
<hook-button hook="mac" content="accessPoint.mac"></hook-button>
|
|
</td>
|
|
<td>{{ accessPoint.encryption }}</td>
|
|
<td>{{ accessPoint.cipher }}</td>
|
|
<td>{{ accessPoint.auth }}</td>
|
|
<td>{{ accessPoint.channel }}</td>
|
|
<td>{{ accessPoint.frequency }} Ghz</td>
|
|
<td>{{ accessPoint.signal }}</td>
|
|
<td class="{{ accessPoint.qualityLabel }}">{{ accessPoint.quality }}%</td>
|
|
<td>
|
|
<button type="button" class="btn btn-default btn-xs" ng-click="toggleCapture(accessPoint)" ng-hide="accessPoint.captureOnSelected" ng-disabled="accessPoint.captureRunning || monitors.length == 0">Capture</button>
|
|
<button type="button" class="btn btn-danger btn-xs" ng-click="toggleCapture(accessPoint)" ng-show="accessPoint.captureOnSelected">Stop</button>
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-default btn-xs" ng-click="toggleDeauth(accessPoint)" ng-hide="accessPoint.deauthOnSelected" ng-disabled="accessPoint.deauthRunning || monitors.length == 0">Deauth</button>
|
|
<button type="button" class="btn btn-danger btn-xs" ng-click="toggleDeauth(accessPoint)" ng-show="accessPoint.deauthOnSelected">Stop</button>
|
|
</td>
|
|
</tr>
|
|
<tr ng-repeat="mac in accessPoint.clients" ng-repeat-end class="active">
|
|
<td></td>
|
|
<td class="autoselect">
|
|
<button type="button" class="btn btn-default btn-xs" ng-click="getMACInfo(mac)" data-toggle="modal" data-target="#infoModal">{{mac}}</button>
|
|
<hook-button hook="mac" content="mac"></hook-button>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td>
|
|
<button type="button" class="btn btn-default btn-xs" ng-click="toggleDeauth(accessPoint, mac)" ng-hide="accessPoint.deauthOnSelected" ng-disabled="accessPoint.deauthRunning || monitors.length == 0">Deauth</button>
|
|
<button type="button" class="btn btn-danger btn-xs" ng-click="toggleDeauth(accessPoint, mac)" ng-show="accessPoint.deauthOnSelected">Stop</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="well" ng-show="(accessPoints.length === 0)">No scan results...</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal fade" id="infoModal" tabindex="-1" role="dialog" aria-labelledby="infoModal">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title" id="infoModalLabel">{{title}}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<pre class="scrollable-pre log-pre">{{output}}</pre>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="panel panel-default" ng-show="$root.status.installed" ng-controller="SiteSurvey_CaptureController">
|
|
<div class="panel-heading pointer" data-toggle="collapse" data-target="#Capture">
|
|
<h4 class="panel-title">Capture <span class="badge">{{capture.length}}</span></h4>
|
|
</div>
|
|
<div id="Capture" class="panel-collapse collapse">
|
|
<div class="panel-body">
|
|
<button class="btn btn-primary btn-sm pull-right" ng-click="refreshCapture()">Refresh Capture</button><div class="clearfix"></div>
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-bordered table-hover" ng-hide="(capture.length == 0)">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>SSID</th>
|
|
<th>MAC</th>
|
|
<th>IVS</th>
|
|
<th>WPA Handshake</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat="entry in capture" ng-if="entry != ''">
|
|
<td>{{entry[0]}}</td>
|
|
<td>{{entry[2]}}</td>
|
|
<td>{{entry[3]}}</td>
|
|
<td>{{entry[4]}}</td>
|
|
<td>{{entry[5]}}</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-fixed-length btn-sm btn-default" data-toggle="modal" data-target="#captureModal" ng-click="viewCapture(entry[1])">View</button>
|
|
<button type="button" class="btn btn-sm btn-default" ng-click="downloadCapture(entry[1])">Download</button>
|
|
<button type="button" class="btn btn-fixed-length btn-sm btn-danger" ng-click="deleteCapture(entry[1])">Delete</button>
|
|
  <img src="/img/throbber.gif" ng-show="throbber"/>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="well" ng-show="(capture.length === 0)">No capture...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="captureModal" tabindex="-1" role="dialog" aria-labelledby="captureModalLabel">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title" id="captureModalLabel">View Capture - {{captureDate}}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<pre class="scrollable-pre log-pre">{{captureOutput}}</pre>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|