Example #1
0
def visualize_file(infile):
    filename = utils.remove_extension(utils.filename(infile))
    infilerd = "%s/%s" % (config["reportsdir"], filename)
    utils.mkdirp(infilerd)

    print "[byteview] visualizing %s:" % (infile)
    print "  reportsdir: %s" % (infilerd)
    print "  curvemap: %s" % (", ".join(config["scurve"]["curvemap"]))
    print "  curvetype: %s" % (", ".join(config["scurve"]["curvetype"]))
    print "  curvecolor: %s" % (", ".join(config["scurve"]["curvecolor"]))
    return scurve(infile=infile,
                  reportsdir=infilerd,
                  curvemap=config["scurve"]["curvemap"],
                  curvetype=config["scurve"]["curvetype"],
                  curvecolor=config["scurve"]["curvecolor"],
                  pngsize=config["scurve"]["pngsize"],
                  showprogress=config["scurve"]["showprogress"],
                  byteviewanimate=config["scurve"]["byteviewanimate"])
Example #2
0
  def create(self):
    self.summary["input"] = {}
    self.summary["views"] = {}
    self.summary["config"] = config

    utils.mkdirp(config["reportsdir"])

    if self.args.inputdir and utils.is_dir(self.args.inputdir):
      self.summary["input"]["virfiles"] = utils.file_list(self.args.inputdir, pattern="*.vir")
      self.summary["input"]["reportjson"] = utils.file_list(self.args.inputdir, pattern="*report.json")
      self.summary["input"]["behaviorjson"] = utils.file_list(self.args.inputdir, pattern="*behavior.json")

      if not len(self.summary["input"]["virfiles"]) and not len(self.summary["input"]["reportjson"]) and not len(self.summary["input"]["behaviorjson"]):
        print "[-] could not find *.vir, *report.json and *.behavior.json files in %s. cannot proceed further" % (self.summary["input"]["directory"])
        sys.exit(1)

      # extract static and behavior data from vt report
      filereport = utils.file_json_open(self.summary["input"]["reportjson"][0])
      self.summary["vtdata"] = {
        "sha256": filereport["sha256"],
        "packer": filereport["additional_info"]["peid"] if "additional_info" in filereport and "peid" in filereport["additional_info"] else None,
        "av": {
          "bitdefender": filereport["scans"]["BitDefender"]["result"],
          "kaspersky": filereport["scans"]["Kaspersky"]["result"],
          "microsoft": filereport["scans"]["Microsoft"]["result"],
          "symantec": filereport["scans"]["Symantec"]["result"],
        },
        "imphash": filereport["additional_info"]["pe-imphash"],
        "ssdeep": filereport["ssdeep"],
        "magic": filereport["additional_info"]["magic"] if "additional_info" in filereport and "magic" in filereport["additional_info"] else None,
      }

      self.summary["views"]["file"] = hilbertviews.visualize_file(self.summary["input"]["virfiles"][0])
      byteviewb64data = utils.file_to_base64(self.summary["views"]["file"]["fileview"][0]) if self.summary["views"]["file"]["fileview"] and len(self.summary["views"]["file"]["fileview"]) and self.summary["views"]["file"]["fileview"][0] else ""
      print

      self.summary["views"]["imports"] = hilbertviews.visualize_imports(self.summary["input"]["virfiles"][0])
      iatviewb64data = utils.file_to_base64(self.summary["views"]["imports"]["importsview"][0]) if self.summary["views"]["imports"]["importsview"] and len(self.summary["views"]["imports"]["importsview"]) and self.summary["views"]["imports"]["importsview"][0] else ""
      print

      self.summary["views"]["behavior"] = hilbertviews.visualize_behavior(self.summary["input"]["behaviorjson"][0])
      behaviorviewb64data = utils.file_to_base64(self.summary["views"]["behavior"]["behaviorview"][0]) if self.summary["views"]["behavior"]["behaviorview"] and len(self.summary["views"]["behavior"]["behaviorview"]) and self.summary["views"]["behavior"]["behaviorview"][0] else ""
      print

      filename = utils.remove_extension(utils.filename(self.summary["input"]["virfiles"][0]))
      self.summary["config"]["directory"] = "%s/%s" % (config["reportsdir"], filename)
      utils.mkdirp(self.summary["config"]["directory"])
      report = config["htmltemplate"].replace("{{datadir}}", config["datadir"]).replace("{{reportdir}}", self.summary["config"]["directory"]).replace("{{sha256}}", filename).replace("{{square.entropy.png}}", iatviewb64data).replace("{{iv.png}}", iatviewb64data).replace("{{bv.png}}", behaviorviewb64data)

      if not len(self.summary["views"]["behavior"]["config"]["behaviorapis"]):
        self.summary["views"]["behavior"]["config"]["cvector"] = None

      # use cvectors from import views to search for similar reports in db
      self.summary["importclusters"] = self.cluster(key="imports")
      print

      # use cvectors from behavior views to search for similar reports in db
      self.summary["behaviorclusters"] = self.cluster(key="behavior")
      print

      self.summary["config"]["scantime"] = utils.get_epoch()
      self.summary["config"]["scantimehuman"] = utils.format_epoch(self.summary["config"]["scantime"])

      self.summary["config"]["reporthtml"] = "%s/report.html" % (self.summary["config"]["directory"])
      utils.file_save(filename=self.summary["config"]["reporthtml"], data=report)
      print "[+] saved %s" % (self.summary["config"]["reporthtml"])

      self.summary["config"]["summaryjson"] = "%s/summary.json" % (self.summary["config"]["directory"])
      utils.file_json_save(filename=self.summary["config"]["summaryjson"], data=self.summary)
      print "[+] saved %s" % (self.summary["config"]["summaryjson"])

      print
      return self
Example #3
0
def visualize_behavior(infile):
    status = {}
    status["config"] = {}
    status["config"]["infile"] = infile
    filename = utils.remove_extension(
        utils.filename(status["config"]["infile"])).replace(".behavior", "")
    infilerd = "%s/%s" % (config["reportsdir"], filename)
    utils.mkdirp(infilerd)
    winapivector = config["apiscout"]["winapivector"]
    apivector = ApiVector.ApiVector(winapivector)
    apiqr = ApiQR(winapivector)
    status["config"]["currapilist"] = []
    report = utils.file_json_open(infile)
    regexes = [
        re.compile("A$"),
        re.compile("ExA$"),
        re.compile("Ex$"),
        re.compile("ExW$"),
        re.compile("W$")
    ]
    try:
        for proc in report["results"]["behavior"]["processes"]:
            for call in proc["calls"]:
                api = call["api"]
                for regex in regexes:
                    api = regex.sub("", api)
                status["config"]["currapilist"].append(api)
        status["config"]["currapilist"] = list(
            set(status["config"]["currapilist"]))
    except:
        status["config"]["currapilist"] = []
    status["behaviorview"] = []
    status["config"]["behaviorapis"], defaultvector = [], [0] * 1024
    for winapi in utils.file_to_list(config["apiscout"]["winapivector"]):
        for api in status["config"]["currapilist"]:
            if "!%s;" % (api) in winapi:
                status["config"]["behaviorapis"].append(winapi)
                index = int(winapi.split(";")[-1])
                defaultvector[index] = 1
    status["config"]["behaviorapis"] = list(
        set(status["config"]["behaviorapis"]))
    status["config"]["cvector"] = apivector.compress(defaultvector)
    print "[behaviorview] visualizing %s:" % (infile)
    print "  reportsdir: %s" % (infilerd)
    print "  importsvector: %s" % (winapivector)
    print "  cvector: %s" % (status["config"]["cvector"])
    print "  behaviorapis: %d" % (sum(defaultvector))
    status["behaviorview"] += apiscout(
        infile=infile,
        outfile="%s/%s.bv" % (infilerd, filename),
        apiqr=apiqr,
        apivector=apivector,
        defaultvector=defaultvector,
        exporthtml=config["scurve"]["exporthtml"])
    if config["scurve"]["behaviorviewanimate"]:
        chunks = utils.chunkify(status["config"]["currapilist"],
                                config["biviewblocksize"])
        outfiles = []
        for idx, chunk in enumerate(chunks):
            status["config"]["behaviorapis"], defaultvector = [], [0] * 1024
            for winapi in utils.file_to_list(
                    config["apiscout"]["winapivector"]):
                for api in chunk:
                    if "!%s;" % (api) in winapi:
                        status["config"]["behaviorapis"].append(winapi)
                        index = int(winapi.split(";")[-1])
                        defaultvector[index] = 1
            status["config"]["behaviorapis"] = list(
                set(status["config"]["behaviorapis"]))
            status["config"]["cvector"] = apivector.compress(defaultvector)
            outfiles.append("%s/%s.bv.%d.png" % (infilerd, filename, idx))
            print "  cvector: %s" % (status["config"]["cvector"])
            print "  behaviorapis: %d" % (sum(defaultvector))
            apiscout(infile=infile,
                     outfile="%s/%s.bv.%d" % (infilerd, filename, idx),
                     apiqr=apiqr,
                     apivector=apivector,
                     defaultvector=defaultvector,
                     exporthtml=config["scurve"]["exporthtml"])
        giffile = "%s/%s.bv.gif" % (infilerd, filename)
        cli = "convert -delay 3 %s gif:- | gifsicle --delay=%d --loop --optimize=2 --colors=256 --multifile - >%s 2>/dev/null" % (
            " ".join(outfiles), config["gifdelay"]
            if config["gifdelay"] and config["gifdelay"] >= 10
            and config["gifdelay"] <= 100 else 100, giffile)
        os.system(cli)
        print "  created gif %s for mode behaviorview" % (giffile)
        utils.remove_files(outfiles)
        status["behaviorview"].append(giffile)
    return status
