Skip to content

Randomly set credentials written in cleartext to world-readable file #3854

@ubuntu-server-builder

Description

@ubuntu-server-builder

This bug was originally filed in Launchpad as LP: #1918303

Launchpad details
affected_projects = ['cloud-init (Ubuntu)', 'cloud-init (Ubuntu Xenial)', 'cloud-init (Ubuntu Bionic)', 'cloud-init (Ubuntu Focal)', 'cloud-init (Ubuntu Groovy)']
assignee = oddbloke
assignee_name = Dan Watkins
date_closed = 2021-05-05T20:34:41.802942+00:00
date_created = 2021-03-09T15:37:00.582455+00:00
date_fix_committed = 2021-03-23T16:24:33.988640+00:00
date_fix_released = 2021-05-05T20:34:41.802942+00:00
id = 1918303
importance = critical
is_complete = True
lp_url = https://bugs.launchpad.net/cloud-init/+bug/1918303
milestone = None
owner = wasp0x01
owner_name = Carl Pearson
private = False
status = fix_released
submitter = wasp0x01
submitter_name = Carl Pearson
tags = ['verification-done', 'verification-done-bionic', 'verification-done-focal', 'verification-done-groovy', 'verification-done-xenial']
duplicates = [1888483]

Launchpad user Carl Pearson(wasp0x01) wrote on 2021-03-09T15:37:00.582455+00:00

Summary

cloud-init allows administrators to set passwords for user accounts via the chpasswd configuration module. Administrators can instruct cloud-init to set a random password generated at runtime using the 'R' or 'RANDOM' keywords.

However, cloud-init appears to write all randomly generated passwords in cleartext to stderr. Cloud-init's default logging configuration, in file /etc/cloud/cloud.cfg.d/05_logging.cfg, redirects both stdout and stderr to the log file /var/log/cloud-init-output.log. The file /var/log/cloud-init-output.log is world readable. Thus, any unprivileged account on the system can view the cleartext password for any account which had a random password generated at runtime. The credentials are not redacted in the log.

Reproduction

Pre-requisites: A device with Ubuntu Server 20.04 installed. Ubuntu Server comes with cloud-init pre-installed out of the box, but the latest release of cloud-init as of this report (21.1) is not available in 20.04's apt repositories. You may need to install v21.1 manually. You will also need an exsiting admin account with root privileges.

  1. Login as admin.
  2. Create an unprivileged user account, bob, and set a password. We will use this account to demonstrate unprivileged account access to generated passwords.
    sudo adduser bob
  3. Create another unprivileged user account, alice, and set a password. We will change this account's password with cloud-init.
    sudo adduser alice
  4. Create and open configuration file /etc/cloud/cloud.cfg.d/95_chpasswd.cfg using vim or other editor of your choice.
    sudo vim /etc/cloud/cloud.cfg.d/95_chpasswd.cfg
  5. Add the following chpasswd configuration content to the file then save and exit.
    chpasswd:
    list: |
    alice:RANDOM
  6. cloud-init only runs the chpasswd function on first boot of the OS that cloud-init knows about. For proof of concept purposes, we need to simulate a new instance. Run:
    sudo cloud-init clean
    to reset cloud-init's state.
  7. Reboot the system.
    sudo reboot
  8. Login as unprivileged user bob.
  9. View the password by runnnig
    cat /var/log/cloud-init-output.log | grep alice
  10. Alice's temporary password should appear on terminal in the form alice:
  11. Logout and log back in to the system as alice using the temporary password. You should get access and prompted to set a new password, which confirms the password bob retrieved from the logs is the actual password for alice's account.

Impact

Any unprivileged user on the system can retrieve all cloud-init randomly set credentials. These could potentially be used to access other accounts.

Notes

If 'expire: false' is added to the chpasswd config, then leaked passwords remain valid until manually changed and increases the risk of unauthorized account access. Otherwise, the default behaviour prompts accounts to set a new password at next login, reducing the time window for unauthorized access.

Accounts not used for interactive login might not get passwords changed or accounts might get a password set but then not authenticate for some time. The precise impact and duration of valid exposed credentials appears dependent somewhat on each cloud-init customer's environment and how they use cloud-init to set credentials.

I'm not sure the best approach to patch this but perhaps the credentials could be written to cloud-init's protected directories or files which restrict access to root users only, such as /var/run/cloud-init/instance-data-sensitive.json?

Line 214 of https://github.com/canonical/cloud-init/blob/master/cloudinit/config/cc_set_passwords.py checks if any random passwords were set and if so prints each one to stderror. This might be the root cause.

Tested on Ubuntu Server 20.04.02, cloud-init latest release 21.1 as of report time. If I can provide any further information please let me know. Thanks!
-Carl

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions