def pb_create(filename): # http://pastebin.com/faq#9 # 512kB limit per paste if fileutils.is_file(filename): with open(filename) as fo: pastedata = fo.read() if b64: pastedata = base64.b64encode(pastedata) res = apis.pastebin_create(pastedata) if res.success: return res.pasteurl return None
def __init__(self, configfile=None): # max bytes (within respective protocol buffers) to inspect self.MAX_INSPECT_UDP_DEPTH = 8192 self.MAX_INSPECT_CTS_DEPTH = 8192 self.MAX_INSPECT_STC_DEPTH = 8192 self.conf = utils.objdict({}) self.configfile = os.path.abspath(configfile) self.config = ConfigParser.SafeConfigParser() if configfile and fileutils.is_file(configfile): self.config.read(self.configfile)
def main(): session = utils.objdict({}) session.config = utils.objdict({}) session.config.configfile = None session.config.cuckooreport = None session.config.inputdir = None session.config.inputfiles = None session.config.interactive = None session.config.nobanner = None session.config.noribenreport = None session.config.reportsdir = None session.config.rescan = None session.config.serve = None session.config.supportedmimetypes = None session.config.verbose = None parser = argparse.ArgumentParser( description="Rudra - The destroyer of evil") parser.add_argument("-c", "--configfile", dest="configfile", action="store", default=None, help="custom config file (default: ./rudra.conf)") parser.add_argument("-f", "--inputfile", dest="inputfile", action="append", default=[], help="file to analyze") parser.add_argument("-d", "--inputdir", dest="inputdir", action="append", default=[], help="directory to analyze") parser.add_argument("-r", "--reportsdir", dest="reportsdir", action="store", default=None, help="custom reports directory (default: ./reports)") parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", default=False, help="invoke interactive mode") parser.add_argument("-b", "--nobanner", dest="nobanner", action="store_true", default=False, help="disable banner") parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False, help="enable verbose output") parser.add_argument("-D", "--reportsdirstruct", dest="reportsdirstruct", action="store_true", default=False, help="retain source-like reports directory structure") parser.add_argument("-R", "--rescan", dest="rescan", action="store_true", default=False, help="force rescan for input file") parser.add_argument("-C", "--cuckooreport", dest="cuckooreport", action="store", default=None, help="cuckoo json report for input file") parser.add_argument("-N", "--noribenreport", dest="noribenreport", action="store", default=None, help="noriben csv report for input file") args = parser.parse_args() # set user preferred file as config file # or use default config file # and read config options from it if args.configfile: configfile = args.configfile else: configfile = "./rudra.conf" configobj = config.Config(configfile) session.config = utils.objdict(configobj.read_as_dict()) if len(args.inputfile) > 0: session.config.inputfiles = [] if len(args.inputfile) > 1: for f in args.inputfile: if fileutils.is_file(f): session.config.inputfiles.append(f) else: utils.error("%s is not a file!" % f) else: session.config.inputfiles = args.inputfile if len(args.inputdir) > 0: session.config.inputfiles = [] for directory in args.inputdir: if fileutils.is_dir(directory): session.config.inputfiles += fileutils.file_list( directory, whitelist=session.config.supportedmimetypes) # set the reports dir if "reportsdir" not in session.config.keys(): session.config.reportsdir = False if args.reportsdir: session.config.reportsdir = args.reportsdir # enable interactive mode if "interactive" not in session.config.keys(): session.config.interactive = False if args.interactive: session.config.interactive = args.interactive # disable banner if requested if "nobanner" not in session.config.keys(): session.config.nobanner = False if args.nobanner: session.config.nobanner = args.nobanner # default config enables following message types: INFO, WARN and ERROR (program exits on an ERROR) # to enable DEBUG messages: activate verbosity if "verbose" not in session.config.keys(): session.config.verbose = False if args.verbose: session.config.verbose = args.verbose # force rescan for input file if "reportsdirstruct" not in session.config.keys(): session.config.reportsdirstruct = False if args.reportsdirstruct: session.config.reportsdirstruct = args.reportsdirstruct # force rescan for input file if "rescan" not in session.config.keys(): session.config.rescan = False if args.rescan: session.config.rescan = args.rescan # use arg as cuckoo report for input file if "cuckooreport" not in session.config.keys(): session.config.cuckooreport = None if args.cuckooreport and not args.inputdir: session.config.cuckooreport = args.cuckooreport # use arg as noriben report for input file if "noribenreport" not in session.config.keys(): session.config.noribenreport = None if args.noribenreport and not args.inputdir: session.config.noribenreport = args.noribenreport r = rudra.Rudra(session=session)
def analyze(self, filename): if not fileutils.is_file(filename): utils.warn("%s is not a file." % filename) return timing = utils.objdict({}) timing.starttime = time.time() self.session.config.reportsdir = "%s/%s/" % ( self.session.config.basereportsdir, fileutils.file_hashes(filename, "sha256")) print "Starting analysis on %s @ %s" % ( filename, utils.time_to_local_string(timing.starttime)) ## refrain scanning a file more than once ## include db checks and ensure config similarity ## or check if the report file already exists in reports directory ## populate these after syncing with db self.session.report.misc = utils.objdict({}) #self.session.report.misc.firstseen = utils.current_datetime_string() #self.session.report.misc.lastseen = utils.current_datetime_string() filesize = fileutils.file_size(filename) if self.session.config.statsfilesizelimit == 0 or filesize <= self.session.config.statsfilesizelimit: # limit is equal to 0 or filesize is lesser than limit # all good, keep going pass else: utils.info( "Disabling entropy compression stats calculation and file visualization (filesize: %d, statsfilesizelimit: %d)" % (filesize, self.session.config.statsfilesizelimit)) self.session.config.enableentropycompressionstats = False self.session.config.enablefilevisualization = False if not self.session.config.enablegeoloc: # if geodata lookup is disabled # map cannot be shown, so disable it explicitly self.session.config.enablegooglemaps = False utils.info( "Geolocation is disabled in config and as such Google Maps layout is being auto-disabled" ) # initialize filemeta specific classes and call analysis methods utils.info( "Invoking filemeta module for type identification and metadata collection" ) filemeta = FileMeta(filename=filename, config=self.session.config) if filemeta: filemeta.analyze() self.session.report.meta = filemeta.report if not self.session.config.enableentropycompressionstats: self.session.report.meta.filesize = filesize else: self.session.report.meta = None if filemeta and self.session.report.meta and self.session.report.meta.filemimetype == "application/vnd.tcpdump.pcap": if self.session.config.enablepcap: utils.info( "Invoking pcapanalysis module for host identification, dns/http/ftp/smtp/pop3/imap probing and flow inspection" ) pcapid = PCAPAnalysis(filename=filename, config=self.session.config) if pcapid: pcapid.analyze() self.session.report.pcap = pcapid.report else: self.session.report.pcap = None else: self.session.report.pcap = None elif filemeta and self.session.report.meta and self.session.report.meta.filemimetype == "application/x-dosexec": if self.session.config.enablepe: utils.info( "Invoking peanalysis module for scanning file and identifying threat indicators" ) pea = PEAnalysis(filename=filename, config=self.session.config) if pea: pea.analyze() self.session.report.pe = pea.report else: self.session.report.pe = None else: self.session.report.pe = None timing.endtime = time.time() timing.elapsedtime = timing.endtime - timing.starttime self.session.report.misc.config = self.session.config self.save() print "Completed analysis on %s @ %s (Elapsed: %s)" % ( filename, utils.time_to_local_string( timing.endtime), utils.elapsed_time_string(timing.elapsedtime))
def already_scanned(self, filesha2): if fileutils.is_file("%s/%s.json" % (self.session.config.currreportpath, self.session.config.currreportfile)): return True return False