This repository has been archived by the owner on May 2, 2022. It is now read-only.
forked from kumzugloom/sqldeveloperpassworddecryptor
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsqldeveloperpassworddecryptor.jy
136 lines (108 loc) · 5.11 KB
/
sqldeveloperpassworddecryptor.jy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# -*- coding: utf-8 -*-
# This file is part of sqldeveloperpassworddecrypter.
#
# Copyright (C) 2015, Thomas Debize <tdebize at mail.com>
# All rights reserved.
#
# sqldeveloperpassworddecrypter is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sqldeveloperpassworddecrypter is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sqldeveloperpassworddecrypter. If not, see <http://www.gnu.org/licenses/>.
from javax.crypto import *
from javax.crypto.spec import *
from java.security import *
import sys
import xml.etree.ElementTree
import base64
import array
import hashlib
# Script version
VERSION = '1.1'
# OptionParser imports
from optparse import OptionParser
from optparse import OptionGroup
# Options definition
parser = OptionParser(usage="%prog [options]\nVersion: " + VERSION)
main_grp = OptionGroup(parser, 'v3 and v4 parameters')
main_grp.add_option('-p', '--encrypted-password', help = '(mandatory): password that you want to decrypt. Ex. -p 054D4844D8549C0DB78EE1A98FE4E085B8A484D20A81F7DCF8', nargs = 1)
main_grp.add_option('-c', '--connections-file', help = '(optional): "connections.xml" file containing encrypted passwords. Ex. -c connections.xml', nargs = 1)
v4_grp = OptionGroup(parser, 'v4 specific parameters')
v4_grp.add_option('-d', '--db-system-id-value', help = '(mandatory for v4): machine-unique value of "db.system.id" attribute in the "product-preferences.xml" file. Ex: -d 6b2f64b2-e83e-49a5-9abf-cb2cd7e3a9ee', nargs = 1)
#v4_grp.add_option('-f', '--db-system-id-file', help = '(optional): "product-preferences.xml" file containing the "db.system.id" attribute value.', nargs = 1)
parser.option_groups.extend([main_grp, v4_grp])
# Handful functions
def des_cbc_decrypt(encrypted_password, decryption_key, iv):
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(decryption_key, "DES"), IvParameterSpec(iv))
decrypted_password = cipher.doFinal(encrypted_password)
return decrypted_password.tostring()
def decrypt_v4(encrypted, db_system_id, parser):
encrypted_password = base64.b64decode(encrypted)
salt = '051399429372e8ad'.decode('hex')
num_iteration = 42
# key generation from a machine-unique value with a fixed salt
key = db_system_id + salt
for i in xrange(num_iteration):
m = hashlib.md5(key)
key = m.digest()
secret_key = key[:8]
iv = key[8:]
decrypted = des_cbc_decrypt(encrypted_password, secret_key, iv)
return decrypted
def decrypt_v3(encrypted, parser):
if len(encrypted) % 2 != 0:
parser.error('v3 encrypted password length is not even (%s), aborting.' % len(encrypted))
if not(encrypted.startswith("05")):
parser.error('v3 encrypted password string not beginning with "05", aborting.\nRemember, for a v4 password you need the db.system.id value !')
encrypted = encrypted.decode('hex')
secret_key = encrypted[1:9]
encrypted_password = encrypted[9:]
iv = "\x00" * 8
decrypted = des_cbc_decrypt(encrypted_password, secret_key, iv)
return decrypted
def main(options, arguments):
"""
Dat main
"""
global parser, VERSION
print 'sqldeveloperpassworddecryptor.py version %s\n' % VERSION
if (options.encrypted_password):
print "[+] encrypted password: %s" % options.encrypted_password
if options.db_system_id_value:
# v4 decryption
print "[+] db.system.id value: %s" % options.db_system_id_value
print "\n[+] decrypted password: %s" % decrypt_v4(options.encrypted_password, options.db_system_id_value, parser)
else:
#v3 decryption
print "\n[+] decrypted password: %s" % decrypt_v3(options.encrypted_password, parser)
elif (options.connections_file):
print "[+] Parsing file: %s" % options.connections_file
tmp = xml.etree.ElementTree.parse(options.connections_file)
root = tmp.getroot()
root = xml.etree.ElementTree.parse(options.connections_file).getroot()
for level1 in root.findall('.//Reference'):
con = {}
for level2 in level1.findall('.//StringRefAddr'):
if level2.get('addrType') == 'password':
if options.db_system_id_value:
con[level2.get('addrType')] = decrypt_v4(level2[0].text, options.db_system_id_value, parser)
else:
con[level2.get('addrType')] = decrypt_v3(level2[0].text, parser)
elif level2.get('addrType') in ['ConnName', 'hostname', 'port', 'user', 'serviceName']:
con[level2.get('addrType')] = level2[0].text
print "[+] Decrypted Connection: %s" % con
else:
parser.error("Please specify a file to decrypt")
print "[+] Task successfully completed."
return None
if __name__ == "__main__" :
options, arguments = parser.parse_args()
main(options, arguments)