Example #4
0
def scurve(infile,
           reportsdir,
           curvemap=["hilbert"],
           curvetype=["square", "unrolled"],
           curvecolor=["entropy", "hilbert", "gradient"],
           pngsize=256,
           showprogress=False,
           byteviewanimate=True):
    status = {}
    status["config"] = {}
    status["config"]["infile"] = infile
    status["config"]["reportsdir"] = reportsdir
    status["config"]["curvemap"] = curvemap
    status["config"]["curvetype"] = curvetype
    status["config"]["curvecolor"] = curvecolor
    status["config"]["pngsize"] = pngsize
    status["config"]["showprogress"] = showprogress
    status["config"]["byteviewanimate"] = byteviewanimate
    status["config"]["filename"] = utils.remove_extension(
        utils.filename(infile))
    utils.mkdirp(status["config"]["reportsdir"])
    data = file(infile).read()
    status["config"]["filesize"] = len(data)
    status["fileview"] = []
    print "  mode: fileview (%d bytes)" % (status["config"]["filesize"])
    for ctidx, ct in enumerate(curvetype):
        for ccidx, cc in enumerate(curvecolor):
            if cc == "entropy":
                csource = binvis.ColorEntropy(data, None)
            elif cc == "hilbert":
                csource = binvis.ColorHilbert(data, None)
            elif cc == "gradient":
                csource = binvis.ColorGradient(data, None)
            else:
                csource = binvis.ColorHilbert(data, None)
            pngfilename = "%s/%s.%s.%s.png" % (status["config"]["reportsdir"],
                                               status["config"]["filename"],
                                               ct, cc)
            status["fileview"].append(pngfilename)
            print "  [%d/%d] %s" % (ccidx + 1, ctidx + 1, pngfilename)
            if ct == "unrolled":
                binvis.drawmap_unrolled(
                    curvemap[0], pngsize, csource, pngfilename,
                    progress.Progress(None)
                    if showprogress else progress.Dummy())
            if ct == "square":
                binvis.drawmap_square(
                    curvemap[0], pngsize, csource, pngfilename,
                    progress.Progress(None)
                    if showprogress else progress.Dummy())
    if status["config"]["byteviewanimate"]:
        utils.mkdirp(status["config"]["reportsdir"])
        chunks = utils.chunkify(data, config["byteviewblocksize"])
        status["byteviewanimate"] = []
        print "  mode: blockdata (%d bytes ~= %d chunks)" % (
            status["config"]["filesize"], len(chunks))
        for ctidx, ct in enumerate(curvetype):
            for ccidx, cc in enumerate(curvecolor):
                outfiles = []
                for idx, chunk in enumerate(chunks):
                    if cc == "entropy":
                        csource = binvis.ColorEntropy(chunks[idx], None)
                    elif cc == "hilbert":
                        csource = binvis.ColorHilbert(chunks[idx], None)
                    elif cc == "gradient":
                        csource = binvis.ColorGradient(chunks[idx], None)
                    else:
                        csource = binvis.ColorHilbert(chunks[idx], None)
                    pngfilename = "%s/%s.%s.%s.%d.png" % (
                        status["config"]["reportsdir"],
                        status["config"]["filename"], ct, cc, idx)
                    outfiles.append(pngfilename)
                    print "  [%d/%d] %s" % (ccidx + 1, ctidx + 1, pngfilename)
                    if ct == "unrolled":
                        binvis.drawmap_unrolled(
                            curvemap[0], pngsize, csource, pngfilename,
                            progress.Progress(None)
                            if showprogress else progress.Dummy())
                    if ct == "square":
                        binvis.drawmap_square(
                            curvemap[0], pngsize, csource, pngfilename,
                            progress.Progress(None)
                            if showprogress else progress.Dummy())
                giffile = "%s/%s.%s.%s.gif" % (status["config"]["reportsdir"],
                                               status["config"]["filename"],
                                               ct, cc)
                cli = "convert -delay 3 %s gif:- | gifsicle --delay=%d --loop --optimize=2 --colors=256 --multifile - >%s 2>/dev/null" % (
                    " ".join(outfiles), config["gifdelay"]
                    if config["gifdelay"] and config["gifdelay"] >= 10
                    and config["gifdelay"] <= 100 else 100, giffile)
                os.system(cli)
                print "  created gif %s for curvetype %s and curvecolor %s" % (
                    giffile, ct, cc)
                utils.remove_files(outfiles)
                status["byteviewanimate"].append(giffile)
    return status
