~stefanor/ibid/zero-param-723132

« back to all changes in this revision

Viewing changes to ibid/plugins/network.py

  • Committer: Michael Gorven
  • Date: 2010-02-24 12:32:52 UTC
  • mfrom: (889.4.15 nmap)
  • Revision ID: michael@gorven.za.net-20100224123252-5ly953ogsmvjhprf
Add Nmap processor for doing port and network scans.
https://code.launchpad.net/~mgorven/ibid/nmap/+merge/19848

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
from ibid.compat import defaultdict
7
7
from httplib import HTTPConnection, HTTPSConnection
8
8
from os.path import exists
 
9
from socket import gethostbyname, gaierror
9
10
from subprocess import Popen, PIPE
10
11
from sys import version_info
11
12
from urllib import getproxies_environment
18
19
    Resolver = None
19
20
 
20
21
import ibid
21
 
from ibid.plugins import Processor, match
 
22
from ibid.plugins import Processor, match, authorise
22
23
from ibid.config import Option, IntOption, FloatOption, DictOption
23
24
from ibid.utils import file_in_path, unicode_output, human_join, \
24
 
                       url_to_bytestring
 
25
                       url_to_bytestring, get_process_output
25
26
from ibid.utils.html import get_country_codes
26
27
 
27
28
help = {}
501
502
        else:
502
503
            event.addresponse(u"I don't know about any protocols using that port")
503
504
 
 
505
help['nmap'] = u'Finds open network ports on a host or scans a subnet for active hosts.'
 
506
class Nmap(Processor):
 
507
    """port scan <hostname>
 
508
    net scan <network>/<prefix>"""
 
509
 
 
510
    feature = 'nmap'
 
511
    permission = 'nmap'
 
512
    min_prefix = IntOption('min_prefix', 'Minimum network prefix that may be scanned', 24)
 
513
 
 
514
    def setup(self):
 
515
        if not file_in_path('nmap'):
 
516
            raise Exception("Cannot locate nmap executable")
 
517
 
 
518
    @match(r'^(?:port\s+scan|nmap)\s+([0-9a-z.-]+)$')
 
519
    @authorise()
 
520
    def host_scan(self, event, host):
 
521
        try:
 
522
            ip = gethostbyname(host)
 
523
        except gaierror, e:
 
524
            event.addresponse(unicode(e.args[1]))
 
525
            return
 
526
 
 
527
        if ip.startswith('127.'):
 
528
            event.addresponse(u"I'm not allowed to inspect my host's internal interface.")
 
529
            return
 
530
 
 
531
        output, error, code = get_process_output(['nmap', '--open', '-n', host])
 
532
 
 
533
        ports = []
 
534
        gotports = False
 
535
        for line in output.splitlines():
 
536
            if gotports:
 
537
                if not line.split():
 
538
                    break
 
539
                port, state, service = line.split()
 
540
                ports.append('%s (%s)' % (port, service))
 
541
            else:
 
542
                if line.startswith('Note: Host seems down.'):
 
543
                    event.addresponse(u'That host seems to be down')
 
544
                    return
 
545
                if line.startswith('PORT'):
 
546
                    gotports = True
 
547
 
 
548
        if ports:
 
549
            event.addresponse(human_join(ports))
 
550
        else:
 
551
            event.addresponse(u'No open ports detected')
 
552
 
 
553
    @match(r'^(?:net(?:work)?\s+scan|nmap)\s+((?:[0-9]{1,3}\.){3}[0-9]{1,3})/([0-9]{1,2})$')
 
554
    @authorise()
 
555
    def net_scan(self, event, network, prefix):
 
556
        if int(prefix) < self.min_prefix:
 
557
            event.addresponse(u"Sorry, I can't scan networks with a prefix less than %s", self.min_prefix)
 
558
            return
 
559
 
 
560
        output, error, code = get_process_output(['nmap', '-sP', '-n', '%s/%s' % (network, prefix)])
 
561
 
 
562
        hosts = []
 
563
        for line in output.splitlines():
 
564
            if line.startswith('Host '):
 
565
                hosts.append(line.split()[1])
 
566
 
 
567
        if hosts:
 
568
            event.addresponse(human_join(hosts))
 
569
        else:
 
570
            event.addresponse(u'No hosts responded to pings')
 
571
 
504
572
# vi: set et sta sw=4 ts=4: