Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unifi backup downloader #11548

Merged
merged 7 commits into from
May 14, 2019
Merged

Conversation

h00die
Copy link
Contributor

@h00die h00die commented Mar 10, 2019

Post module to run against Ubiquiti Unifi Controllers to download any backup or autobackup files.

These files are.... annoying. They have a .unf extension but are AES encrypted zip files. Luckily, its a known key so we decrypt it. The files then need to be repaired, zip has -FF to do this (and it works), however the ruby zip gems dont have this. So if zip is available on the system (aka nix and maybe osx), we repair the file as well. If a repair doesn't happen, 7zip may work, but haven't tried.

See docs for install instructions, and verification steps.

@bcoles there is a system call in here, the module provides all input, can you think of an RCE possible on this? I thought maybe if your target was something with ticks in it maybe, but also couldn't think of a better way to do the call. Open to help and suggestions!

@bcoles
Copy link
Contributor

bcoles commented Mar 10, 2019

These files are.... annoying. They have a .unf extension but are AES encrypted zip files. Luckily, its a known key so we decrypt it. The files then need to be repaired, zip has -FF to do this (and it works), however the ruby zip gems dont have this. So if zip is available on the system (aka nix and maybe osx), we repair the file as well. If a repair doesn't happen, 7zip may work, but haven't tried.

I believe the established approach is to cry. Something like this:

    print_status('The backup files were stored in the loot database.')
    print_status('The files are ZIP encrypted, and due to the lack of the archive/zip gem,')
    print_status('they cannot be decrypted in Metasploit.')
    print_status('You will need to open them up with zip or a similar utility, and use the')
    print_status('password <whatever the password is @hoodie)> to unzip them.')
    print_status('Annoy the Metasploit developers until this gets fixed!')

@bcoles there is a system call in here, the module provides all input, can you think of an RCE possible on this? I thought maybe if your target was something with ticks in it maybe, but also couldn't think of a better way to do the call. Open to help and suggestions!

The obvious attack vectors are local. No obvious remote vector, as the path and arguments are fully controlled by Metasploit store_loot and Rex::Quickfile. Obviously a malicious zip could have unintended consequences if the zip utility on the system has known vulnerabilities (ie, traversal).

A couple of things stand out, but may prove to be non-issues:

  • Rex::Quickfile writes to /tmp with 600 permissions and randomized file name. May be racey (?)
    • Edit: Perhaps a more likely local attack vector exists with --out #{temp_file.path}.zip. Possible symlink attack for arbitrary file overwrite?
  • system call may suffer from pathing issues for yes, and maybe zip, depending how zip_exe = Msf::Util::Helper.which('zip') works, as the full path is not provided.

@bcoles
Copy link
Contributor

bcoles commented Mar 10, 2019

@h00die
Copy link
Contributor Author

h00die commented Mar 11, 2019

It isn't a password protected zip, its an AES encrypted zip. If I didn't document that clearly, i definitely can adjust.

to be clear, the database file needs the following:
unzip(fix_zip(aes_decrypt(file)))
and after that, we most likely only care about db.gz because of course a gz in a zip:
bson_reader(gunzip(db.gz))

First things first, get files. Once this lands, I'll work on a db parser.

@jmartin-tech
Copy link
Contributor

Default backup path on macOS is ~/Library/Application Support/UniFi/data/backup/autobackup/.

@jmartin-tech
Copy link
Contributor