Example #5
0
def visualize_imports(infile):
    status = {}
    status["config"] = {}
    status["config"]["infile"] = infile
    filename = utils.remove_extension(
        utils.filename(status["config"]["infile"]))
    infilerd = "%s/%s" % (config["reportsdir"], filename)
    utils.mkdirp(infilerd)
    winapivector = config["apiscout"]["winapivector"]
    apivector = ApiVector.ApiVector(winapivector)
    apiqr = ApiQR(winapivector)
    try:
        pe = pefile.PE(status["config"]["infile"])
        pe.parse_data_directories()
        status["config"]["currapilist"] = []
        regexes = [
            re.compile("A$"),
            re.compile("ExA$"),
            re.compile("Ex$"),
            re.compile("ExW$"),
            re.compile("W$")
        ]
        for entry in pe.DIRECTORY_ENTRY_IMPORT:
            for imp in entry.imports:
                if imp.name:
                    api = imp.name
                    for regex in regexes:
                        api = regex.sub("", api)
                    status["config"]["currapilist"].append(api)
        status["config"]["currapilist"] = list(
            set(status["config"]["currapilist"]))
    except:
        status["config"]["currapilist"] = []
    status["importsview"] = []
    status["config"]["importapis"], defaultvector = [], [0] * 1024
    for winapi in utils.file_to_list(config["apiscout"]["winapivector"]):
        for api in status["config"]["currapilist"]:
            if "!%s;" % (api) in winapi:
                status["config"]["importapis"].append(winapi)
                index = int(winapi.split(";")[-1])
                defaultvector[index] = 1
    status["config"]["importapis"] = list(set(status["config"]["importapis"]))
    status["config"]["cvector"] = apivector.compress(defaultvector)
    print "[iatview] visualizing %s:" % (status["config"]["infile"])
    print "  reportsdir: %s" % (infilerd)
    print "  importsvector: %s" % (winapivector)
    print "  cvector: %s" % (status["config"]["cvector"])
    print "  importapis: %d" % (sum(defaultvector))
    status["importsview"] += apiscout(
        infile=status["config"]["infile"],
        outfile="%s/%s.iv" % (infilerd, filename),
        apiqr=apiqr,
        apivector=apivector,
        defaultvector=defaultvector,
        exporthtml=config["scurve"]["exporthtml"])
    if config["scurve"]["iatviewanimate"]:
        chunks = utils.chunkify(status["config"]["currapilist"],
                                config["biviewblocksize"])
        outfiles = []
        for idx, chunk in enumerate(chunks):
            status["config"]["importapis"], defaultvector = [], [0] * 1024
            for winapi in utils.file_to_list(
                    config["apiscout"]["winapivector"]):
                for api in chunk:
                    if "!%s;" % (api) in winapi:
                        status["config"]["importapis"].append(winapi)
                        index = int(winapi.split(";")[-1])
                        defaultvector[index] = 1
            status["config"]["importapis"] = list(
                set(status["config"]["importapis"]))
            status["config"]["cvector"] = apivector.compress(defaultvector)
            outfiles.append("%s/%s.iv.%d.png" % (infilerd, filename, idx))
            print "  cvector: %s" % (status["config"]["cvector"])
            print "  importapis: %d" % (sum(defaultvector))
            outfiles += apiscout(infile=status["config"]["infile"],
                                 outfile="%s/%s.iv.%d" %
                                 (infilerd, filename, idx),
                                 apiqr=apiqr,
                                 apivector=apivector,
                                 defaultvector=defaultvector,
                                 exporthtml=config["scurve"]["exporthtml"])
        giffile = "%s/%s.iv.gif" % (infilerd, filename)
        cli = "convert -delay 3 %s gif:- | gifsicle --delay=%d --loop --optimize=2 --colors=256 --multifile - >%s 2>/dev/null" % (
            " ".join(outfiles), config["gifdelay"]
            if config["gifdelay"] and config["gifdelay"] >= 10
            and config["gifdelay"] <= 100 else 100, giffile)
        os.system(cli)
        print "  created gif %s for mode iatview" % (giffile)
        utils.remove_files(outfiles)
        status["importsview"].append(giffile)
    return status