예제 #1
0
    def test_dir_exists(self):
        id, sample = self.add_task()
        task = Task()
        task.load_from_db(id)

        assert not task.dir_exists()
        os.mkdir(cwd(analysis=id))
        assert task.dir_exists()
예제 #2
0
def migrate_cwd():
    db = Database()
    log.warning(
        "This is the first time you're running Cuckoo after updating your "
        "local version of Cuckoo. We're going to update files in your CWD "
        "that require updating. Note that we'll first ensure that no custom "
        "patches have been applied by you before applying any modifications "
        "of our own.")

    # Remove now-obsolete index_*.yar files.
    for filename in os.listdir(cwd("yara")):
        if filename.startswith("index_") and filename.endswith(".yar"):
            os.remove(cwd("yara", filename))

    # Create new directories if not present yet.
    mkdir(cwd("stuff"))
    mkdir(cwd("yara", "office"))

    # Create the new $CWD/whitelist/ directory.
    if not os.path.exists(cwd("whitelist")):
        shutil.copytree(cwd("..", "data", "whitelist", private=True),
                        cwd("whitelist"))

    # Create the new $CWD/yara/dumpmem/ directory.
    if not os.path.exists(cwd("yara", "dumpmem")):
        mkdir(cwd("yara", "dumpmem"))

    hashes = {}
    for line in open(cwd("cwd", "hashes.txt", private=True), "rb"):
        if not line.strip() or line.startswith("#"):
            continue
        hash_, filename = line.split()
        hashes[filename] = hashes.get(filename, []) + [hash_]

    # We remove $CWD/monitor/latest upfront if it's a symbolic link, because
    # our migration code doesn't properly handle symbolic links.
    if os.path.islink(cwd("monitor", "latest")):
        os.remove(cwd("monitor", "latest"))

    modified, outdated, deleted = [], [], []
    for filename, hashes in hashes.items():
        if not os.path.exists(cwd(filename)):
            if hashes[-1] != "0" * 40:
                outdated.append(filename)
            continue
        hash_ = hashlib.sha1(open(cwd(filename), "rb").read()).hexdigest()
        if hash_ not in hashes:
            modified.append(filename)
        elif hashes[-1] == "0" * 40:
            deleted.append(filename)
        elif hash_ != hashes[-1]:
            outdated.append(filename)

    if modified:
        log.error(
            "One or more files in the CWD have been modified outside of "
            "regular Cuckoo usage. Due to these changes Cuckoo isn't able to "
            "automatically upgrade your setup.")

        for filename in sorted(modified):
            log.warning("Modified file: %s (=> %s)", filename, cwd(filename))

        log.error("Moving forward you have two options:")
        log.warning(
            "1) You make a backup of the affected files, remove their "
            "presence in the CWD (yes, actually 'rm -f' the file), and "
            "re-run Cuckoo to automatically restore the new version of the "
            "file. Afterwards you'll be able to re-apply any changes as you "
            "like.")
        log.warning(
            "2) You revert back to the version of Cuckoo you were on "
            "previously and accept that manual changes that have not been "
            "merged upstream require additional maintenance that you'll "
            "pick up at a later point in time.")

        sys.exit(1)

    for filename in sorted(deleted):
        log.debug("Deleted %s", filename)
        os.unlink(cwd(filename))

    for filename in sorted(outdated):
        filepath = cwd("..", "data", filename, private=True)
        if not os.path.exists(filepath):
            log.debug(
                "Failed to upgrade file not shipped with this release: %s",
                filename)
            continue

        log.debug("Upgraded %s", filename)
        if not os.path.exists(os.path.dirname(cwd(filename))):
            os.makedirs(os.path.dirname(cwd(filename)))
        shutil.copy(filepath, cwd(filename))

    log.info("Checking if any task directories are missing")
    for db_task in db.list_tasks(status=TASK_PENDING, details=False):
        task = Task(db_task)
        if not task.dir_exists():
            task.create_empty()
            for target in task.targets:
                if target.is_file and not os.path.exists(target.copied_binary):
                    target.copy()
        else:
            # Always call this so that missing (newly added) directories
            # are created
            task.create_dirs()

    log.info("Automated migration of your CWD was successful! Continuing "
             "execution of Cuckoo as expected.")