def test_add_multi_write_file_element(self, out_dir, data):
        store = forensicstore.new(out_dir + "/amcache.forensicstore")
        file_date = datetime.datetime(2014, 9, 11, 21, 50, 18, 301000)
        origin = {
            "path": "C:\\Windows\\appcompat\\Programs\\Amcache.hve",
            "volume": "2"
        }
        file = store.add_file_element("WindowsAMCacheHveFile", "Amcache.hve",
                                      file_date, file_date, file_date, origin,
                                      [])
        with store.add_file_element_export(file) as export:
            for _ in range(123):
                export.write(b'A')

        elements = store.all()
        first = list(elements).pop()

        del first["id"]
        assert first == EXAMPLE_FORENSICSTORE[2]

        with store.fs.open("/WindowsAMCacheHveFile/Amcache.hve", 'rb') as io:
            assert io.read() == 123 * b'A'

        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
Exemplo n.º 2
0
def test_import_image(tmp):
    return
    client = docker.from_env()

    # build image
    image_tag = "test_artifacts"
    image, _ = client.images.build(path="import-image/", tag=image_tag)

    store = forensicstore.new(os.path.join(tmp, "input.forensicstore"))
    store.close()

    # run image
    store_path = os.path.abspath(tmp)
    store_path_unix = to_unix_path(store_path)
    import_path = os.path.abspath(os.path.join(tmp, INPUT_IMAGE_SUBDIR))
    import_path_unix = to_unix_path(import_path)
    volumes = {
        store_path_unix: {
            'bind': '/input',
            'mode': 'rw'
        },
        import_path_unix: {
            'bind': '/input/' + INPUT_IMAGE_SUBDIR,
            'mode': 'ro'
        }
    }
    container = client.containers.run(
        image_tag,
        command=["--input-file", "win10_mock.vhd"],
        volumes=volumes,
        detach=True,
    )
    result = container.wait()
    out = container.logs()
    container.remove()
    print(out.decode("utf-8"))

    assert result["StatusCode"] == 0

    # test results
    store = forensicstore.open(os.path.join(store_path, "input.forensicstore"))
    items = list(store.all())
    store.close()

    # shutil.copyfile(os.path.join(store_path, "input.forensicstore"), "./input.forensicstore")
    assert len(items) == 1832

    # cleanup
    try:
        shutil.rmtree(tmp)
    except PermissionError:
        pass
    def test_insert_quotes(self, out_dir, data):
        store = forensicstore.new(out_dir + "/quotes.forensicstore")

        element_id = store.insert({"type": "any_type"})
        store.update(
            element_id,
            {"foo": '@"%ProgramFiles%\\Windows Journal\\Journal.exe",-3072'})

        assert store.get(element_id)[
            "foo"] == '@"%ProgramFiles%\\Windows Journal\\Journal.exe",-3072'

        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
    def test_add_directory_element(self, out_dir, data):
        store = forensicstore.new(out_dir + "/program_files.forensicstore")
        dir_date = datetime.datetime(2014, 9, 11, 21, 50, 18, 301000)
        store.add_directory_element("WindowsEnvironmentVariableProgramFiles",
                                    "C:\\Program Files", dir_date, dir_date,
                                    dir_date, [])
        elements = store.all()
        first = list(elements).pop()
        del first["id"]
        assert first == EXAMPLE_FORENSICSTORE[3]

        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
    def test_import_store(self, out_dir, data):
        import_store = forensicstore.new(out_dir + "/tmp.forensicstore")
        with import_store.store_file("testfile.txt") as (path, io):
            io.write(123 * b'A')
            import_store.insert({"type": "foo", "export_path": path})
        import_store.close()

        store = forensicstore.new(out_dir + "/amcache.forensicstore")
        with store.store_file("testfile.txt") as (path, io):
            io.write(123 * b'B')
            store.insert({"type": "foo", "export_path": path})

        store.import_forensicstore(out_dir + "/tmp.forensicstore")

        elements = store.all()
        assert len(list(elements)) == 2
        with store.fs.open("/testfile.txt", 'rb') as io:
            assert io.read() == 123 * b'B'
        with store.fs.open("/testfile_0.txt", 'rb') as io:
            assert io.read() == 123 * b'A'

        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
    def test_add_duplicate_file_element(self, out_dir, data):
        store = forensicstore.new(out_dir + "/amcache.forensicstore")
        file_date = datetime.datetime(2014, 9, 11, 21, 50, 18, 301000)
        origin = {
            "path": "C:\\Windows\\appcompat\\Programs\\Amcache.hve",
            "volume": "2"
        }
        file1 = store.add_file_element("WindowsAMCacheHveFile", "Amcache.hve",
                                       file_date, file_date, file_date, origin,
                                       [])
        with store.add_file_element_export(file1) as export:
            export.write(123 * b'A')

        file2 = store.add_file_element("WindowsAMCacheHveFile", "Amcache.hve",
                                       file_date, file_date, file_date, origin,
                                       [])
        with store.add_file_element_export(file2) as export:
            export.write(123 * b'B')

        file3 = store.add_file_element("WindowsAMCacheHveFile", "Amcache.hve",
                                       file_date, file_date, file_date, origin,
                                       [])
        with store.add_file_element_export(file3, "Amcache_b.hve") as export:
            export.write(123 * b'C')

        file4 = store.add_file_element("WindowsAMCacheHveFile", "Amcache.hve",
                                       file_date, file_date, file_date, origin,
                                       [])
        with store.add_file_element_export(file4, "Amcache_b.hve") as export:
            export.write(123 * b'D')

        first = store.get(file1)
        del first["id"]
        assert first == EXAMPLE_FORENSICSTORE[2]

        with store.fs.open("/WindowsAMCacheHveFile/Amcache.hve", 'rb') as io:
            assert io.read() == 123 * b'A'
        with store.fs.open("/WindowsAMCacheHveFile/Amcache_0.hve", 'rb') as io:
            assert io.read() == 123 * b'B'
        with store.fs.open("/WindowsAMCacheHveFile/Amcache_b.hve", 'rb') as io:
            assert io.read() == 123 * b'C'
        with store.fs.open("/WindowsAMCacheHveFile/Amcache_b_0.hve",
                           'rb') as io:
            assert io.read() == 123 * b'D'
        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
