예제 #1
0
 def __init__(self, irc):
     self.__parent = super(Ndoc, self)
     self.__parent.__init__(irc)
     self.ndir = self.registryValue('nmapDir')
     self.nbin = self.registryValue('nmapBin')
     self.nsrc = self.registryValue('nmapSrc')
     sys.path.append(os.path.join(self.nsrc,'ndiff'))
     from ndiff import Scan
     self.Scan = Scan
     sys.path.append(os.path.join(self.nsrc, 'zenmap'))
     from zenmapCore.ScriptMetadata import ScriptMetadata, get_script_entries
     from zenmapCore.NmapCommand import NmapCommand
     self.NmapCommand = NmapCommand
     from zenmapCore.NmapOptions import NmapOptions
     self.NmapOptions = NmapOptions
     from zenmapCore.UmitConf import PathsConfig
     paths = PathsConfig()
     paths.set_nmap_command_path(self.nbin)
     self.meta = dict( (e.filename, e) for e in get_script_entries(
         os.path.join(self.ndir, 'scripts'),
         os.path.join(self.ndir, 'nselib') )
     )
     self.libs = map(lambda x: os.path.basename(x).split('.')[0], glob.glob(os.path.join(self.ndir, 'nselib', '*.lua*')))
     if have_pytags:
         self.tags = EtagFile()
         self.tags.parse_from_file(os.path.join(self.nsrc, 'TAGS'))
     findproc = Popen("find . -type f \\( -name '*.c' -o -name '*.cc' -o -name '*.h' \\) -print0 | xargs -0 egrep -Hn " +
             "-e '(fatal|error) *\\(' " +
             "-e 'warn(ing)? *\\(' " +
             "-e 'fprintf *\\( *stderr' " +
             "-e '\\<(die|bye|loguser|report|printf) *\\(' ", cwd=self.ndir, shell=True, stdout=PIPE)
     errs, _ = findproc.communicate()
     self.errs = {}
     for line in errs.splitlines():
         m = reErr.match(line)
         if m:
             n = Node()
             n.file = m.group('file')
             n.line = m.group('line')
             n.text = m.group('text')
             for errstr in n.text.split('"')[1::2]: #simple string finder
                 if len(errstr) > 8 and reInteresting.match(errstr):
                     if errstr in self.errs:
                         self.errs[errstr].append(n)
                     else:
                         self.errs[errstr] = [n]
     #TODO: try-catch
     luaman = open(self.registryValue('luaManualTerms'),"r")
     self.luaterms = {}
     for term in map(string.strip, luaman):
         t = term.split("-")
         if t[0] == "pdf":
             self.luaterms[t[1]] = term
         else:
             self.luaterms[term] = term
     luaman.close()
     svnproc = Popen("svn info | awk '$1==\"Revision:\"{print $2}'", cwd=self.nsrc, shell=True, stdout=PIPE)
     self.svnrev, _ = svnproc.communicate()
     self.svnrev = self.svnrev.strip()
     self.lastload = datetime.utcnow()