Sorry wrong button, should not have closed :-(

@h00die
Copy link
Contributor Author

h00die commented Mar 14, 2019

Thanks @jmartin-r7 . Added osx to the code, however w/o a box to test with, someone will need to test that portion.

@h00die
Copy link
Contributor Author

h00die commented Mar 14, 2019

Travis error isn't related to this PR code:

ERROR:  While executing gem ... (Gem::RemoteFetcher::UnknownHostError)
    timed out (https://api.rubygems.org/specs.4.8.gz)
The command "gem update --system" failed and exited with 1 during .

@h00die h00die added the blocked Blocked by one or more additional tasks label Mar 27, 2019
@h00die
Copy link
Contributor Author

h00die commented Mar 27, 2019

delayed until I can test on a mac

@h00die h00die removed the blocked Blocked by one or more additional tasks label Apr 6, 2019
@h00die
Copy link
Contributor Author

h00die commented Apr 6, 2019

OSX testing completed, this is ready for review.

@h00die
Copy link
Contributor Author

h00die commented May 10, 2019

ping anyone with unify, this has been ready for review for a month and its framework friday :)

@jmartin-tech jmartin-tech self-assigned this May 10, 2019
@h00die
Copy link
Contributor Author

h00die commented May 10, 2019

Just tested against 5.10.23 (latest) and still working. I did notice though that when on a shell, if there are multiple files which are larger in size, or the encrypted zips have something that breaks the cat command (unsure which is true), the module will crash. Fixed that, dropped shell support, and documented.

Copy link
Contributor

@jmartin-tech jmartin-tech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works and I can land as is if desire is to defer on enhancements I have noted.


# https://help.ubnt.com/hc/en-us/articles/205202580-UniFi-system-properties-File-Explanation
sprop_locations.each do |sprop|
next unless exists?(sprop)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From testing.

Might be worth adding some detail here when no locations result in data.

On a windows system with no backup stored the module reported accessing system.properties and did then complete. When no backup exists may be worth a status.

I also noted on Linux when the session user does not have read access to system.properties path there is no detail reported.

Same linux target:
session as regular user

msf5 payload(linux/x64/meterpreter/reverse_tcp) > use post/multi/gather/ubiquiti_unifi_backup
msf5 post(multi/gather/ubiquiti_unifi_backup) > set session 1
session => 1
msf5 post(multi/gather/ubiquiti_unifi_backup) > run
[*] Post module execution completed
msf5 post(multi/gather/ubiquiti_unifi_backup) > exit

session as root

msf5 payload(linux/x64/meterpreter/reverse_tcp) > use post/multi/gather/ubiquiti_unifi_backup
msf5 post(multi/gather/ubiquiti_unifi_backup) > set session 1
session => 1
msf5 post(multi/gather/ubiquiti_unifi_backup) > run

[+] Read UniFi Controller file /var/lib/unifi/system.properties
[+] File /var/lib/unifi/backup/5.10.23.unf saved to /home/msfuser/.msf4/loot/20190514173003_default_192.168.17.102_ubiquiti.unifi.b_530890.unf
[+] File 5.10.23.unf DECRYPTED and saved to /home/msfuser/.msf4/loot/20190514173003_default_192.168.17.102_ubiquiti.unifi.b_721128.zip.  File needs to be repair via `zip -FF`
[*] Attempting to repair zip file (this is normal)
[+] File /var/lib/unifi/backup/5.10.23.unf DECRYPTED and REPAIRED and saved to /home/msfuser/.msf4/loot/20190514173004_default_192.168.17.102_ubiquiti.unifi.b_058997.zip.
[+] File /var/lib/unifi/backup/autobackup/autobackup_5.10.23_20190514_1725_1557854700012.unf saved to /home/msfuser/.msf4/loot/20190514173005_default_192.168.17.102_ubiquiti.unifi.b_558645.unf
[+] File autobackup_5.10.23_20190514_1725_1557854700012.unf DECRYPTED and saved to /home/msfuser/.msf4/loot/20190514173005_default_192.168.17.102_ubiquiti.unifi.b_491301.zip.  File needs to be repair via `zip -FF`
[*] Attempting to repair zip file (this is normal)
[+] File /var/lib/unifi/backup/autobackup/autobackup_5.10.23_20190514_1725_1557854700012.unf DECRYPTED and REPAIRED and saved to /home/msfuser/.msf4/loot/20190514173005_default_192.168.17.102_ubiquiti.unifi.b_438546.zip.
[*] Post module execution completed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd agree with you, looks like i went too 'linux' style and made everything verbose printing. I'll add a few prints for more detail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added two prints, one for when reading system.properties files, and one for when trying to read data. I could add another one for 'no data was found' as well if you'd think it to be beneficial

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works, thanks.

@jmartin-tech jmartin-tech merged commit 0f6eacd into rapid7:master May 14, 2019
jmartin-tech added a commit that referenced this pull request May 14, 2019
msjenkins-r7 pushed a commit that referenced this pull request May 14, 2019
@jmartin-tech
Copy link
Contributor

Release Notes

post/multi/gather/ubiquiti_unifi_backup downloads any backup or autobackup files from Ubiquiti Unifi Controllers on Windows/Linux/MacOS.

@h00die
Copy link
Contributor Author

h00die commented May 14, 2019

Thanks @jmartin-r7

@h00die h00die deleted the ubiquiti_unifi_backup branch May 14, 2019 23:59
@gdavidson-r7 gdavidson-r7 added the rn-modules release notes for new or majorly enhanced modules label May 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants