Jump to content

VTSTech-32hex.py v0.36 - 100khash/sec, Hashlist support. RAdminv2.x Support


VTSTech

Recommended Posts

2085b5c9ee6fbaeeba14dee365dc01cb.png

import sys, os, hashlib, binascii, time

from passlib.apps import custom_app_context as pwd_context
from passlib.context import CryptContext

if sys.platform.startswith('win32'):
	import msvcrt
pwd_context = CryptContext(schemes=["hex_md5", "hex_md4", "hex_sha1", "nthash" ])
 
def banner():
	print "#########################################"
	print "# VTSTech-32hex v0.36 Python Version    #"
	print "# Facebook: facebook.com/VTSTech        #"
	print "# Twitter: @VTSTech_                    #"
	print "# Web: www.VTS-Tech.org                 #"
	print "# E-mail: veritas@vts-tech.org          #"
	print "# XMPP: veritas@creep.im                #"
	print "# BTC 1VTSgzD24bjkSGdD7kvauxkxHZ4yiwhdU #"
	print "#########################################"

StartTime = time.time()
ETime = 0
silent = 1
Cracked = ""
lines = 0
linet = 0
CrkCnt = 0
cnt = ""
TotalTime = ""
LastAlgo = ""
numpass = open('passwords.dat')
num_pass = sum(1 for line in numpass)
numpass.close()
if len(sys.argv) == 1:
	banner()
	print ""
	print "Usage: VTStech-32hex.py -l hashlist.txt - List mode using hashlist.txt"
	print ""
	print "Options"
	print ""
	print "-l hashlist.txt, load target hashes from hashlist.txt"
	print "-s speed per sec updates (60s interval)"
	print ""
	print "Press any key to display speed/sec"	
	print ""
	print "Supports the following encryption methods:"
	print ""	
	print "MD5 md5()"	
	print "MD4 md4()"	
	print "NTLM"
	print "RAdmin v2.x"
	print "MD5-SHA1 md5(sha1())"
	print "MD5-UP-MD5 md5(strtoupper(md5()))"	
	print "Double MD5 md5(md5())"	
	print "Triple MD5 md5(md5(md5()))"		
	print "Quadruple MD5 md5(md5(md5(md5())))"
	print "Quintuple MD5 md5(md5(md5(md5(md5()))))"
	print "Hextuple MD5 md5(md5(md5(md5(md5(md5())))))"
	print "Double MD4 md4(md4())"	
	print "Triple MD4 md4(md4(md4()))"		
	print "Quadruple MD4 md4(md4(md4(md4())))"
	print "Quintuple MD4 md4(md4(md4(md4(md4()))))"
	print "Hextuple MD4 md4(md4(md4(md4(md4(md4())))))"	
	sys.exit()
else:
	banner()
	print "Press any key to display speed/sec"
	if len(sys.argv[1]) == 2:
		if sys.argv[1] == "-l":
			target = sys.argv[2]
			hashes = open(sys.argv[2])				 
		elif sys.argv[2] == "-l":
			target = sys.argv[3]
			hashes = open(sys.argv[3])
		elif sys.argv[3] == "-l":
			target = sys.argv[4]
			hashes = open(sys.argv[4])
		if sys.argv[1] == "-s":
			silent = 0
		elif sys.argv[2] == "-s":
			silent = 0
