Projects STRLCPY Osintgram Commits 2cbbf3c3
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■
    .gitignore
    skipped 3 lines
    4 4  *.pyc
    5 5  *.json
    6 6  venv/
    7  -credentials.ini
     7 +config/credentials.ini
  • ■ ■ ■ ■ ■ ■
    osintgram.py
     1 +import yaml
     2 +from src import utils
     3 +from src import OsintgramStatus
     4 +import sys
     5 +import signal
     6 +import argparse
     7 +from src import printcolors as pc
     8 +import readline
     9 +from src.Osintgram import Osintgram
     10 + 
     11 + 
     12 + 
     13 +def signal_handler(sig, frame):
     14 + pc.printout("\nGoodbye!\n", pc.RED)
     15 + sys.exit(0)
     16 + 
     17 + 
     18 +def completer(text, state):
     19 + options = [i for i in status.get_commands() if i.startswith(text)]
     20 + if state < len(options):
     21 + return options[state]
     22 + else:
     23 + return None
     24 + 
     25 +def _quit():
     26 + pc.printout("Goodbye!\n", pc.RED)
     27 + sys.exit(0)
     28 + 
     29 + 
     30 + 
     31 +parser = argparse.ArgumentParser(description='Osintgram is a OSINT tool on Instagram. It offers an interactive shell '
     32 + 'to perform analysis on Instagram account of any users by its nickname ')
     33 +parser.add_argument('id', type=str, # var = id
     34 + help='username')
     35 +parser.add_argument('-C','--cookies', help='clear\'s previous cookies', action="store_true")
     36 +parser.add_argument('-j', '--json', help='save commands output as JSON file', action='store_true')
     37 +parser.add_argument('-f', '--file', help='save output in a file', action='store_true')
     38 +parser.add_argument('-c', '--command', help='run in single command mode & execute provided command', action='store')
     39 +parser.add_argument('-o', '--output', help='where to store photos', action='store')
     40 + 
     41 +args = parser.parse_args()
     42 + 
     43 + 
     44 +signal.signal(signal.SIGINT, signal_handler)
     45 +# if is_windows:
     46 +# pyreadline.Readline().parse_and_bind("tab: complete")
     47 +# pyreadline.Readline().set_completer(completer)
     48 +# else:
     49 +# gnureadline.parse_and_bind("tab: complete")
     50 +# gnureadline.set_completer(completer)
     51 + 
     52 +stream = open("src/setup.yaml", 'r')
     53 +setup = yaml.safe_load(stream)
     54 + 
     55 +parser = argparse.ArgumentParser(description='Osintgram is a OSINT tool on Instagram. It offers an interactive shell '
     56 + 'to perform analysis on Instagram account of any users by its nickname ')
     57 +parser.add_argument('id', type=str, # var = id
     58 + help='username')
     59 +parser.add_argument('-C','--cookies', help='clear\'s previous cookies', action="store_true")
     60 +parser.add_argument('-j', '--json', help='save commands output as JSON file', action='store_true')
     61 +parser.add_argument('-f', '--file', help='save output in a file', action='store_true')
     62 +parser.add_argument('-c', '--command', help='run in single command mode & execute provided command', action='store')
     63 +parser.add_argument('-o', '--output', help='where to store photos', action='store')
     64 + 
     65 +args = parser.parse_args()
     66 + 
     67 +if not args.command:
     68 + utils.printlogo(setup['version'], setup['author'])
     69 + 
     70 +status = OsintgramStatus.OsintgramStatus()
     71 + 
     72 +api = Osintgram(args.id, args.file, args.json, args.command, args.output, args.cookies)
     73 + 
     74 + 
     75 +status.set_commands(setup['commands'])
     76 + 
     77 + 
     78 +while True:
     79 + if args.command:
     80 + cmd = args.command
     81 + _cmd = commands.get(args.command)
     82 + else:
     83 + signal.signal(signal.SIGINT, signal_handler)
     84 +
     85 + completer = utils.Completer(status.get_commands())
     86 + readline.set_completer_delims(' \t\n;')
     87 + readline.set_completer(completer.complete)
     88 + readline.parse_and_bind('tab: complete')
     89 + readline.set_completion_display_matches_hook(completer.display_matches)
     90 + 
     91 + if(status.is_command_mode()):
     92 + pc.printout(status.get_command() + '> ', pc.GREEN)
     93 + else:
     94 + pc.printout("Run a command: ", pc.YELLOW)
     95 + cmd = input()
     96 +
     97 + if cmd in status.get_commands():
     98 + _cmd = cmd
     99 + 
     100 + if status.is_command_mode():
     101 + status.set_subcommand(cmd)
     102 + else:
     103 + status.set_command(cmd)
     104 + 
     105 + commands = status.get_commands()
     106 + else:
     107 + _cmd = None
     108 + 
     109 + if _cmd:
     110 + __import__(status.get_module())
     111 + mymodule = sys.modules[status.get_module()]
     112 + if status.is_subcommand():
     113 + command.__getattribute__(_cmd)()
     114 + else:
     115 + command = mymodule.Command(status.get_path(), api)
     116 +
     117 + elif _cmd == "":
     118 + print("")
     119 + else:
     120 + pc.printout("Unknown command\n", pc.RED)
     121 + 
     122 + if args.command:
     123 + break
     124 + 
     125 + 
     126 + 
  • ■ ■ ■ ■ ■ ■
    src/Command.py
     1 +import yaml
     2 +import readline
     3 +import signal
     4 +from prettytable import PrettyTable
     5 +from src import printcolors as pc
     6 +from src import utils as utils
     7 +import json
     8 +import sys
     9 +import time
     10 + 
     11 + 
     12 +class Command(object):
     13 + 
     14 + def __init__(self, path, api):
     15 + self.commands = []
     16 + self.path = path
     17 + stream = open(self.path, 'r')
     18 + self.config = yaml.safe_load(stream)
     19 + self.options_values = self.config['options']
     20 + self.osintgram = api
     21 + 
     22 + def get_options(self):
     23 + return self.config['options']
     24 +
     25 + def options(self):
     26 + t = PrettyTable(['Option', 'Value'])
     27 + for key, value in self.options_values.items():
     28 + t.add_row([key, str(value)])
     29 + print(t)
     30 + 
     31 + def set(self):
     32 + i = 1
     33 + for key, value in self.options_values.items():
     34 + print(str(i) + ". " + key)
     35 + i = i + 1
     36 + try:
     37 + index = input("Choose option: ")
     38 + key = list(self.options_values.keys())[int(index) - 1]
     39 + v = input("[" + key + "] Choose a value: ")
     40 + self.options_values[key] = v
     41 + print(self.options_values)
     42 + 
     43 + except ValueError:
     44 + print("Not a number")
     45 + 
     46 + def run(self):
     47 + if self.osintgram.check_private_profile():
     48 + return
     49 + 
     50 + pc.printout("Searching for " + self.osintgram.target + " followers...\n")
     51 + 
     52 + followers = []
     53 + 
     54 + rank_token = self.osintgram.generate_uuid()
     55 + data = self.osintgram.get_api().user_followers(str(self.osintgram.target_id), rank_token=rank_token)
     56 + 
     57 + followers.extend(data.get('users', []))
     58 + 
     59 + next_max_id = data.get('next_max_id')
     60 + while next_max_id:
     61 + if(int(self.options_values['delay']) > 0):
     62 + time.sleep(int(self.options_values['delay']))
     63 + 
     64 + sys.stdout.write("\rCatched %i followers" % len(followers))
     65 + sys.stdout.flush()
     66 + results = self.osintgram.get_api().user_followers(str(self.osintgram.target_id), rank_token=rank_token, max_id=next_max_id)
     67 + followers.extend(results.get('users', []))
     68 + next_max_id = results.get('next_max_id')
     69 + sys.stdout.write("\rCatched %i followers" % len(followers))
     70 + sys.stdout.flush()
     71 +
     72 + data = []
     73 + for user in followers:
     74 + u = {
     75 + 'id': user['pk'],
     76 + 'username': user['username'],
     77 + 'full_name': user['full_name']
     78 + }
     79 + data.append(u)
     80 + 
     81 + utils.print_in_table(data, ['ID', 'Username', 'Full Name'], ['id', 'username', 'full_name'])
  • ■ ■ ■ ■ ■
    src/Osintgram.py
    skipped 21 lines
    22 22   
    23 23  class Osintgram:
    24 24   api = None
    25  - api2 = None
    26 25   geolocator = Nominatim(user_agent="http")
    27 26   user_id = None
    28 27   target_id = None
    skipped 32 lines
    61 60   self.following = self.check_following()
    62 61   if(show_output):
    63 62   self.__printTargetBanner__()
     63 + 
     64 + def get_api(self):
     65 + return self.api
     66 +
     67 + def generate_uuid(self):
     68 + return AppClient.generate_uuid()
    64 69   
    65 70   def __get_feed__(self):
    66 71   data = []
    skipped 245 lines
    312 317   
    313 318   
    314 319   def get_followers(self):
    315  - if self.check_private_profile():
    316  - return
    317  - 
    318  - pc.printout("Searching for " + self.target + " followers...\n")
    319  - 
    320  - _followers = []
    321 320   followers = []
    322 321   
    323  - 
    324  - rank_token = AppClient.generate_uuid()
     322 + rank_token = self.generate_uuid()
    325 323   data = self.api.user_followers(str(self.target_id), rank_token=rank_token)
    326 324   
    327  - _followers.extend(data.get('users', []))
     325 + followers.extend(data.get('users', []))
    328 326   
    329 327   next_max_id = data.get('next_max_id')
    330 328   while next_max_id:
    331  - sys.stdout.write("\rCatched %i followers" % len(_followers))
     329 + sys.stdout.write("\rCatched %i followers" % len(followers))
    332 330   sys.stdout.flush()
    333 331   results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
    334  - _followers.extend(results.get('users', []))
     332 + followers.extend(results.get('users', []))
    335 333   next_max_id = results.get('next_max_id')
    336  - sys.stdout.write("\rCatched %i followers" % len(_followers))
     334 + sys.stdout.write("\rCatched %i followers" % len(followers))
    337 335   sys.stdout.flush()
    338 336   
    339 337   print("\n")
    340 338   
    341  - for user in _followers:
    342  - u = {
    343  - 'id': user['pk'],
    344  - 'username': user['username'],
    345  - 'full_name': user['full_name']
    346  - }
    347  - followers.append(u)
     339 + return followers
    348 340   
    349  - t = PrettyTable(['ID', 'Username', 'Full Name'])
    350  - t.align["ID"] = "l"
    351  - t.align["Username"] = "l"
    352  - t.align["Full Name"] = "l"
    353  - 
    354  - json_data = {}
    355  - followings_list = []
    356  - 
    357  - for node in followers:
    358  - t.add_row([str(node['id']), node['username'], node['full_name']])
    359  - 
    360  - if self.jsonDump:
    361  - follow = {
    362  - 'id': node['id'],
    363  - 'username': node['username'],
    364  - 'full_name': node['full_name']
    365  - }
    366  - followings_list.append(follow)
    367  - 
    368  - if self.writeFile:
    369  - file_name = self.output_dir + "/" + self.target + "_followers.txt"
    370  - file = open(file_name, "w")
    371  - file.write(str(t))
    372  - file.close()
    373  - 
    374  - if self.jsonDump:
    375  - json_data['followers'] = followers
    376  - json_file_name = self.output_dir + "/" + self.target + "_followers.json"
    377  - with open(json_file_name, 'w') as f:
    378  - json.dump(json_data, f)
    379  - 
    380  - print(t)
    381 341   
    382 342   def get_followings(self):
    383 343   if self.check_private_profile():
    skipped 1498 lines
  • ■ ■ ■ ■ ■ ■
    src/OsintgramStatus.py
     1 +import yaml
     2 + 
     3 +class OsintgramStatus:
     4 + 
     5 + def __init__(self):
     6 + self.command_mode = False
     7 + self.setted_subcommand = False
     8 + self.command = ""
     9 + self.subcommand = ""
     10 + self.commands = []
     11 + 
     12 + def get_command(self):
     13 + return self.command
     14 + 
     15 + def set_command(self, command):
     16 + self.command_mode = True
     17 + self.command = command
     18 + stream = open(self.get_path(), 'r')
     19 + setup = yaml.safe_load(stream)
     20 + self.commands = setup['commands']
     21 + 
     22 + def get_subcommand(self):
     23 + return self.subcommand
     24 + 
     25 + def set_subcommand(self, command):
     26 + self.subcommand = command
     27 + self.setted_subcommand = True
     28 + 
     29 + def is_command_mode(self):
     30 + return self.command_mode
     31 + 
     32 + def is_subcommand(self):
     33 + return self.setted_subcommand
     34 +
     35 + def get_commands(self):
     36 + return self.commands
     37 + 
     38 + def set_commands(self, commands):
     39 + self.commands = commands
     40 + 
     41 + def get_path(self):
     42 + return "src/commands/" + self.command + "/config.yaml"
     43 +
     44 + def get_module(self):
     45 + return "src.commands." + self.command + ".run"
     46 + 
     47 + 
  • ■ ■ ■ ■ ■ ■
    src/commands/followers/config.yaml
     1 +---
     2 +name: "followers"
     3 +description: "List target followers"
     4 +commands:
     5 + - set
     6 + - help
     7 + - options
     8 + - run
     9 +options:
     10 + output_limit: 0
     11 + delay: 0
     12 + output:
     13 + - json
     14 + - csv
     15 +
  • ■ ■ ■ ■ ■ ■
    src/commands/followers/run.py
     1 +import yaml
     2 +import readline
     3 +import signal
     4 +from prettytable import PrettyTable
     5 +from src import printcolors as pc
     6 +from src import utils as utils
     7 +from src import Command
     8 +import json
     9 +import sys
     10 +import time
     11 + 
     12 + 
     13 +class Command:
     14 + 
     15 + def __init__(self, path, api):
     16 + self.commands = []
     17 + self.path = path
     18 + stream = open(self.path, 'r')
     19 + self.config = yaml.safe_load(stream)
     20 + self.options_values = self.config['options']
     21 + self.osintgram = api
     22 + 
     23 + def get_options(self):
     24 + return self.config['options']
     25 +
     26 + def options(self):
     27 + t = PrettyTable(['Option', 'Value'])
     28 + for key, value in self.options_values.items():
     29 + t.add_row([key, str(value)])
     30 + print(t)
     31 + 
     32 + def set(self):
     33 + i = 1
     34 + for key, value in self.options_values.items():
     35 + print(str(i) + ". " + key)
     36 + i = i + 1
     37 + try:
     38 + index = input("Choose option: ")
     39 + key = list(self.options_values.keys())[int(index) - 1]
     40 + v = input("[" + key + "] Choose a value: ")
     41 + self.options_values[key] = v
     42 + print(self.options_values)
     43 + 
     44 + except ValueError:
     45 + print("Not a number")
     46 + 
     47 + def run(self):
     48 + if self.osintgram.check_private_profile():
     49 + return
     50 + 
     51 + pc.printout("Searching for " + self.osintgram.target + " followers...\n")
     52 + 
     53 + followers = []
     54 + 
     55 + rank_token = self.osintgram.generate_uuid()
     56 + data = self.osintgram.get_api().user_followers(str(self.osintgram.target_id), rank_token=rank_token)
     57 + 
     58 + followers.extend(data.get('users', []))
     59 + 
     60 + next_max_id = data.get('next_max_id')
     61 + while next_max_id:
     62 + if(int(self.options_values['delay']) > 0):
     63 + time.sleep(int(self.options_values['delay']))
     64 + 
     65 + sys.stdout.write("\rCatched %i followers" % len(followers))
     66 + sys.stdout.flush()
     67 + results = self.osintgram.get_api().user_followers(str(self.osintgram.target_id), rank_token=rank_token, max_id=next_max_id)
     68 + followers.extend(results.get('users', []))
     69 + next_max_id = results.get('next_max_id')
     70 + sys.stdout.write("\rCatched %i followers" % len(followers))
     71 + sys.stdout.flush()
     72 +
     73 + data = []
     74 + for user in followers:
     75 + u = {
     76 + 'id': user['pk'],
     77 + 'username': user['username'],
     78 + 'full_name': user['full_name']
     79 + }
     80 + data.append(u)
     81 + 
     82 + utils.print_in_table(data, ['ID', 'Username', 'Full Name'], ['id', 'username', 'full_name'])
     83 + 
     84 +
     85 +
     86 + 
     87 +
     88 + 
     89 + 
     90 + 
     91 +
     92 + 
     93 +
     94 + 
     95 + 
  • ■ ■ ■ ■ ■ ■
    src/setup.yaml
     1 +---
     2 +version: 2.0.0
     3 +author: "Giuseppe Criscione"
     4 + 
     5 +commands:
     6 + - followers
     7 + - command2
  • ■ ■ ■ ■ ■ ■
    src/utils.py
     1 +from __future__ import print_function
     2 + 
     3 +import sys
     4 +from os import environ
     5 + 
     6 +from prettytable import PrettyTable
     7 + 
     8 +from src import printcolors as pc
     9 +from src import artwork
     10 + 
     11 + 
     12 +def printlogo(version, author):
     13 + pc.printout(artwork.ascii_art, pc.YELLOW)
     14 + pc.printout("\nVersion " + version + " - Developed by " + author + "\n\n", pc.YELLOW)
     15 + pc.printout("Type 'list' to show all allowed commands\n")
     16 + 
     17 +def completer(commands, text, state):
     18 + options = [i for i in commands if i.startswith(text)]
     19 + if state < len(options):
     20 + return options[state]
     21 + else:
     22 + return None
     23 + 
     24 + 
     25 +def print_in_table(data, header, values):
     26 + t = PrettyTable(header)
     27 + for i in header:
     28 + t.align[i] = "l"
     29 + 
     30 + for d in data:
     31 + t.add_row([d[i] for i in values])
     32 + 
     33 + print(t)
     34 + 
     35 + 
     36 + 
     37 +class Completer(object): # Custom completer
     38 + 
     39 + def __init__(self, options):
     40 + self.options = sorted(options)
     41 + 
     42 + def complete(self, text, state):
     43 + if state == 0: # on first trigger, build possible matches
     44 + if not text:
     45 + self.matches = self.options[:]
     46 + else:
     47 + self.matches = [s for s in self.options
     48 + if s and s.startswith(text)]
     49 + 
     50 + # return match indexed by state
     51 + try:
     52 + return self.matches[state]
     53 + except IndexError:
     54 + return None
     55 + 
     56 + def display_matches(self, substitution, matches, longest_match_length):
     57 + line_buffer = readline.get_line_buffer()
     58 + columns = environ.get("COLUMNS", 80)
     59 + 
     60 + print()
     61 + 
     62 + tpl = "{:<" + str(int(max(map(len, matches)) * 1.2)) + "}"
     63 + 
     64 + buffer = ""
     65 + for match in matches:
     66 + match = tpl.format(match[len(substitution):])
     67 + if len(buffer + match) > columns:
     68 + print(buffer)
     69 + buffer = ""
     70 + buffer += match
     71 + 
     72 + if buffer:
     73 + print(buffer)
     74 + 
     75 + print("> ", end="")
     76 + print(line_buffer, end="")
     77 + sys.stdout.flush()
     78 + 
     79 + 
     80 + 
Please wait...
Page is in error, reload to recover