net/arp-scan: style + whitespace cleanup

This commit is contained in:
Franco Fichtner
2017-10-04 09:07:47 +02:00
parent e7042b7454
commit 304e32e805
11 changed files with 120 additions and 124 deletions
+11 -11
View File
@@ -1,16 +1,16 @@
ARP Scan sends ARP packets to hosts on the local network and displays
any responses that are received.
ARP Scan sends ARP packets to hosts on the local network and displays
any responses that are received.
The Address Resolution Protocol (ARP) uses a simple message format containing
The Address Resolution Protocol (ARP) uses a simple message format containing
one address resolution request or response (usually IPv4).
ARP Scan is a simple tool yet very powerful and it represent the only way
to find a device using an arp response. Once youve found the MAC
address, you can find more info about that device by matching that MAC
address to its vendor.
ARP Scan is a simple tool yet very powerful and it represent the only way
to find a device using an arp response. Once youve found the MAC
address, you can find more info about that device by matching that MAC
address to its vendor.
Arp scan techniques are very important to understand ARP/MAC responses
for penetration tester and diagnosys purpose. It is the first tool for
network monitoring, especially against ip collisions, arpspoof and all
kind of hijack techniques, like Man-In-The-Middle Attack. It also helps
Arp scan techniques are very important to understand ARP/MAC responses
for penetration tester and diagnosys purpose. It is the first tool for
network monitoring, especially against ip collisions, arpspoof and all
kind of hijack techniques, like Man-In-The-Middle Attack. It also helps
in cases when someone is spoofing IP address and DoS-ing your server.
@@ -87,5 +87,4 @@ class ServiceController extends ApiControllerBase
return array("message" => "error");
}
}
}
@@ -41,31 +41,30 @@ class SettingsController extends ApiControllerBase
public function getAction()
{
// define list of configurable settings
$result = array();
if ($this->request->isGet()) {
$mdl = new ARPscanner();
$result['arpscanner'] = $mdl->getNodes();
// returns: {"arpscanner":{"general":{"interface":
// {"lan":{"value":"lan","selected":1}},"networks":
// {"10.0.1.0\/24":{"value":"10.0.1.0\/24","selected":1}}}}}
$backend = new Backend();
$bckresult = trim($backend->configdRun("arpscanner interfaces"));
$ifnames = json_decode($bckresult);
$result['arpscanner']['general']['interface'] = array();
if (is_array($ifnames) || is_object($ifnames))
{
foreach ($ifnames as &$arr) {
$ifname = $arr[0];
$result['arpscanner']['general']['interface'][$ifname] = array();
$result['arpscanner']['general']['interface'][$ifname]['value'] = join(", ", array($ifname, " (".$arr[2].")") );
$result = array();
if ($this->request->isGet()) {
$mdl = new ARPscanner();
$result['arpscanner'] = $mdl->getNodes();
// returns: {"arpscanner":{"general":{"interface":
// {"lan":{"value":"lan","selected":1}},"networks":
// {"10.0.1.0\/24":{"value":"10.0.1.0\/24","selected":1}}}}}
$backend = new Backend();
$bckresult = trim($backend->configdRun("arpscanner interfaces"));
$ifnames = json_decode($bckresult);
$result['arpscanner']['general']['interface'] = array();
if (is_array($ifnames) || is_object($ifnames)) {
foreach ($ifnames as &$arr) {
$ifname = $arr[0];
$result['arpscanner']['general']['interface'][$ifname] = array();
$result['arpscanner']['general']['interface'][$ifname]['value'] = join(", ", array($ifname, " (".$arr[2].")"));
}
}
// $result['arpscanner']['general']['networks'] = '192.168.1.0/24,172.16.45.0/25';
}
// $result['arpscanner']['general']['networks'] = '192.168.1.0/24,172.16.45.0/25';
}
return $result;
return $result;
}
/**
@@ -79,7 +78,7 @@ class SettingsController extends ApiControllerBase
// load model and update with provided data
$mdl = new ARPscanner();
$mdl->setNodes($this->request->getPost("arpscanner"));
// perform validation
$valMsgs = $mdl->performValidation();
foreach ($valMsgs as $field => $msg) {
@@ -88,7 +87,7 @@ class SettingsController extends ApiControllerBase
}
$result["validations"]["general.".$msg->getField()] = $msg->getMessage();
}
// serialize model to config and save
if ($valMsgs->count() == 0) {
$mdl->serializeToConfig();
@@ -98,6 +97,4 @@ class SettingsController extends ApiControllerBase
}
return $result;
}
}
@@ -45,7 +45,7 @@ class IndexController extends \OPNsense\Base\IndexController
$this->view->title = gettext('ARP Scan');
$this->view->general = $this->getForm("general");
$this->view->pick('OPNsense/ARPscanner/index');
$this->view->generalForm = $this->getForm("general");
}
}
@@ -34,7 +34,8 @@ use OPNsense\Base\BaseModel;
class ARPscanner extends BaseModel
{
public function test(){
public function test()
{
$command="/sbin/ifconfig -l -u";
exec($command, $output);
return $output;
@@ -28,11 +28,11 @@ POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript">
function flush_table(){
$('#netTable tr').slice(2).remove()
}
var check_state = 0;
function check_scanner_status(ifname){
// sets 0 if stopped and 1 if running
@@ -56,12 +56,12 @@ POSSIBILITY OF SUCH DAMAGE.
$("#scan_progress").removeClass("fa fa-spinner fa-pulse");
$("#startScanner").removeClass("disabled")
}
});
});
}
function get_status(ifname){
flush_table();
ajaxCall(url="/api/arpscanner/service/status",
ajaxCall(url="/api/arpscanner/service/status",
sendData={'interface':ifname},
callback=function(data,status) {
$.each(data['peers'], function(key_x,peer) {
@@ -74,12 +74,12 @@ POSSIBILITY OF SUCH DAMAGE.
check_scanner_status(ifname)
$("#ifname").text(ifname);
$("#started").text(data['started']);
$("#last").text(data['last']);
$("#last").text(data['last']);
});
}
$( document ).ready(function() {
var data_get_map = {'frm_GeneralSettings': "/api/arpscanner/settings/get"};
//~ console.log(data_get_map);
mapDataToFormUI(data_get_map).done(function(data){
@@ -87,10 +87,10 @@ POSSIBILITY OF SUCH DAMAGE.
formatTokenizersUI();
$('select').selectpicker('refresh');
// check if the scanner is already running
first_status = $('#arpscanner\\.general\\.interface option:selected')[0].value;
first_status = $('#arpscanner\\.general\\.interface option:selected')[0].value;
check_scanner_status(first_status);
});
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/arpscanner/settings/set",formid='frm_GeneralSettings',callback_ok=function(){
@@ -98,15 +98,15 @@ POSSIBILITY OF SUCH DAMAGE.
ajaxCall(url="/api/arpscanner/service/reload", sendData={},callback=function(data,status) {
// action to run after reload
});
});
});
$("#statusScanner").click(function(){
value = $('#arpscanner\\.general\\.interface option:selected')[0].value;
get_status(value);
});
$("#stopScanner").click(function(){
// action to run after successful save, for example reconfigure service.
value = $('#arpscanner\\.general\\.interface option:selected')[0].value;
@@ -118,7 +118,7 @@ POSSIBILITY OF SUCH DAMAGE.
check_scanner_status(value);
});
});
// CHECK STATUS
// check the status opf the scanner on selected interface
$("#arpscanner\\.general\\.interface").change(function(){
@@ -126,7 +126,7 @@ POSSIBILITY OF SUCH DAMAGE.
get_status(value);
$("#ifname").text(value);
$("#started").text('');
$("#last").text('');
$("#last").text('');
});
@@ -135,38 +135,38 @@ POSSIBILITY OF SUCH DAMAGE.
$("#scan_progress").addClass("fa fa-spinner fa-pulse");
var ifname = $('#arpscanner\\.general\\.interface option:selected')[0].value;
var networks = $('#arpscanner\\.general\\.networks').val();
ajaxCall(url="/api/arpscanner/service/start",
ajaxCall(url="/api/arpscanner/service/start",
sendData={'interface':ifname, 'networks': networks},
callback=function(data,status) {
// action to run after reload
//~ console.log(data);
$("#ifname").text(data['interface']);
$("#started").text(data['started']);
$("#last").text(data['last']);
$("#last").text(data['last']);
flush_table();
check_scanner_status(ifname);
});
});
}); // END
</script>
<section class="col-xs-12">
<div id="update_stop" class="alert alert-info" role="alert" style="min-height: 65px;">
<div class="pull-left updatestatus" style="margin-top: 8px;">{{ lang._('Scan is stopped')}}</div>
</div>
</div>
<div id="update_start" class="alert alert-warning" role="alert" style="min-height: 65px; display:none;">
<div class="pull-left updatestatus" style="margin-top: 8px;">{{ lang._('Scan is running')}}</div>
</div>
<div class="pull-left updatestatus" style="margin-top: 8px;">{{ lang._('Scan is running')}}</div>
</div>
<div class="content-box">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings'])}}
<div class="col-md-12" style="padding-bottom: 13px; padding-top: 13px;">
<button class='btn btn-default' id="stopScanner" style="margin-right: 8px;">{{ lang._('Stop') }} <i id=""></i></button>
<button class='btn btn-default' id="statusScanner" style="margin-right: 8px;">{{ lang._('Refresh') }} <i id=""></i></button>
<button class='btn btn-default' id="stopScanner" style="margin-right: 8px;">{{ lang._('Stop') }} <i id=""></i></button>
<button class='btn btn-default' id="statusScanner" style="margin-right: 8px;">{{ lang._('Refresh') }} <i id=""></i></button>
<button class="btn btn-primary pull-center" id="startScanner" type="button"><i id="scan_progress" class=""></i><b>{{ lang._('Start') }}</b></button>
</div>
</div>
@@ -180,15 +180,15 @@ POSSIBILITY OF SUCH DAMAGE.
<tr>
<th><b>{{ lang._('Interface name') }}</b></th>
<th><b>{{ lang._('Started') }}</b></th>
<th><b>{{ lang._('Last update') }}</b></th>
<th><b>{{ lang._('Last update') }}</b></th>
</tr>
</thead>
<tbody>
<td><p id="ifname"></p></td>
<td><p id="started"></p></td>
<td><p id="last"></p></td>
<td><p id="last"></p></td>
</tbody>
</table>
<hr>
<table id="netTable">
@@ -44,7 +44,7 @@ class ArpScanner(ProcessIO):
grep -v "ps ax "| \
grep -E '^[ 0-9]+'| \
awk -F' ' '{{print $1}}'"""
def __init__(self, ifname, network):
"""
netif='eth0'
@@ -57,7 +57,7 @@ class ArpScanner(ProcessIO):
self.regexp = '([0-9\.]+)[\t]*([\dA-F]{2}(?:[-:][\dA-F]{2}){5})[\t]*([A-Za-z0-9\ \.\-\,\'\(\)]*)'
# os_command_filter needs '{}'.format(ifname)
self._DEBUG = False
# FileIO contains all the IO files
tmp_fileio_path = '/tmp/ARPscanner'
self.tmp = tmp_fileio_path
@@ -77,10 +77,10 @@ class ArpScanner(ProcessIO):
fout = os.path.sep.join((self.tmp, self.ifname))+'.out'
if not os.path.exists(fout):
return
self.result['last'] = time.ctime(os.path.getmtime(fout))
self.result['started'] = time.ctime(os.path.getctime(fout))
with open(fout, 'r') as f:
fcont = f.read()
#~ print(fcont)
@@ -88,7 +88,7 @@ class ArpScanner(ProcessIO):
if self._DEBUG: print(regexp)
for netfound in regexp:
self.result['peers'].append(
(netfound[0].replace('\t', ''),
(netfound[0].replace('\t', ''),
netfound[1], netfound[2]))
#~ return self.result
@@ -101,35 +101,35 @@ class ArpScanner(ProcessIO):
if running: return self.status()
fileio = FileIO(self.ifname, self.tmp)
os_command = ["arp-scan", "-I", self.ifname, self.network,
os_command = ["arp-scan", "-I", self.ifname, self.network,
"--retry", "5"]
# run a child and detach
osc = Popen(os_command,
stdout=fileio.out,
stderr=fileio.err,
osc = Popen(os_command,
stdout=fileio.out,
stderr=fileio.err,
bufsize=0,
shell=False)
def get_json(self):
return json.dumps(self.result)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', nargs='?', required=True,
parser.add_argument('-i', nargs='?', required=True,
help="network interface")
parser.add_argument('-net', nargs='?', help="""network to scan""")
parser.add_argument('-check', action="store_true", required=False,
parser.add_argument('-check', action="store_true", required=False,
help="check if arp-san is running on that interface")
parser.add_argument('-start', action="store_true", required=False,
help="starts arp-scan")
parser.add_argument('-stop', action="store_true", required=False,
parser.add_argument('-start', action="store_true", required=False,
help="starts arp-scan")
parser.add_argument('-stop', action="store_true", required=False,
help="Stops scanning on that interfaces")
parser.add_argument('-status', action="store_true", required=False,
parser.add_argument('-status', action="store_true", required=False,
help="Parse arp-scan stdout and return json")
args = parser.parse_args()
if not args.net:
args.net = '--localnet'
@@ -144,10 +144,9 @@ if __name__ == '__main__':
sys.exit()
ap = ArpScanner(args.i, args.net)
if args.start:
ap.start()
ap.status()
ap.status()
print(ap.get_json())
@@ -36,21 +36,21 @@ class FileIO(object):
# file names
self.nerr = '{}.err'.format(name)
self.nout = '{}.out'.format(name)
# file paths
self.epath = os.path.sep.join((path, self.nerr))
self.opath = os.path.sep.join((path, self.nout))
if not os.path.exists(path):
os.makedirs(path)
# file obj, 1 means the buffer size, small as possibile to flush
# data soon as possible :)
# this feature would be better with python3
self.err = open(self.epath, 'w', buffering=0)
self.out = open(self.opath, 'w', buffering=0)
def close(self):
self.err.close()
self.out.close()
@@ -3,17 +3,17 @@
#~ Copyright © 2017 Giuseppe De Marco <giuseppe.demarco@unical.it>
#~ All rights reserved.
#~
#~
#~ Redistribution and use in source and binary forms, with or without modification,
#~ are permitted provided that the following conditions are met:
#~
#~
#~ 1. Redistributions of source code must retain the above copyright notice,
#~ this list of conditions and the following disclaimer.
#~
#~
#~ 2. Redistributions in binary form must reproduce the above copyright notice,
#~ this list of conditions and the following disclaimer in the documentation
#~ and/or other materials provided with the distribution.
#~
#~
#~ THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
#~ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
#~ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
@@ -59,7 +59,7 @@ AF_UNIX = 1
AF_INET = 2
class IPtools(object):
@staticmethod
def get_ip_address(ifname):
# python2 only
@@ -71,7 +71,7 @@ class IPtools(object):
SIOCGIFADDR,
struct.pack('256s', ifname[:15])
)[20:24])
@staticmethod
def get_netmask(ifname):
# python2 only
@@ -79,10 +79,10 @@ class IPtools(object):
#
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
35099,
s.fileno(),
35099,
struct.pack('256s', ifname))[20:24])
@staticmethod
def is_up(ifname):
''' Return True if the interface is up, False otherwise. '''
@@ -92,9 +92,9 @@ class IPtools(object):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Get existing device flags
ifreq = struct.pack('16sh', ifname, 0)
flags = struct.unpack('16sh',
fcntl.ioctl(s.fileno(),
SIOCGIFFLAGS,
flags = struct.unpack('16sh',
fcntl.ioctl(s.fileno(),
SIOCGIFFLAGS,
ifreq))[1]
# Set new flags
@@ -102,7 +102,7 @@ class IPtools(object):
return True
else:
return False
@staticmethod
def get_mac(ifname):
''' Obtain the device's mac address. '''
@@ -128,7 +128,7 @@ class IPtools(object):
ifreq = struct.pack('16sH6B8x', ifname, AF_UNIX, *macbytes)
fcntl.ioctl(s.fileno(), SIOCSIFHWADDR, ifreq)
@staticmethod
def get_interfaces(json_output=False):
"""
@@ -137,12 +137,12 @@ class IPtools(object):
name_pattern = "^(\w+)\s"
mac_pattern = ".*?HWaddr[ ]([0-9A-Fa-f:]{17})"
ip_pattern = ".*?\n\s+inet[ ]addr:((?:\d+\.){3}\d+)"
pattern = re.compile("".join((name_pattern,
mac_pattern,
pattern = re.compile("".join((name_pattern,
mac_pattern,
ip_pattern,
)),
flags=re.MULTILINE)
ifconfig = subprocess.check_output("ifconfig").decode()
interfaces = pattern.findall(ifconfig)
Interface = namedtuple("Interface", "name {mac} {ip}".format(
@@ -160,12 +160,12 @@ class IPtools(object):
name_pattern = "^(\w+).+[\n\t\s]*.*[\n\t\s]*"
mac_pattern = ".*?ether[ ]([0-9A-Fa-f:]{17})[\n\t\s]*"
ip_pattern = ".*?\n\s+inet[ ]((?:\d+\.){3}\d+)"
pattern = re.compile("".join((name_pattern,
mac_pattern,
pattern = re.compile("".join((name_pattern,
mac_pattern,
ip_pattern,
)),
flags=re.MULTILINE)
ifconfig = subprocess.check_output(["ifconfig", "-u"]).decode()
interfaces = pattern.findall(ifconfig)
Interface = namedtuple("Interface", "name {mac} {ip}".format(
@@ -39,21 +39,21 @@ class ProcessIO(object):
"""
mypid = getpid()
os_command = os_command_filter.format(ifname)
osc = Popen(os_command,
stdin=PIPE,
stdout=PIPE,
osc = Popen(os_command,
stdin=PIPE,
stdout=PIPE,
stderr=PIPE,
shell=True)
output, err = osc.communicate()
if _DEBUG: print(output)
if output:
pids = []
pids = []
for pid in output.split(linesep):
if pid and int(pid) != mypid:
pids.append(int(pid))
return pids[:]
return 0
@classmethod
def stop(cls, ifname, os_command_filter):
""" stop scanning on that interface """
@@ -24,7 +24,7 @@ type:script_output
message:get network interfaces
[check]
command:python2.7 /usr/local/opnsense/scripts/OPNsense/ARPscanner/ARPscanner.py
command:python2.7 /usr/local/opnsense/scripts/OPNsense/ARPscanner/ARPscanner.py
parameters:-i %s -check
type:script_output
message:check if arp scan is running on %s interface