Beispiel #1
0
    def start(self):
        if not self.do_run:
            return
        try:
            self.executable.append(self.file_path)
            if isinstance(self.pre_script_args_list, list):
                for args in self.pre_script_args_list:
                    self.executable.append(args)
            else:
                self.executable.append(self.pre_script_args_list)
            log.info("Pre_script command: %s", " ".join(self.executable))
            p = subprocess.check_output(self.executable,
                                        timeout=self.timeout,
                                        stderr=subprocess.STDOUT)

            nf = NetlogFile()
            nf.init("logs/pre_script.log")
            nf.sock.send(p)
            nf.close()
            log.info(
                "Successfully ran pre_script, saved output to logs/pre_script.logs"
            )
            return True
        except subprocess.CalledProcessError as e:
            log.error("Error, return code: %s", e.returncode)
            log.error("Error, Process stdout: %s", e.output)
        except Exception as e:
            log.error("Error running pre_script due to error: %s", e)
            return False
Beispiel #2
0
    def start(self):
        if not self.do_run:
            return
        try:
            nf = NetlogFile()
            nf.init("logs/during_script.log")
            self.executable.append(self.file_path)
            if isinstance(self.during_script_args_list, list):
                for args in self.during_script_args_list:
                    self.executable.append(args)
            else:
                self.executable.append(self.during_script_args_list)
            log.info("During_script command: %s", " ".join(self.executable))
            popen = subprocess.Popen(self.executable,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     universal_newlines=True)

            for stdout_line in iter(popen.stdout.readline, ""):
                nf.sock.send(stdout_line.encode())
            popen.stdout.close()
            nf.close()
            return_code = popen.wait()
            log.info(
                "Running during_script, saved output to logs/during_script.logs"
            )
            if return_code:
                log.error("Process stderr: %s", popen.stderr)
                raise subprocess.CalledProcessError(return_code,
                                                    str(self.executable))
        except Exception as e:
            log.error("Error running during_script due to error: %s", e)
            return False
        return True
Beispiel #3
0
def test_netlogfile_init(p):
    nf = NetlogFile()
    nf.init(u"dump-\u202e.exe")
    nf.sock = None
    nf.init(u"dump-\u202e.exe", u"file-\u202e.exe")
    a, b = p.return_value.sendall.call_args_list
    assert a[0][0] == str(a[0][0])
    assert b[0][0] == str(b[0][0])
Beispiel #4
0
def test_netlogfile_init(p):
    nf = NetlogFile()
    nf.init(u"dump-\u202e.exe")
    nf.sock = None
    nf.init(u"dump-\u202e.exe", u"file-\u202e.exe")
    a, b = p.return_value.sendall.call_args_list
    assert a[0][0] == str(a[0][0])
    assert b[0][0] == str(b[0][0])
Beispiel #5
0
    def dump_memory_block(self, addr, length):
        """Dump process memory.
        @return: operation status.
        """
        if not self.pid:
            log.warning("No valid pid specified, memory dump aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %d is not alive, memory "
                        "dump aborted", self.pid)
            return False

        self.get_system_info()

        page_size = self.system_info.dwPageSize
        if length < page_size:
            length = page_size

        # Now upload to host from the StringIO.
        idx = self.dumpmem[self.pid] = self.dumpmem.get(self.pid, 0) + 1
        file_name = os.path.join("memory", "block-%s-%s-%s.dmp" % (self.pid, hex(addr), idx))

        process_handle = self.open_process()
        mbi = MEMORY_BASIC_INFORMATION()

        if KERNEL32.VirtualQueryEx(process_handle,
                                   addr,
                                   byref(mbi),
                                   sizeof(mbi)) == 0:
            log.warning("Couldn't obtain MEM_BASIC_INFO for pid %d address %s", self.pid, hex(addr))
            return False

        # override request with the full mem region attributes
        addr = mbi.BaseAddress
        length = mbi.RegionSize

        count = c_ulong(0)
        try:
            buf = create_string_buffer(length)
            if KERNEL32.ReadProcessMemory(process_handle, addr, buf, length, byref(count)):
                header = struct.pack("QIIII", addr, length, mbi.State, mbi.Type, mbi.Protect)
                nf = NetlogFile()
                nf.init(file_name)
                nf.sock.sendall(header)
                nf.sock.sendall(buf.raw)
                nf.close()
            else:
                log.warning("ReadProcessMemory failed on process_handle %r addr %s length %s", process_handle, hex(addr), hex(length))
        except:
            log.exception("ReadProcessMemory exception on process_handle %r addr %s length %s", process_handle, hex(addr), hex(length))

        KERNEL32.CloseHandle(process_handle)

        log.info("Memory block dump of process with pid %d, addr %s, length %s completed", self.pid, hex(addr), hex(length))
        return True