md5 = CryptContext(schemes=["hex_md5"],)
md5sha_hash = CryptContext(schemes=["hex_sha1"],)
md4 = CryptContext(schemes=["hex_md4"],)
nt_hash = CryptContext(schemes=["nthash"],)
numhash = open(target)
line=0
num_hash = sum(1 for line in numhash)
print ""
print num_pass,"passwords,", num_hash,"hashes loaded."
print ""
TotalPass = (num_pass * num_hash) * 16
numhash.close()
hashes = open(target)
for lineh in hashes:
	passwd = open("passwords.dat")	
	CurrHash = lineh
	CurrTime = time.time()
	TotalTime = CurrTime - StartTime
	if sys.platform.startswith('win32'):
			while msvcrt.kbhit():
				msvcrt.getch()
				progress = str(cnt),chr(47),str(TotalPass)
				pcnt = "(",str(round(float(float(cnt) / float(TotalPass))*100,2)),"%)"
				duration = str(round(TotalTime,2)),"s"
				print "Elapsed:",''.join(duration),"Progess:",''.join(progress),''.join(pcnt),"Speed:", round((cnt / TotalTime),2),"Hash/s"
	if ((CurrTime - ETime)  > 60) or ((CurrTime - ETime) == CurrTime):
		if (TotalTime > 1):
			if silent == 0:
				progress = str(cnt),chr(47),str(TotalPass)
				pcnt = "(",str(round(float(float(cnt) / float(TotalPass))*100,2)),"%)"
				duration = str(round(TotalTime,2)),"s"
				print "Elapsed:",''.join(duration),"Progess:",''.join(progress),''.join(pcnt),"Speed:", round((cnt / TotalTime),2),"Hash/s"
		ETime = CurrTime
	for linep in passwd:
		lines += 1
		CurrPass = linep
		CurrHash = CurrHash.strip(chr(13))
		CurrHash = CurrHash.strip(chr(10))
		CurrHash = CurrHash.strip(chr(34))
		CurrPass = CurrPass.strip(chr(13))
		CurrPass = CurrPass.strip(chr(10))
		CurrPass = CurrPass.strip(chr(34))
		md51x = md5.encrypt(CurrPass)
		md52x = md5.encrypt(md51x)
		md53x = md5.encrypt(md52x)
		md54x = md5.encrypt(md53x)
		md55x = md5.encrypt(md54x)
		md56x = md5.encrypt(md55x)
		md5sha1 = md5.encrypt(md5sha_hash.encrypt(CurrPass))
		md41x = md4.encrypt(CurrPass)
		md42x = md4.encrypt(md41x)
		md43x = md4.encrypt(md42x)
		md44x = md4.encrypt(md43x)
		md45x = md4.encrypt(md44x)
		md46x = md4.encrypt(md45x)
		CurrPass2 = str(CurrPass + str((chr(0) * 100)))
		radmin = md5.encrypt(CurrPass2[0:100])
		md5umd5 = md5.encrypt(md51x.upper())
		cnt = (lines * 16)
		CurrTime = time.time()
		try:
			CurrPass.decode('ascii')
		except UnicodeDecodeError:
			ntlm = md4.encrypt(" ".encode('utf-16le'))	
		else:			
			ntlm = md4.encrypt(CurrPass.encode('utf-16le'))			
		TotalTime = CurrTime - StartTime
		if md51x == CurrHash:
			Algo = "MD5"
			Cracked = md51x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md52x == CurrHash:
			Algo = "Double MD5"
			Cracked = md52x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)				
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md53x == CurrHash:
			Algo = "Triple MD5"
			Cracked = md53x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md54x == CurrHash:
			Algo = "Quadruple MD5"
			Cracked = md54x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md55x == CurrHash:
			Algo = "Quintuple MD5"
			Cracked = md55x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md56x == CurrHash:
			Algo = "Hextuple MD5"
			Cracked = md56x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md5sha1 == CurrHash:
			Algo = "MD5(SHA1())"
			Cracked = md5sha1,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md41x == CurrHash:
			Algo = "MD4"
			Cracked = md41x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md42x == CurrHash:
			Algo = "Double MD4"
			Cracked = md42x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md43x == CurrHash:
			Algo = "Triple MD4"
			Cracked = md43x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md44x == CurrHash:
			Algo = "Quadruple MD4" 
			Cracked = md44x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md45x == CurrHash:
			Algo = "Quintuple MD4"
			Cracked = md45x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
		elif md46x == CurrHash:
			Algo = "Hextuple MD4"
			Cracked = md46x,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)	
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
			break
		elif ntlm == CurrHash:
			Algo = "NTLM"
			Cracked = ntlm,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)
				LastAlgo == Algo
				CrkCnt = CrkCnt + 1				
			break
			break
		elif radmin == CurrHash:
			Algo = "radmin"
			Cracked = radmin,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
			break
		elif md5umd5 == CurrHash:
			Algo = "MD5-UP-MD5"
			Cracked = md5umd5,":",CurrPass
			if LastAlgo == Algo:
				print ''.join(Cracked)
			else:
				print "Encryption Method:",Algo
				print ''.join(Cracked)
				LastAlgo = Algo
				CrkCnt = CrkCnt + 1		
			break
			break			