Exemplo n.º 7
0
def test_docker(tmp):
    client = docker.from_env()

    # build image
    image_tag = "test_artifacts"
    image, _ = client.images.build(path="import-image/", tag=image_tag)

    store = forensicstore.new(os.path.join(tmp, "input.forensicstore"))
    store.close()

    # run image
    store_path = os.path.abspath(tmp)
    store_path_unix = to_unix_path(store_path)
    import_path = os.path.abspath(os.path.join(tmp, "in"))
    import_path_unix = to_unix_path(import_path)
    volumes = {
        store_path_unix: {
            'bind': '/store',
            'mode': 'rw'
        },
        import_path_unix: {
            'bind': '/data',
            'mode': 'ro'
        }
    }
    out = client.containers.run(image_tag,
                                command=["input.forensicstore"],
                                volumes=volumes,
                                stderr=True).decode("ascii")
    # print(out)

    # test results
    store = forensicstore.open(os.path.join(store_path, "input.forensicstore"))
    items = list(store.all())
    store.close()

    shutil.copyfile(os.path.join(store_path, "input.forensicstore"),
                    "./input.forensicstore")
    # assert len(items) == 8

    # cleanup
    try:
        shutil.rmtree(tmp)
    except PermissionError:
        pass
    def test_add_registry_key_element(self, out_dir, data):
        store = forensicstore.new(out_dir + "/codepage.forensicstore")
        key_date = datetime.datetime(2009, 7, 14, 4, 34, 14, 225000)
        key = store.add_registry_key_element(
            "WindowsCodePage", key_date,
            "HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Nls\\CodePage",
            [])
        store.add_registry_value_element(key, "REG_SZ",
                                         "1252".encode("utf-16"), "ACP")

        elements = store.all()
        first = list(elements).pop()
        del first["id"]
        assert first == EXAMPLE_FORENSICSTORE[5]

        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
    def test_add_process_element(self, out_dir, data):
        store = forensicstore.new(out_dir + "/iptables.forensicstore")
        cmd_date = datetime.datetime(2016, 1, 20, 14, 11, 25, 550000)
        cmd = store.add_process_element("IPTablesRules", "iptables", cmd_date,
                                        "/root/", "/sbin/iptables -L -n -v", 0,
                                        [])
        with store.add_process_element_stdout(
                cmd) as stdout, store.add_process_element_stderr(
                    cmd) as stderr:
            stdout.write(b"foo")
            stderr.write(b"bar")

        elements = store.all()
        first = list(elements).pop()
        del first["id"]
        assert first == EXAMPLE_FORENSICSTORE[0]

        with store.fs.open("/IPTablesRules/stdout", 'rb') as io:
            assert io.read() == b"foo"
        with store.fs.open("/IPTablesRules/stderr", 'rb') as io:
            assert io.read() == b"bar"
        store.close()
        shutil.rmtree(out_dir)
        shutil.rmtree(data)