Beispiel #6
0
    def run(self):
        """Run capturing of usage info.
        @return: operation status.
        """

        meminfo = MEMORYSTATUSEX()
        meminfo.dwLength = sizeof(MEMORYSTATUSEX)

        phquery = PVOID()
        PDH.PdhOpenQuery(None, None, byref(phquery))
        buflen = DWORD()
        buflen.value = 0
        PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time",
                                   None, byref(buflen), 0)
        buf = create_string_buffer(buflen.value + 1)
        PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time",
                                   buf, byref(buflen), 0)
        counters = buf.raw.rstrip(b"\x00").split(b"\x00")
        counter_handles = []
        for counter in counters:
            if b"_Total" in counter:
                continue
            phcounter = PVOID()
            PDH.PdhAddCounterA(phquery, counter, None, byref(phcounter))
            counter_handles.append(phcounter)

        nf = NetlogFile()
        nf.init("aux/usage.log")

        PDH.PdhCollectQueryData(phquery)

        while self.do_run:
            time.sleep(2)
            PDH.PdhCollectQueryData(phquery)
            usage = PDH_FMT_COUNTERVALUE()
            bigfloat = 0.0
            for counter_handle in counter_handles:
                PDH.PdhGetFormattedCounterValue(counter_handle, PDH_FMT_DOUBLE,
                                                None, byref(usage))
                if usage.doubleValue > bigfloat:
                    bigfloat = usage.doubleValue

            KERNEL32.GlobalMemoryStatusEx(byref(meminfo))
            usagedata = b"%d %d\n" % (meminfo.dwMemoryLoad, round(bigfloat))
            nf.send(usagedata)

        for counter_handle in counter_handles:
            PDH.PdhRemoveCounter(counter_handle)
        PDH.PdhCloseQuery(phquery)

        nf.close()

        return True
    def run(self):
        """Run screenshotting.
        @return: operation status.
        """
        if "screenshots" in self.options:
            self.do_run = int(self.options["screenshots"])

        scr = Screenshot()

        # TODO We should also send the action "pillow" so that the Web
        # Interface can adequately inform the user about this missing library.
        if not scr.have_pil():
            log.info(
                "Python Image Library (either PIL or Pillow) is not "
                "installed, screenshots are disabled."
            )
            return False

        img_counter = 0
        img_last = None

        while self.do_run:
            time.sleep(SHOT_DELAY)

            try:
                img_current = scr.take()
            except IOError as e:
                log.error("Cannot take screenshot: %s", e)
                continue

            if img_last and scr.equal(img_last, img_current, SKIP_AREA):
                continue

            img_counter += 1

            # workaround as PIL can't write to the socket file object :(
            tmpio = StringIO.StringIO()
            img_current.save(tmpio, format="JPEG")
            tmpio.seek(0)

            # now upload to host from the StringIO
            nf = NetlogFile()
            nf.init("shots/%04d.jpg" % img_counter)

            for chunk in tmpio:
                nf.sock.sendall(chunk)

            nf.close()

            img_last = img_current

        return True
Beispiel #8
0
    def stop(self):
        """Stop screenrecording"""
        # Stop the video
        self.src.stop()

        # TODO: taking video based on events
        try:
            with open(self.src.file, "rb") as f:
                nf = NetlogFile()
                nf.init("screenrecord/%s" % self.src.fname)
                nf.sock.sendall(f.read())
                nf.close()
        except Exception as e:
            log.debug("Screenrecord bug: %s", e)