print ""
print ""
DidWeWin = "Recovered: ",str(CrkCnt),"/",str(num_hash)," (",str(round(float(CrkCnt) / float(num_hash)*100,2)),"%)"
progress = str(cnt),chr(47),str(TotalPass)
pcnt = "(",str(round(float(float(cnt) / float(TotalPass))*100,2)),"%)"
duration = str(round(TotalTime,2)),"s"
print ''.join(DidWeWin)
print ""
print "Elapsed time:",''.join(duration),"Progess:",''.join(progress),''.join(pcnt),"Speed:", round((cnt / TotalTime),2),"Hash/s"
print "Recovery complete."
sys.exit()
http://www.vts-tech.org/32hex-v0-2/

Uses PassLib https://pypi.python.org/packages/source/p/passlib/passlib-1.6.2.tar.gz

Download VTSTech-32hex.py-036.rar

Edited by VTSTech
Link to comment
Share on other sites

The main purpose of this program is to identify a 32hex hashtype, once the hashtype has been identified there is much faster methods of recovery.

Regardless of its purpose, looking at the code I don't think that's a proper description of what it does. What you're doing is taking a single hash and a wordlist and you encrypt the words from the wordlist to make various hashes, comparing against the single hash. If at the end of the run you find you had a match, you say you cracked the hash, what it is and what the associated password is.

So, what I think you've created is a very slow password cracker that doesn't limit itself to a single hashing algorithm.

Improvement suggestions:

- Use a dictionary to map a computed hash to the hash type and password. Lets you get rid of that *MASSIVE* if.

- Break the for-loop when a match is found.

- Don't print your banner for each line in your wordlist file. It'll probably be VERY annoying.

- md52x and up all get populated with one more MD5 iteration than what the name suggests.

- Reuse the previous MD5/MD4 calculation when you're computing multiple iterations. This code does 26 MD5 calculations and should be able to do the same with just 6. Same for MD4 (from 21 to 6).

- Going beyond the above, you should put the repeat-iterations in a loop so you can have a global set to the maximum amount of iterations rather than hard-coding 6.

- Are repeated iterations of MD5/MD4 actually being used??? Repeating the algo just increases the chance of collisions.

- Include SHA256.

- Your md5sha_hash class actually gets populated with the sha1 implementation. No MD5 comes into play so this is a very misleading name for a variable. And I just don't get it. If you have the SHA1, why bother with MD5? Is this actually used? In, like, REAL software??

- Why are you first looping through the lines of the wordlist to get a 'linet' value which you're not going to use anyways?

- I don't get this line:

print Cracked[0],chr(58),Cracked[2]
. Cracked[1] always gets populated with that char 58. If you're not using it, remove it from the Cracked array. Better yet, populate Cracked with a formatted string and just print that. Makes everything much clearer.
Link to comment
Share on other sites

Regardless of its purpose, looking at the code I don't think that's a proper description of what it does. What you're doing is taking a single hash and a wordlist and you encrypt the words from the wordlist to make various hashes, comparing against the single hash. If at the end of the run you find you had a match, you say you cracked the hash, what it is and what the associated password is.

So, what I think you've created is a very slow password cracker that doesn't limit itself to a single hashing algorithm.

Improvement suggestions:

- Use a dictionary to map a computed hash to the hash type and password. Lets you get rid of that *MASSIVE* if.

- Break the for-loop when a match is found.

- Don't print your banner for each line in your wordlist file. It'll probably be VERY annoying.

- md52x and up all get populated with one more MD5 iteration than what the name suggests.

- Reuse the previous MD5/MD4 calculation when you're computing multiple iterations. This code does 26 MD5 calculations and should be able to do the same with just 6. Same for MD4 (from 21 to 6).

