Path: blob/master/InstagramPy/InstagramPySession.py
197 views
# The MIT License.1# Copyright (C) 2017 The Future Shell , DeathSec.2#3# @filename : InstagramPySession.py4# @description : creates a new session , checks for configuration and gets critical data5# , loads save and saves data too.6import json7import os8import uuid9import hashlib10import requests11from stem import Signal12from stem.control import Controller1314DEFAULT_PATH = "{}/".format(os.path.expanduser('~'))151617class InstagramPySession:18'''19__init__:20- loads configuration from specified file.21- gets the perfect place for the save file.22- sets class variables for later use.23'''2425magic_cookie = None26api_url = None27user_agent = None28ig_sig_key = None29ig_sig_version = None30tor_proxy = None31tor_controller = None32save_data = None33dump_data = None34current_save = None35username = ''36password = ''37password_list = None38password_list_md5_sum = None39password_list_buffer = None40password_list_length = 041eopl = False42current_line = 143ip = None44cli = None45bot = requests.Session()4647def __init__(self, username, password_list, configuration, save_location, cli):4849self.username = username50self.cli = cli5152if not os.path.isfile(password_list):53self.cli.ReportError(54"password list not found at {}.".format(password_list))55self.password_list = password_list56'''57Note: Always open password list with errors ignored because all password list58mostly has a wrong encoding or the users pc does not support it!59'''60self.password_list_buffer = open(61password_list, encoding='utf-8', errors='ignore')62self.password_list_md5_sum = str(63self.md5sum(open(password_list, "rb")).hexdigest())6465with open(password_list, encoding='utf-8', errors='ignore') as f:66for line in f:67self.password_list_length += 16869if configuration == DEFAULT_PATH:70configuration = "{}instapy-config.json".format(DEFAULT_PATH)71if save_location == DEFAULT_PATH:72save_location = "{}.instagram-py/".format(DEFAULT_PATH)7374dump_location = "{}dump.json".format(save_location)7576if not os.path.isfile(configuration):77self.cli.ReportError(78"configuration file not found at {}".format(configuration))79else:80try:81with open(configuration, "r") as fp:82configuration = json.load(fp)83except Exception as err:84self.cli.ReportError(85"invalid configuration file at {}".format(configuraion))8687self.api_url = configuration['api-url']88self.user_agent = configuration['user-agent']89self.ig_sig_key = configuration['ig-sig-key']90self.ig_sig_version = configuration['ig-sig-version']91self.tor_proxy = "{}://{}:{}".format(92configuration['tor']['protocol'], configuration['tor']['server'], configuration['tor']['port'])93if not configuration['tor']['control']['password'] == "":94self.OpenTorController(95configuration['tor']['control']['port'], configuration['tor']['control']['password'])96else:97self.OpenTorController(98configuration['tor']['control']['port'], None)99100self.bot.proxies = {101# tor socks proxy!102"https": self.tor_proxy,103"http": self.tor_proxy104}105106# build headers107108self.bot.headers.update(109{110'Connection': 'close', # make sure requests closes the sockets instead of keep-alive!111'Accept': '*/*',112'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',113'Cookie2': '$Version=1',114'Accept-Language': 'en-US',115'User-Agent': self.user_agent116}117)118119'''120Note: https://icanhazip.com is a free domain to get your current tor ip121this is not a dangerous website for sure , thank you @majorhayden122'''123try:124self.ip = self.bot.get(125'https://icanhazip.com').content.rstrip().decode()126except KeyboardInterrupt:127self.cli.ReportError("process aborted by the user")128except (BaseException, Exception) as err:129self.cli.ReportError(130"Connection to host failed , check your connection and tor configuration.")131132if not os.path.exists(save_location):133try:134os.mkdir(save_location)135except (BaseException, Exception) as err:136self.cli.ReportError(err)137138self.save_data = save_location139else:140self.save_data = save_location141142self.dump_data = dump_location143144try:145self.bot.get(146"{}si/fetch_headers/?challenge_type=signup&guid={}".format(147self.api_url, str(uuid.uuid4()).replace('-', ''))148)149self.magic_cookie = self.bot.cookies['csrftoken']150except KeyboardInterrupt:151self.cli.ReportError(152"cannot get the magic cookie , aborted by the user")153except (BaseException, Exception) as err:154self.cli.ReportError(err)155156'''157ReadSaveFile()158- Checks if we have located the save file159- if not creates one160- opens the save file and load it as json data161- check if the user uses the same password list file for the same user162- set the current password pointer to the given data163'''164165def ReadSaveFile(self, isResume):166if self.current_save == None:167self.CreateSaveFile(isResume)168SaveFile = json.load(open(self.current_save, 'r'))169self.current_line = SaveFile['line-count']170if self.password_list_md5_sum == SaveFile['password-file-md5'] and self.username == SaveFile['username']:171c_line = 1172for line in self.password_list_buffer:173self.password = str(line).rstrip()174if c_line == self.current_line:175break176c_line += 1177return True178179'''180UpdateSaveFile()181- check if we have created a save file182- if yes , rewrite the the save file with the current session!183'''184185def UpdateSaveFile(self):186if not self.current_save == None:187updatefile = open(self.current_save, 'w')188json.dump(189{190"username": str(self.username),191"password-file-md5": str(self.password_list_md5_sum),192"line-count": self.current_line193}, updatefile)194updatefile.close()195196'''197CreateSaveFile()198- checks if we have not openned any save file but know the save location.199- if yes , creates with default settings to the location.200'''201202def CreateSaveFile(self, isResume):203if self.current_save == None and not self.save_data == None:204save = '{}{}.dat'.format(self.save_data, hashlib.sha224(205self.username.encode('utf-8')).hexdigest())206self.current_save = save207if not os.path.isfile(save):208self.UpdateSaveFile()209else:210if not isResume:211self.UpdateSaveFile()212213def ReadDumpFile(self, username):214if not self.dump_data == None:215if not os.path.isfile(self.dump_data):216return None217json_dump = json.load(open(self.dump_data, 'r'))218required_info = None219220try:221required_info = json_dump[username]222except KeyError:223pass224225return required_info226227def WriteDumpFile(self, info):228if not self.dump_data == None:229json_dump = {}230if os.path.isfile(self.dump_data):231json_dump = json.load(open(self.dump_data, 'r'))232json_dump[info['id']] = info233json.dump(json_dump, open(self.dump_data, 'w'))234return True235236'''237CurrentPassword()238- returns the current password pointed to the password list239'''240241def CurrentPassword(self):242return self.password243244'''245NextPassword()246- increaments and sets the next password as our current password247'''248249def NextPassword(self):250if not self.current_line > self.password_list_length:251for line in self.password_list_buffer:252self.password = str(line.rstrip())253break254self.current_line += 1255else:256self.eopl = True257258'''259GetUsername()260- returns current session username261'''262263def GetUsername(self):264return self.username265266'''267md5sum( FILE POINTER , BLOCK SIZE)268- opens large files from FILE POINTER269- calculates md5 with BLOCK SIZE with respect to FILE POINTER270- finalizes and returns a hashlib object!271'''272273def md5sum(self, fp, block_size=2**20):274md5 = hashlib.md5()275while True:276data = fp.read(block_size)277if not data:278break279md5.update(data)280return md5281282'''283ChangeIPAddress()284- stem <-> Signal285- Changes Tor Identity with the controller!286'''287288def ChangeIPAddress(self):289if not self.tor_controller == None:290# signal tor to change ip291self.tor_controller.signal(Signal.NEWNYM)292self.ip = self.bot.get(293'https://icanhazip.com').content.rstrip().decode()294return True295return False296297'''298OpenTorController(PORT , PASSWORD)299- Creates a fresh tor controller instance to the session300'''301302def OpenTorController(self, port, password):303try:304self.tor_controller = Controller.from_port(port=int(port))305if password == None:306self.tor_controller.authenticate()307else:308self.tor_controller.authenticate(password=password)309except Exception as err:310self.cli.ReportError(311"Tor configuration invalid or server down :: {}".format(err))312313314