Beispiel #9
0
    def run(self):
        """Run screenshotting.
        @return: operation status.
        """
        if "screenshots" in self.options:
            shot_delay = int(self.options["screenshots"])
            if shot_delay == 0: self.do_run = False
        else:
            shot_delay = 1

        if not Screenshot().have_pil():
            log.warning("Python Image Library is not installed, "
                        "screenshots are disabled")
            return False

        img_counter = 0
        img_last = None

        while self.do_run:
            time.sleep(shot_delay)

            try:
                img_current = Screenshot().take()
            except IOError as e:
                log.error("Cannot take screenshot: %s", e)
                continue

            if img_last:
                if Screenshot().equal(img_last, img_current, SKIP_AREA):
                    continue

            img_counter += 1

            # workaround as PIL can't write to the socket file object :(
            tmpio = StringIO.StringIO()
            img_current.save(tmpio, format="JPEG")
            tmpio.seek(0)

            # now upload to host from the StringIO
            nf = NetlogFile()
            nf.init("shots/%s.jpg" % str(img_counter).rjust(4, "0"))

            for chunk in tmpio:
                nf.sock.sendall(chunk)

            nf.close()

            img_last = img_current

        return True
Beispiel #10
0
    def run(self):
        """Run screenshotting.
        @return: operation status.
        """
        if "screenshots" in self.options:
            shot_delay = int(self.options["screenshots"])
            if shot_delay == 0: self.do_run = False
        else:
            shot_delay = 1

        if not Screenshot().have_pil():
            log.warning("Python Image Library is not installed, "
                        "screenshots are disabled")
            return False

        img_counter = 0
        img_last = None

        while self.do_run:
            time.sleep(shot_delay)

            try:
                img_current = Screenshot().take()
            except IOError as e:
                log.error("Cannot take screenshot: %s", e)
                continue

            if img_last:
                if Screenshot().equal(img_last, img_current, SKIP_AREA):
                    continue

            img_counter += 1

            # workaround as PIL can't write to the socket file object :(
            tmpio = StringIO.StringIO()
            img_current.save(tmpio, format="JPEG")
            tmpio.seek(0)

            # now upload to host from the StringIO
            nf = NetlogFile()
            nf.init("shots/%s.jpg" % str(img_counter).rjust(4, "0"))

            for chunk in tmpio:
                nf.sock.sendall(chunk)

            nf.close()

            img_last = img_current

        return True
Beispiel #11
0
    def stop(self):
        log.info("Collecting EMET events...")

        c = wmi.WMI(privileges=['Security'])
        for event in c._raw_query('SELECT * FROM Win32_NTLogEvent'):
            if event.SourceName == "EMET":
               #https://msdn.microsoft.com/en-us/library/aa394226(v=vs.85).aspx maybe add more values?
          dadada.append([event.SourceName, event.Category, event.Type, event.ComputerName, event.User, event.Message])

        bleekscheet = "\n".join(str(x) for x in dadada)
        nf = NetlogFile()
        nf.init("logs/emet_events.log")
        nf.send(bleekscheet)
        nf.close()
        return True
Beispiel #12
0
    def run(self):
        """Run screenshotting.
        @return: operation status.
        """
        if not self.enabled:
            return False

        if not Screenshot().have_pil():
            log.warning(
                "Python Image Library is not installed, screenshots are disabled"
            )
            return False

        img_counter = 0
        img_last = None

        while self.do_run:
            time.sleep(SHOT_DELAY)

            try:
                img_current = Screenshot().take()
            except IOError as e:
                log.error("Cannot take screenshot: %s", e)
                continue

            if img_last:
                if Screenshot().equal(img_last, img_current, SKIP_AREA):
                    continue

            img_counter += 1
            # workaround as PIL can't write to the socket file object :(
            tmpio = BytesIO()
            img_current.save(tmpio, format="JPEG")
            tmpio.seek(0)

            # now upload to host from the StringIO
            nf = NetlogFile()
            nf.init(f"shots/{str(img_counter).rjust(4, '0')}.jpg")
            for chunk in tmpio:
                nf.sock.send(chunk)
            nf.close()
            img_last = img_current

        return True