Exemplo n.º 10
0
def main():
    parser = argparse.ArgumentParser(
        prog="discoruns",
        description=
        "Extract persistence mechanisms from disc images or forensicstores.")

    parser.add_argument(
        '--format',
        help="Output format of the collected persistence mechanisms.",
        choices=['console', 'json'],
        dest='format',
        default="console")
    parser.add_argument("-v",
                        "--verbose",
                        help="Show logging messages.",
                        dest='verbose',
                        action="store_true",
                        default=False)

    subparsers = parser.add_subparsers(title="subcommands",
                                       dest="subcommand",
                                       required=True)

    parser_image = subparsers.add_parser('image')
    parser_image.add_argument(
        "image",
        metavar="IMAGE",
        help="Location of a disk image or a forensicstore.")

    parser_forensicstore = subparsers.add_parser('forensicstore')
    parser_forensicstore.add_argument("forensicstore",
                                      metavar="FORENSICSTORE",
                                      help="Location of a forensicstore.")

    args = parser.parse_args()

    if args.verbose:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)

    start_time = time.time()

    if args.subcommand == "image":
        if not os.path.exists(args.image):
            logger.error("Image does not exist!")
            sys.exit(1)

        fstore_full_path = f"{Path(args.image).stem}.forensicstore"

        # Create new store
        try:
            store = forensicstore.new(fstore_full_path)
            store.close()
        except forensicstore.forensicstore.StoreExitsError:
            logger.error("Forensicstore does allready exist!")
            sys.exit(1)

        # Start extraction
        logger.info("Collecting artifacts. This might take a while...")
        ArtifactCollectorWrapper(
            args.image, fstore_full_path,
            f"{os.path.join(os.path.dirname(os.path.abspath(__file__)), 'artifacts')}",
            "WindowsPersistence").collect_artifacts()

    elif args.subcommand == "forensicstore":
        if not os.path.exists(args.forensicstore):
            logger.error("Forensicstore does not exist!")
            sys.exit(1)

        logger.info("Using an existing forensicstore.")
        fstore_full_path = args.forensicstore

    collected_mechanisms = collect(fstore_full_path)

    if args.format == "json":
        print(json.dumps(collected_mechanisms, indent=4))
    else:
        print(tabulate.tabulate(collected_mechanisms))
        print()
        print("Total found entries: " + str(len(collected_mechanisms)))
        print("Execution time: %.4s seconds" % (time.time() - start_time))
Exemplo n.º 11
0
def main():
    root_parser = argparse.ArgumentParser(description='Handle forensicstores')
    root_subparsers = root_parser.add_subparsers(dest='root_command')
    root_subparsers.required = True

    create_parser = root_subparsers.add_parser("create")
    create_parser.add_argument('store')

    import_parser = root_subparsers.add_parser("import")
    import_parser.add_argument('url')
    import_parser.add_argument('store')

    validate_parser = root_subparsers.add_parser("validate")
    validate_parser.add_argument('store')
    validate_parser.add_argument('--no-fail',
                                 action='store_true',
                                 dest="nofail")

    element_parser = root_subparsers.add_parser("element")
    element_subparsers = element_parser.add_subparsers(dest='command')
    element_subparsers.required = True

    get_parser = element_subparsers.add_parser("get")
    get_parser.add_argument('id')
    get_parser.add_argument('store')

    select_parser = element_subparsers.add_parser("select")
    select_parser.add_argument('type')
    select_parser.add_argument('store')

    all_parser = element_subparsers.add_parser("all")
    all_parser.add_argument('store')

    insert_parser = element_subparsers.add_parser("insert")
    insert_parser.add_argument('json')
    insert_parser.add_argument('store')

    update_parser = element_subparsers.add_parser("update")
    update_parser.add_argument('id')
    update_parser.add_argument('json')
    update_parser.add_argument('store')

    args = root_parser.parse_args()

    if args.root_command == "create":
        store = forensicstore.new(args.store)
        store.close()
    elif args.root_command == "validate":
        store = forensicstore.open(args.store)
        errors = store.validate()
        if errors:
            print(json.dumps(errors))
        if args.nofail:
            sys.exit(0)
        sys.exit(len(errors))
    elif args.root_command == "element":
        if args.command == "get":
            store = forensicstore.open(args.store)
            element = store.get(args.id)
            print(json.dumps(element))
            store.close()
        elif args.command == "select":
            store = forensicstore.open(args.store)
            elements = list(store.select([{"type": args.type}]))
            print(json.dumps(elements))
            store.close()
        elif args.command == "all":
            store = forensicstore.open(args.store)
            elements = list(store.all())
            print(json.dumps(elements))
            store.close()
        elif args.command == "insert":
            store = forensicstore.open(args.store)
            element = store.insert(json.loads(args.json))
            print(json.dumps(element))
            store.close()
        elif args.command == "update":
            store = forensicstore.open(args.store)
            print(args.json)
            element = store.update(args.id, json.loads(args.json))
            print(json.dumps(element))
            store.close()
        else:
            NotImplementedError("Sub command %s does not exist" % args.command)
    else:
        NotImplementedError("Command %s does not exist" % args.root_command)
 def test_init_create(self, out_dir, data):
     store = forensicstore.new(out_dir + "/init_create.forensicstore")
     store.close()
     assert os.path.exists(out_dir + "/init_create.forensicstore")
     shutil.rmtree(out_dir)
     shutil.rmtree(data)