- Going beyond the above, you should put the repeat-iterations in a loop so you can have a global set to the maximum amount of iterations rather than hard-coding 6.

- Are repeated iterations of MD5/MD4 actually being used??? Repeating the algo just increases the chance of collisions.

- Include SHA256.

- Your md5sha_hash class actually gets populated with the sha1 implementation. No MD5 comes into play so this is a very misleading name for a variable. And I just don't get it. If you have the SHA1, why bother with MD5? Is this actually used? In, like, REAL software??

- Why are you first looping through the lines of the wordlist to get a 'linet' value which you're not going to use anyways?

- I don't get this line:

print Cracked[0],chr(58),Cracked[2]
. Cracked[1] always gets populated with that char 58. If you're not using it, remove it from the Cracked array. Better yet, populate Cracked with a formatted string and just print that. Makes everything much clearer.

I havent put a lot of work into the python version yet ;)

But thanks for the suggestions. I'm not too too concerned with speed as I'm never going to get MHash/sec using these methods. In the GUI Version I'm reading everything into arrays first.

Link to comment
Share on other sites

  • 4 weeks later...

- Are repeated iterations of MD5/MD4 actually being used??? Repeating the algo just increases the chance of collisions.

- If you have the SHA1, why bother with MD5? Is this actually used? In, like, REAL software??

Link to comment
Share on other sites

- Are repeated iterations of MD5/MD4 actually being used??? Repeating the algo just increases the chance of collisions.

- If you have the SHA1, why bother with MD5? Is this actually used? In, like, REAL software??

Served me well in a recent password cracking competition. Was a number of 5x MD5 i wouldnt have found using Hashcat.

Also because SHA1 is a 40 character hash and not a 32 character hash it is not attempted with this script.

See VTSTech-40hex.py for that at www.vts-tech.org/32hex-v0-2/

86c83e6c4952cc778a366bf024081aca.png

Edited by VTSTech
Link to comment
Share on other sites

Fair enough.

In general though, in case people are developing applications that include some login module and are wondering how best to store the password in encrypted form, please read this StackOverflow question and in particular its chosen answer.

The short and sweet of it is that repeating a hash as-is doesn't make the hash more secure and in fact decreases the quality of the hash by making hash collisions more likely (look up the Birthday Paradox for an explanation). There are a number of hashing algorithms (bcrypt and PBKDF2 to name 2) which have been explicitly designed to be repeated and in doing so don't lose quality. What you gain with this is control over the amount of work that needs to be performed to compute a single hash (and thus the amount of work that needs to be performed to brute-force the hash).

The core problem people try to solve by repeat-hashing a value is that the value to hash is predictable allowing people to create a rainbow table with precomputed hashes of commonly used values up to a given length and only needing a quick lookup to discover the password for the hash, defeating it by simply not needing to perform the hard work. Repeat-hashing means you need to have multiple rainbox tables - one for each number of repeats. Making those rainbow tables takes quite some time and a LOT of storage so having more of them around becomes more and more unattractive. When you realise that common values for repeating your hash with PBKDF2 lie somewhere between 60.000 and 120.000 iterations, you do the math... It will take your server a bit longer to verify the validity of a password hash, but that's a small price to pay. And if due to some advancement in computing the computation of the hash suddenly can be done in 1/10th the time you simply up the iterations to compensate, making the work needed to crack a single hash constant over time rather than decreasing due to advances in math and computing tech.

A far cheaper way to solve the core problem is SEED YOUR HASHES! It's best to seed with a few values unique to your user, so the username, email and user id (if appliccable) come to mind. Most databases have some unique id for the database record storing your user object, so you can use that and I also recommend using a value that is kept outside of the database. Some configuration file with a big random in it should work just fine. The 'security by obscurity' bit is that your attacker needs to know what you used in what order to seed your hashes on top of the actual data itself.

If your attacker still manages to acquire all the data (which would be impressive), figures out the order in which the various parts need to be fed through the algorithm (also quite impressive), (s)he still needs to break the algorithm itself...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...