Beispiel #13
0
    def start(self):
        if not self.enabled:
            return True

        try:
            if self.config.category != "file":
                log.debug("Skipping authenticode validation, analysis is not "
                          "a file.")
                return True

            sign_path = os.path.join(os.getcwd(), "bin", "signtool.exe")
            if not os.path.exists(sign_path):
                log.info("Skipping authenticode validation, signtool.exe was "
                         "not found in bin/")
                return True

            log.debug("Checking for a digitial signature.")
            file_path = os.path.join(os.environ["TEMP"] + os.sep,
                                     str(self.config.file_name))
            cmd = '{0} verify /pa /v "{1}"'.format(sign_path, file_path)
            ret, out, err = util.cmd_wrapper(cmd)
            out = out.decode(locale.getpreferredencoding(), errors="ignore")

            # Return was 0, authenticode certificate validated successfully
            if not ret:
                _ = self.parse_digisig(out)
                self.jsonify("Certificate Chain", self.cert_build)
                self.jsonify("Timestamp Chain", self.time_build)
                self.json_data["valid"] = True
                log.debug("File has a valid signature.")
            # Non-zero return, it didn't validate or exist
            else:
                self.json_data["error"] = True
                errmsg = b" ".join(b"".join(err.split(b":")[1:]).split())
                self.json_data["error_desc"] = errmsg.decode("utf-8")
                if b"file format cannot be verified" in err:
                    log.debug("File format not recognized.")
                elif b"No signature found" not in err:
                    log.debug("File has an invalid signature.")
                    _ = self.parse_digisig(out)
                    self.jsonify("Certificate Chain", self.cert_build)
                    self.jsonify("Timestamp Chain", self.time_build)
                else:
                    log.debug("File is not signed.")

            if self.json_data:
                log.info("Uploading signature results to aux/{0}.json".format(
                    self.__class__.__name__))
                upload = BytesIO()
                upload.write(json.dumps(self.json_data, ensure_ascii=False).encode("utf-8"))
                upload.seek(0)
                nf = NetlogFile()
                nf.init("aux/DigiSig.json")
                for chunk in upload:
                    nf.sock.send(chunk)
                nf.close()

        except Exception as e:
            print(e)
            import traceback
            log.exception(traceback.format_exc())

        return True
Beispiel #14
0
    def dump_memory_block(self, addr, length):
        """Dump process memory.
        @return: operation status.
        """
        if not self.pid:
            log.warning("No valid pid specified, memory dump aborted")
            return False

        if not self.is_alive():
            log.warning(
                "The process with pid %d is not alive, memory "
                "dump aborted", self.pid)
            return False

        self.get_system_info()

        page_size = self.system_info.dwPageSize
        if length < page_size:
            length = page_size

        # Now upload to host from the StringIO.
        idx = self.dumpmem[self.pid] = self.dumpmem.get(self.pid, 0) + 1
        file_name = os.path.join(
            "memory", "block-%s-%s-%s.dmp" % (self.pid, hex(addr), idx))

        process_handle = self.open_process()
        mbi = MEMORY_BASIC_INFORMATION()

        if KERNEL32.VirtualQueryEx(process_handle, addr, byref(mbi),
                                   sizeof(mbi)) == 0:
            log.warning("Couldn't obtain MEM_BASIC_INFO for pid %d address %s",
                        self.pid, hex(addr))
            return False

        # override request with the full mem region attributes
        addr = mbi.BaseAddress
        length = mbi.RegionSize

        count = c_ulong(0)
        try:
            buf = create_string_buffer(length)
            if KERNEL32.ReadProcessMemory(process_handle, addr, buf, length,
                                          byref(count)):
                header = struct.pack("QIIII", addr, length, mbi.State,
                                     mbi.Type, mbi.Protect)
                nf = NetlogFile()
                nf.init(file_name)
                nf.sock.sendall(header)
                nf.sock.sendall(buf.raw)
                nf.close()
            else:
                log.warning(
                    "ReadProcessMemory failed on process_handle %r addr %s length %s",
                    process_handle, hex(addr), hex(length))
        except:
            log.exception(
                "ReadProcessMemory exception on process_handle %r addr %s length %s",
                process_handle, hex(addr), hex(length))

        KERNEL32.CloseHandle(process_handle)

        log.info(
            "Memory block dump of process with pid %d, addr %s, length %s completed",
            self.pid, hex(addr), hex(length))
        return True