OpenVAS Change Request #47: OpenVAS-Scanner: Keep uploaded files in memory instead of on disk
Status: Voted +5. Done. Implemented with SVN revisions 7635 and 7638.
To eliminate possible TOCTOU attacks on the scanner.
To allow privilege downgrades in the scanner.
Currently, files uploaded to the OpenVAS scanner through NVT preferences of the type file are written to temporary files when they are uploaded at the start of a scan. A mapping is created between the original name of the file on the users machine (e.g. /home/user/abc.txt) and the name of the temporary file on the OpenVAS scanner (e.g. /var/lib/openvas/tmp/tmp.12345-678). When the NVT which uploaded the file runs during the attack, the location or content of this temporary file will be provided to NVT. When the task has finished, the temporary files are removed.
NVTs can access the uploaded file in two ways: they can use the command script_get_preference_file_content to access the contents of the file or the command script_get_preference_file_location to determine to location of the temporary file on the OpenVAS scanner.
One weakness of this approach is that it opens the possibility of TOCTOU (time of check, time of use) race conditions: a local attacker could use the insecure creation of the temporary file to overwrite arbitrary files (as described by Tim Brown here and here) or could alter the contents of the uploaded file between upload and actual use by the NVT.
The file system access currently happens at a time where the process has elevated privileges and has access to the entire disk; this amplifies the threat described above. In order to have the OpenVAS scanner operating in a secure manner, the OpenVAS project is committed to enabling the scanner to run with the least privileges possible; this may mean that writing to disk or accessing files on disk might not be possible for the process in the future.
To avoid any need for disk access or elevated privileges, this change request proposes the storage of uploaded files in memory instead of on disk.
The least invasive way to switch to memory based storage would be to use the mapping described above to map the original file name to the actual contents of the file instead of the file name on the scanner (see below).
The scanner would no longer write uploaded files to disk, thereby reducing potential attack vectors and removing the need for disk access in this context.
Depending on the size of the uploaded files, memory usage of openvas-scanner would increase during a scan.
Design and Implementation
The least invasive approach would require a few minor changes to openvas-scanner and openvas-libraries:
- In openvas-scanner/openvasd/ntp_11.c (ntp_11_recv_file): Currently, the uploaded file is written to a temporary file and the name of the temporary file is kept in memory. This should be changed to storing the contents of the file in memory instead of the name of the temporary file.
- In openvas-libraries/nasl/nasl_scanner_glue.c (script_get_preference_file_content): This function currently opens the temporary file and provides its content to the NVT. This should be changed to retrieve the content from memory instead of from the file.
- In openvas-libraries/misc/plugutils.c (get_plugin_preference_fname): This function currently provides the mapping from the original name of the file to the name of the temporary file, but would after the change provided the mapping from the name of the uploaded file to its contents. The function name should be changed to reflect this change.
- In openvas-scanner/openvassd/attack.c (unlink_name_mapped_file): This callback currently removes the temporary files from disk after a scan has finished. This should be changed to free the memory used by the uploaded file instead.
This change would require additional changes to update the handling of ssh login information uploaded by the client in openvas-scanner:
- In openvas-scanner/openvassd/ntp_11.c (build_global_host_sshlogins_map): This function currently uses the hash_table_file_read function provided by openvas-libraries/misc/hash_table_file.c to read a file into a hash table. It should be changed to use the hash_table_file_read_text function provided by the same file to read the contents from memory instead.
- In openvas-scanner/openvassd/ntp_11.c (build_global_sshlogin_info_map): This function currently uses the openvas_ssh_login_file_read function provided by openvas-libraries/misc/openvas_ssh_login.c to read a file into a hash table. This file currently does not provide a function to read the contents from memory into the hash table, so this would require an additional change:
- In openvas-libraries/misc/openvas_ssh_login.c: A function should be added to allow importing a key file from memory instead of from disk; this can be easily done by using g_key_file_load_from_data instead of g_key_file_load_from_file.
- 2010-05-13 Michael Wiegand <email@example.com>:
Updated status, removed paragraph with outdated information.
- 2010-05-03 Michael Wiegand <firstname.lastname@example.org>:
- 2010-03-26 Michael Wiegand <email@example.com>: