diff --git a/README.md b/README.md index 8d8afca5..edf3a497 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://img.shields.io/badge/version-0.9-green)](https://github.com/Datalux/Osintgram/releases/tag/0.9) +[![](https://img.shields.io/badge/version-1.0-green)](https://github.com/Datalux/Osintgram/releases/tag/1.0) [![](https://img.shields.io/badge/license-GPLv3-blue)](https://img.shields.io/badge/license-GPLv3-blue) [![](https://img.shields.io/badge/language-Python3-red)](https://img.shields.io/badge/language-Python3-red) [![](https://img.shields.io/badge/Telegram-Channel-blue.svg)](https://t.me/osintgram) @@ -31,7 +31,7 @@ Osintgram offers an interactive shell to perform analysis on Instagram account o ``` You can find detailed commands usage [here](doc/COMMANDS.md). -[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/0.9) | +[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/1.0) | [CHANGELOG](doc/CHANGELOG.md) ## Tools diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4dcabd0f..3b4379ce 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [1.0](https://github.com/Datalux/Osintgram/releases/tag/1.0) +**Enhancements** +- Set itself as target (#53) +- Get others info from user (`info` command): + - Whats'App number (if avaible) + - City Name (if avaible) + - Address Street (if avaible) + - Contact phone number (if avaible) + +**Bug fixes** +- Fix login issue (#79, #80, #81) + ## [0.9](https://github.com/Datalux/Osintgram/releases/tag/0.9) **Enhancements** diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index ccdae6ba..37336530 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -68,6 +68,10 @@ Show target info like: - business email (if available) - HD profile picture url - connected Facebook page (if available) +- Whats'App number (if avaible) +- City Name (if avaible) +- Address Street (if avaible) +- Contact phone number (if avaible) ### JSON Can set preference to export commands output as JSON in output folder. It save output in `_.JSON` file. diff --git a/main.py b/main.py index 67cf3ba7..95fa79b0 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ def printlogo(): pc.printout("\_______ /____ >__|___| /__| \___ /|__| (____ /__|_| /\n", pc.YELLOW) pc.printout(" \/ \/ \/ /_____/ \/ \/ \n", pc.YELLOW) print('\n') - pc.printout("Version 0.9 - Developed by Giuseppe Criscione - 2019\n\n", pc.YELLOW) + pc.printout("Version 1.0 - Developed by Giuseppe Criscione\n\n", pc.YELLOW) pc.printout("Type 'list' to show all allowed commands\n") pc.printout("Type 'FILE=y' to save results to files like '_.txt (deafult is disabled)'\n") pc.printout("Type 'FILE=n' to disable saving to files'\n") diff --git a/src/Osintgram.py b/src/Osintgram.py index b2060865..754fbbb8 100644 --- a/src/Osintgram.py +++ b/src/Osintgram.py @@ -442,60 +442,83 @@ def get_hashtags(self): pc.printout("Sorry! No results found :-(\n", pc.RED) def get_user_info(self): - content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") - - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) - - data = content.json() - data = data['graphql']['user'] - - pc.printout("[ID] ", pc.GREEN) - pc.printout(str(data['id']) + '\n') - pc.printout("[FULL NAME] ", pc.RED) - pc.printout(str(data['full_name']) + '\n') - pc.printout("[BIOGRAPHY] ", pc.CYAN) - pc.printout(str(data['biography']) + '\n') - pc.printout("[FOLLOWED] ", pc.BLUE) - pc.printout(str(data['edge_followed_by']['count']) + '\n') - pc.printout("[FOLLOW] ", pc.GREEN) - pc.printout(str(data['edge_follow']['count']) + '\n') - pc.printout("[BUSINESS ACCOUNT] ", pc.RED) - pc.printout(str(data['is_business_account']) + '\n') - if data['is_business_account']: - pc.printout("[BUSINESS CATEGORY] ") - pc.printout(str(data['business_category_name']) + '\n') - pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) - pc.printout(str(data['is_verified']) + '\n') - if 'business_email' in data: - pc.printout("[BUSINESS EMAIL] ", pc.BLUE) - pc.printout(str(data['business_email']) + '\n') - pc.printout("[HD PROFILE PIC] ", pc.GREEN) - pc.printout(str(data['profile_pic_url_hd']) + '\n') - if data['connected_fb_page']: - pc.printout("[FB PAGE] ", pc.RED) - pc.printout(str(data['connected_fb_page']) + '\n') + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) + + data = content['user_detail']['user'] + + pc.printout("[ID] ", pc.GREEN) + pc.printout(str(data['pk']) + '\n') + pc.printout("[FULL NAME] ", pc.RED) + pc.printout(str(data['full_name']) + '\n') + pc.printout("[BIOGRAPHY] ", pc.CYAN) + pc.printout(str(data['biography']) + '\n') + pc.printout("[FOLLOWED] ", pc.BLUE) + pc.printout(str(data['follower_count']) + '\n') + pc.printout("[FOLLOW] ", pc.GREEN) + pc.printout(str(data['following_count']) + '\n') + pc.printout("[BUSINESS ACCOUNT] ", pc.RED) + pc.printout(str(data['is_business']) + '\n') + if data['is_business']: + if not data['can_hide_category']: + pc.printout("[BUSINESS CATEGORY] ") + pc.printout(str(data['category']) + '\n') + pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) + pc.printout(str(data['is_verified']) + '\n') + if 'public_email' in data and data['public_email']: + pc.printout("[EMAIL] ", pc.BLUE) + pc.printout(str(data['public_email']) + '\n') + pc.printout("[HD PROFILE PIC] ", pc.GREEN) + pc.printout(str(data['hd_profile_pic_url_info']['url']) + '\n') + if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: + pc.printout("[FB PAGE] ", pc.RED) + pc.printout(str(data['connected_fb_page']) + '\n') + if 'whatsapp_number' in data and data['whatsapp_number']: + pc.printout("[WHATSAPP NUMBER] ", pc.GREEN) + pc.printout(str(data['whatsapp_number']) + '\n') + if 'city_name' in data and data['city_name']: + pc.printout("[CITY] ", pc.YELLOW) + pc.printout(str(data['city_name']) + '\n') + if 'address_street' in data and data['address_street']: + pc.printout("[ADDRESS STREET] ", pc.RED) + pc.printout(str(data['address_street']) + '\n') + if 'contact_phone_number' in data and data['contact_phone_number']: + pc.printout("[CONTACT PHONE NUMBER] ", pc.CYAN) + pc.printout(str(data['contact_phone_number']) + '\n') - if self.jsonDump: - user = { - 'id': data['id'], - 'full_name': data['full_name'], - 'biography': data['biography'], - 'edge_followed_by': data['edge_followed_by']['count'], - 'edge_follow': data['edge_follow']['count'], - 'is_business_account': data['is_business_account'], - 'is_verified': data['is_verified'], - 'profile_pic_url_hd': data['profile_pic_url_hd'] - } - if 'business_email' in data: - user['business_email'] = data['business_email'] - if data['connected_fb_page']: - user['connected_fb_page'] = data['connected_fb_page'] + if self.jsonDump: + user = { + 'id': data['pk'], + 'full_name': data['full_name'], + 'biography': data['biography'], + 'edge_followed_by': data['follower_count'], + 'edge_follow': data['following_count'], + 'is_business_account': data['is_business_account'], + 'is_verified': data['is_business'], + 'profile_pic_url_hd': data['hd_profile_pic_url_info']['url'] + } + if 'public_email' in data and data['public_email']: + user['email'] = data['public_email'] + if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: + user['connected_fb_page'] = data['fb_page_call_to_action_id'] + if 'whatsapp_number' in data and data['whatsapp_number']: + user['whatsapp_number'] = data['whatsapp_number'] + if 'city_name' in data and data['city_name']: + user['city_name'] = data['city_name'] + if 'address_street' in data and data['address_street']: + user['address_street'] = data['address_street'] + if 'contact_phone_number' in data and data['contact_phone_number']: + user['contact_phone_number'] = data['contact_phone_number'] + + json_file_name = "output/" + self.target + "_info.json" + with open(json_file_name, 'w') as f: + json.dump(user, f) - json_file_name = "output/" + self.target + "_info.json" - with open(json_file_name, 'w') as f: - json.dump(user, f) + except ClientError as e: + pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) + pc.printout("\n") + exit(2) def get_total_likes(self): if self.check_private_profile(): @@ -821,27 +844,32 @@ def get_user_photo(self): pc.printout("\nWoohoo! We downloaded " + str(counter) + " photos (saved in output/ folder) \n", pc.GREEN) def get_user_propic(self): - content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) - data = content.json() + data = content['user_detail']['user'] - uurl = data["graphql"]["user"] - if "profile_pic_url_hd" in uurl: - URL = data["graphql"]["user"]["profile_pic_url_hd"] - else: - URL = data["graphql"]["user"]["profile_pic_url"] + if "hd_profile_pic_url_info" in data: + URL = data["hd_profile_pic_url_info"]['url'] + else: + #get better quality photo + items = len(data['hd_profile_pic_versions']) + URL = data["hd_profile_pic_versions"][items-1]['url'] - if URL != "": - end = "output/" + self.target + "_propic.jpg" - urllib.request.urlretrieve(URL, end) - pc.printout("Target propic saved in output folder\n", pc.GREEN) + if URL != "": + end = "output/" + self.target + "_propic.jpg" + urllib.request.urlretrieve(URL, end) + pc.printout("Target propic saved in output folder\n", pc.GREEN) - else: - pc.printout("Sorry! No results found :-(\n", pc.RED) + else: + pc.printout("Sorry! No results found :-(\n", pc.RED) + + except ClientError as e: + print(e) + print("An error occured... exit") + exit(2) def get_user_stories(self): if self.check_private_profile(): @@ -946,25 +974,27 @@ def get_people_tagged_by_user(self): pc.printout("Sorry! No results found :-(\n", pc.RED) def get_user(self, username): - content = requests.get("https://www.instagram.com/" + username + "/?__a=1") - - if content.status_code == 404: - print("Oops... " + str(self.target) + " non exist, please enter a valid username.") - sys.exit(2) + try: + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target}) + content = self.api._call_api(endpoint) - data = content.json() + if self.writeFile: + file_name = "output/" + self.target + "_user_id.txt" + file = open(file_name, "w") + file.write(str(content['user_detail']['user']['pk'])) + file.close() - if self.writeFile: - file_name = "output/" + self.target + "_user_id.txt" - file = open(file_name, "w") - file.write(str(data['graphql']['user']['id'])) - file.close() + user = dict() + user['id'] = content['user_detail']['user']['pk'] + user['is_private'] = content['user_detail']['user']['is_private'] - user = dict() - user['id'] = data['graphql']['user']['id'] - user['is_private'] = data['graphql']['user']['is_private'] + return user + except ClientError as e: + pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) + pc.printout("\n") + exit(2) - return user + def set_write_file(self, flag): if flag: @@ -1024,6 +1054,8 @@ def login(self, u, p): #pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED) error = json.loads(e.error_response) pc.printout(error['message'], pc.RED) + pc.printout(": ", pc.RED) + pc.printout(e.msg, pc.RED) pc.printout("\n") if 'challenge' in error: print("Please follow this link to complete the challenge: " + error['challenge']['url']) @@ -1047,6 +1079,8 @@ def onlogin_callback(self, api, new_settings_file): # print('SAVED: {0!s}'.format(new_settings_file)) def check_following(self): + if self.target_id == self.api.authenticated_user_id: + return True endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id}) return self.api._call_api(endpoint)['user_detail']['user']['friendship_status']['following']