예제 #2
0
class Ndoc(callbacks.Plugin):
    """Ask me about Nmap."""
    def __init__(self, irc):
        self.__parent = super(Ndoc, self)
        self.__parent.__init__(irc)
        self.ndir = self.registryValue('nmapDir')
        self.nbin = self.registryValue('nmapBin')
        self.nsrc = self.registryValue('nmapSrc')
        sys.path.append(os.path.join(self.nsrc,'ndiff'))
        from ndiff import Scan
        self.Scan = Scan
        sys.path.append(os.path.join(self.nsrc, 'zenmap'))
        from zenmapCore.ScriptMetadata import ScriptMetadata, get_script_entries
        from zenmapCore.NmapCommand import NmapCommand
        self.NmapCommand = NmapCommand
        from zenmapCore.NmapOptions import NmapOptions
        self.NmapOptions = NmapOptions
        from zenmapCore.UmitConf import PathsConfig
        paths = PathsConfig()
        paths.set_nmap_command_path(self.nbin)
        self.meta = dict( (e.filename, e) for e in get_script_entries(
            os.path.join(self.ndir, 'scripts'),
            os.path.join(self.ndir, 'nselib') )
        )
        self.libs = map(lambda x: os.path.basename(x).split('.')[0], glob.glob(os.path.join(self.ndir, 'nselib', '*.lua*')))
        if have_pytags:
            self.tags = EtagFile()
            self.tags.parse_from_file(os.path.join(self.nsrc, 'TAGS'))
        findproc = Popen("find . -type f \\( -name '*.c' -o -name '*.cc' -o -name '*.h' \\) -print0 | xargs -0 egrep -Hn " +
                "-e '(fatal|error) *\\(' " +
                "-e 'warn(ing)? *\\(' " +
                "-e 'fprintf *\\( *stderr' " +
                "-e '\\<(die|bye|loguser|report|printf) *\\(' ", cwd=self.ndir, shell=True, stdout=PIPE)
        errs, _ = findproc.communicate()
        self.errs = {}
        for line in errs.splitlines():
            m = reErr.match(line)
            if m:
                n = Node()
                n.file = m.group('file')
                n.line = m.group('line')
                n.text = m.group('text')
                for errstr in n.text.split('"')[1::2]: #simple string finder
                    if len(errstr) > 8 and reInteresting.match(errstr):
                        if errstr in self.errs:
                            self.errs[errstr].append(n)
                        else:
                            self.errs[errstr] = [n]
        try:
            luaman = open(self.registryValue('luaManualTerms'),"r")
            self.luaterms = {}
            for term in map(string.strip, luaman):
                t = term.split("-")
                if t[0] == "pdf":
                    self.luaterms[t[1]] = term
                else:
                    self.luaterms[term] = term
        except IOError as e:
            self.luaterms = False
        luaman.close()
        svnproc = Popen("svn info | awk '$1==\"Revision:\"{print $2}'", cwd=self.nsrc, shell=True, stdout=PIPE)
        self.svnrev, _ = svnproc.communicate()
        self.svnrev = self.svnrev.strip()
        self.lastload = datetime.utcnow()

    def luaterm(self, irc, msg, args, term):
        """<term>

        Returns a link to the Lua 5.3 manual section for <term>."""
        if not self.luaterms:
            irc.reply("Failed to load Lua 5.3 terms. http://www.lua.org/manual/5.3/manual.html")
            return

        if term in self.luaterms:
            irc.reply("http://www.lua.org/manual/5.3/manual.html#{0}".format(self.luaterms[term]))
        else:
            irc.reply("No such term in Lua 5.3 manual: http://www.lua.org/manual/5.3/manual.html")
    luaterm = wrap(luaterm, ['anything'])

    def description(self, irc, msg, args, script):
        """<script>

        Returns the description of a script"""
        m = reScript.match(script) 
        if m:
            script = "%s.nse" %( m.group('fname') )
            try:
                irc.reply(nsedoc_filter(self.meta[script].description))
            except KeyError:
                irc.reply("Script not found")
        else:
            irc.reply("Bad input")
    description = wrap(description, ['anything'])

    def author(self, irc, msg, args, script):
        """<script>

        Returns the author of a script"""
        m = reScript.match(script) 
        if m:
            script = "%s.nse" %( m.group('fname') )
            try:
                irc.replies(self.meta[script].author)
            except KeyError:
                irc.reply("Script not found")
        else:
            irc.reply("Bad input")
    author = wrap(author, ['anything'])

    def liblist(self, irc, msg, args):
        """

        Returns the list of NSE libraries."""
        irc.replies(self.libs)
    liblist = wrap(liblist, [])

    def rand(self, irc, msg, args):
        """

        Returns the description and URL of a random script."""
        script = random.choice(self.meta.keys())
        irc.reply(self.meta[script].url)
        irc.reply(nsedoc_filter(self.meta[script].description))
    rand = wrap(rand, [])

    def url(self, irc, msg, args, name):
        """<name>

        Returns a link to the NSEdoc page for <name>. <name> can be a script, library, or library.method."""
        m = re.match(r'(?P<libname>\w+)(?:\.(?P<method>\w+)[\(\)]{0,2})?$', name)
        if m and m.group('libname') in self.libs:
            link = "https://nmap.org/nsedoc/lib/%s.html#%s" %(m.group('libname'), m.group('method') or '')
            irc.reply( link )
        else:
            m = reScript.match(name)
            if m:
                script = "%s.nse" %( m.group('fname') )
                try:
                    irc.reply(self.meta[script].url)
                except KeyError:
                    irc.reply("Script not found")
            else:
                irc.reply("Bad input")
    url = wrap(url, ['anything'])

    def usage(self, irc, msg, args, script):
        """<script>

        Returns the usage of a script"""
        m = reScript.match(script) 
        if m:
            script = "%s.nse" %( m.group('fname') )
            try:
                for line in (self.meta[script].usage or "No usage available").split("\n"):
                    if not line:
                        continue
                    irc.reply( line )
            except KeyError:
                irc.reply("Script not found")
        else:
            irc.reply("Bad input")
    usage = wrap(usage, ['anything'])

    def categories(self, irc, msg, args, script):
        """<script>

        Returns the categories of a script"""
        m = reScript.match(script) 
        if m:
            script = "%s.nse" %( m.group('fname') )
            try:
                cat = ( self.meta[script].categories or ["No categories available"])
                irc.replies(cat)
            except KeyError:
                irc.reply("Script not found")
        else:
            irc.reply("Bad input")
    categories = wrap(categories, ['anything'])

    def requires(self, irc, msg, args, script):
        """<script>

        Returns the libraries that a script requires"""
        m = reScript.match(script) 
        if m:
            script = "%s.nse" %( m.group('fname') )
            if script in self.meta:
                req = ScriptMetadata.get_requires(os.path.join(self.ndir, 'scripts', script)) or ["No requires available"]
                irc.replies(req)
            else:
                irc.reply("Script not found")
        else:
            irc.reply("Bad input")
    requires = wrap(requires, ['anything'])

    def args(self, irc, msg, args, script, arg):
        """<script> [<arg>]

        Returns the --script-args that a script accepts. With <arg>, returns the description of <arg>."""
        m = reScript.match(script)
        if not m and "." in script and not arg:
            arg = script
            script = script.split(".")[0]
            m = reScript.match(script)
        if m:
            script = "%s.nse" %( m.group('fname') )
            try:
                args = ( self.meta[script].arguments or [["No script arguments available"]])
            except KeyError:
                irc.reply("Script not found")
                return
            if arg:
                for a in args:
                    if a[0] == arg:
                        irc.reply(nsedoc_filter(a[1] or "No description"))
            else:
                irc.replies(a[0] for a in args)
        else:
            irc.reply("Bad input")
    args = wrap(args, ['anything',optional('anything')])

    def expand(self, irc, msg, args, spec):
        """<spec>

        Returns the list of scripts that <spec> will attempt to run."""
        ops = self.NmapOptions()
        ops.executable = self.nbin
        ops["--script-help"] = spec
        ops["-oX"] = "-"
        command_string = ops.render_string()
        nmap_proc = self.NmapCommand(command_string)
        stderr = open("/dev/null", "w")
        try:
            nmap_proc.run_scan(stderr = stderr)
        except Exception, e:
            stderr.close()
            irc.reply("Failed to expand")
            return
        nmap_proc.command_process.wait()
        stderr.close()
        nmap_proc.stdout_file.seek(0)
        result = ScriptHelpXMLContentHandler.parse_nmap_script_help(nmap_proc.stdout_file)
        irc.replies(map(lambda f: reScript.search(f).group("fname"), result.script_filenames) or ["No scripts match"])