cuckoosandbox / cuckoo

Cuckoo Sandbox is an automated dynamic malware analysis system
http://www.cuckoosandbox.org
Other
5.57k stars 1.71k forks source link

Using 'cuckoo clean' will not remove any files that symlinks point to #3086

Open soutzis opened 4 years ago

soutzis commented 4 years ago

I am analysing a large number of binaries and so I created a symlink for the analyses directory. Everything works fine, but when using 'cuckoo clean', the function shutil.rmtree($CWD/storage/analyses/) will throw an Exception:

[cuckoo.apps.apps] WARNING: Error removing directory /home/user/.cuckoo/storage/analyses: Cannot call rmtree on a symbolic link

Cuckoo version and OS:

Cuckoo 2.0.7 & Ubuntu 18.04

This can be reproduced by:
  1. Create a soft link for a directory (e.g. 'analyses'): sudo ln -s /preferred_location/analyses/ /$CWD/storage/analyses
  2. Execute cuckoo clean
This can be easily fixed by:

One line of code. In the cuckoo_clean() function (located in the file cuckoo/cuckoo/apps/apps.py), there is a for-loop that deletes various files and directories:

# Delete the various files and directories. In case of directories, keep
# the parent directories, so to keep the state of the CWD in tact.
for path in paths:
    if os.path.isdir(path):
        try:
            shutil.rmtree(path)
            os.mkdir(path)
        except (IOError, OSError) as e:
            log.warning("Error removing directory %s: %s", path, e)
    elif os.path.isfile(path):
        try:
            os.unlink(path)
        except (IOError, OSError) as e:
            log.warning("Error removing file %s: %s", path, e)

Just before calling rmtree(), you could use os.path.realpath() to get the absolute path in case of a symlink. See below:

# Delete the various files and directories. In case of directories, keep
# the parent directories, so to keep the state of the CWD in tact.
for path in paths:
    if os.path.isdir(path):
        try:
            path = os.path.realpath(path)  # This gracefully handles cases with soft links!
            shutil.rmtree(path)
            os.mkdir(path)
        except (IOError, OSError) as e:
            log.warning("Error removing directory %s: %s", path, e)
    elif os.path.isfile(path):
        try:
            os.unlink(path)
        except (IOError, OSError) as e:
            log.warning("Error removing file %s: %s", path, e)

I have tested the above solution and it works beautifully.

soutzis commented 4 years ago

Created a pull request (#3087) with said changes.