mirror of
https://github.com/bellingcat/octosuite.git
synced 2026-06-12 13:28:35 +03:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8364053f97 | ||
|
|
1f288d503f | ||
|
|
57911bd68f | ||
|
|
264048e4bf | ||
|
|
671fbdcaa4 | ||
|
|
5fc5af4157 | ||
|
|
8bc799c829 | ||
|
|
85cadefd50 | ||
|
|
646ea3cb51 | ||
|
|
3e18a3301a | ||
|
|
d4b595d79e | ||
|
|
0f247d1dd8 | ||
|
|
1b2c441237 | ||
|
|
2723c2f8dd |
@@ -11,10 +11,10 @@ A framework for gathering open-source intelligence on GitHub users, repositories
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# Wiki
|
# Wiki
|
||||||
[Refer to the Wiki](https://github.com/bellingcat/octosuite/wiki) for installation instructions, in addition to all other documentation.
|
[Refer to the Wiki](https://github.com/bellingcat/octosuite/wiki) for installation instructions, in addition to all other documentation.
|
||||||
@@ -52,6 +52,7 @@ A framework for gathering open-source intelligence on GitHub users, repositories
|
|||||||
- [x] All the above can be used with command-line arguments (PyPI Package only)
|
- [x] All the above can be used with command-line arguments (PyPI Package only)
|
||||||
- [x] ...And more
|
- [x] ...And more
|
||||||
|
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
> Octosuite automatically logs network and user activity of each session, the logs are saved by date and time in the .logs folder
|
> Octosuite automatically logs network and user activity of each session, the logs are saved by date and time in the .logs folder
|
||||||
|
|
||||||
@@ -59,6 +60,10 @@ A framework for gathering open-source intelligence on GitHub users, repositories
|
|||||||
# License
|
# License
|
||||||

|

|
||||||
|
|
||||||
|
# Credits
|
||||||
|
* The code used for finding emails from usernames is taken from [Somdev Sangwan](https://github.com/s0md3v)'s [Zen](https://github.com/s0md3v/zen)
|
||||||
|
|
||||||
|
|
||||||
# Donations
|
# Donations
|
||||||
If you like OctoSuite and would like to show support, you can Buy A Coffee for the developer using the button below
|
If you like OctoSuite and would like to show support, you can Buy A Coffee for the developer using the button below
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from octosuite.config import red, white, green, reset, Tree
|
|||||||
|
|
||||||
# banner.py
|
# banner.py
|
||||||
# This file holds the program's banner and version tag
|
# This file holds the program's banner and version tag
|
||||||
version_tag = "3.0.1"
|
version_tag = "3.1.0"
|
||||||
|
|
||||||
|
|
||||||
def banner():
|
def banner():
|
||||||
@@ -16,7 +16,7 @@ def banner():
|
|||||||
| |.----.| |_.-----.| __|.--.--.|__| |_.-----.
|
| |.----.| |_.-----.| __|.--.--.|__| |_.-----.
|
||||||
| - || __|| _| _ ||__ || | || | _| -__|
|
| - || __|| _| _ ||__ || | || | _| -__|
|
||||||
|_______||____||____|_____||_______||_____||__|____|_____|
|
|_______||____||____|_____||_______||_____||__|____|_____|
|
||||||
v{version_tag}#dev
|
v{version_tag}
|
||||||
{white}— Advanced Github {red}OSINT{white} Framework
|
{white}— Advanced Github {red}OSINT{white} Framework
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ def usage():
|
|||||||
|
|
||||||
def create_parser():
|
def create_parser():
|
||||||
parser = argparse.ArgumentParser(description='OCTOSUITE: Advanced GitHub osint framework — by Richard Mwewa | https://about.me/rly0nheart', usage=usage())
|
parser = argparse.ArgumentParser(description='OCTOSUITE: Advanced GitHub osint framework — by Richard Mwewa | https://about.me/rly0nheart', usage=usage())
|
||||||
parser.add_argument('-m', '--method', help='method', choices=['user_profile', 'user_repos', 'user_gists', 'user_orgs', 'user_events',
|
parser.add_argument('-m', '--method', help='method', choices=['user_email', 'user_profile', 'user_repos', 'user_gists', 'user_orgs', 'user_events',
|
||||||
'user_subscriptions', 'user_following', 'user_followers', 'user_follows',
|
'user_subscriptions', 'user_following', 'user_followers', 'user_follows',
|
||||||
'org_profile', 'org_repos', 'org_events', 'org_member',
|
'org_profile', 'org_repos', 'org_events', 'org_member',
|
||||||
'repo_profile', 'repo_contributors', 'repo_stargazers', 'repo_forks',
|
'repo_profile', 'repo_contributors', 'repo_stargazers', 'repo_forks',
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ def user_command():
|
|||||||
user_cmd_table = Table(show_header=True, header_style=header_title)
|
user_cmd_table = Table(show_header=True, header_style=header_title)
|
||||||
user_cmd_table.add_column("Command", style="dim")
|
user_cmd_table.add_column("Command", style="dim")
|
||||||
user_cmd_table.add_column("Description")
|
user_cmd_table.add_column("Description")
|
||||||
|
user_cmd_table.add_row("email", "Return a target's email")
|
||||||
user_cmd_table.add_row("profile", "Get a target's profile info")
|
user_cmd_table.add_row("profile", "Get a target's profile info")
|
||||||
user_cmd_table.add_row("gists", "Return a users's gists")
|
user_cmd_table.add_row("gists", "Return a users's gists")
|
||||||
user_cmd_table.add_row("org", "Return organizations that a target belongs to/owns")
|
user_cmd_table.add_row("org", "Return organizations that a target belongs to/owns")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#!usr/bin/python
|
#!usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
@@ -9,6 +10,7 @@ import requests
|
|||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from requests.auth import HTTPBasicAuth
|
||||||
from octosuite.banner import version_tag, banner
|
from octosuite.banner import version_tag, banner
|
||||||
from octosuite.config import Tree, Text, Table, Prompt, Confirm, xprint, create_parser, args, red, white, green, yellow, header_title, reset
|
from octosuite.config import Tree, Text, Table, Prompt, Confirm, xprint, create_parser, args, red, white, green, yellow, header_title, reset
|
||||||
from octosuite.message_prefixes import ERROR, WARNING, PROMPT, POSITIVE, NEGATIVE, INFO # wondering why I name all the variables instead of just using the * wildcard?, because it's the pythonic way lol
|
from octosuite.message_prefixes import ERROR, WARNING, PROMPT, POSITIVE, NEGATIVE, INFO # wondering why I name all the variables instead of just using the * wildcard?, because it's the pythonic way lol
|
||||||
@@ -29,7 +31,7 @@ if os.name == "nt":
|
|||||||
try:
|
try:
|
||||||
from pyreadline3 import Readline
|
from pyreadline3 import Readline
|
||||||
except ImportError:
|
except ImportError:
|
||||||
subprocess.run(['pip3', 'install', 'pyreadline3'])
|
subprocess.run(['pip3', 'install', 'pyreadline3'], shell=False)
|
||||||
readline = Readline()
|
readline = Readline()
|
||||||
else:
|
else:
|
||||||
import readline
|
import readline
|
||||||
@@ -199,7 +201,7 @@ An advanced and lightning fast framework for gathering open-source intelligence
|
|||||||
|
|
||||||
|
|
||||||
Whats new in v{version_tag}?
|
Whats new in v{version_tag}?
|
||||||
[{green}FIXED{reset}] Fixed a bug '[ERROR] An error occurred: can only concatenate str (not "NoneType") to str'
|
[{green}IMPROVED{reset}] Added a subcommand to the 'user' commands, that will be used to get a user's email 'user:email' (CLI only)
|
||||||
|
|
||||||
Read the wiki: https://github.com/bellingcat/octosuite/wiki
|
Read the wiki: https://github.com/bellingcat/octosuite/wiki
|
||||||
GitHub REST API documentation: https://docs.github.com/rest
|
GitHub REST API documentation: https://docs.github.com/rest
|
||||||
@@ -207,6 +209,22 @@ GitHub REST API documentation: https://docs.github.com/rest
|
|||||||
xprint(about_text)
|
xprint(about_text)
|
||||||
|
|
||||||
|
|
||||||
|
def get_email_from_contributor(username, repo, contributor):
|
||||||
|
response = requests.get(f"https://github.com/{username}/{repo}/commits?author={contributor}",
|
||||||
|
auth=HTTPBasicAuth(username, '')).text
|
||||||
|
latest_commit = re.search(rf'href="/{username}/{repo}/commit/(.*?)"', response)
|
||||||
|
if latest_commit:
|
||||||
|
latest_commit = latest_commit.group(1)
|
||||||
|
else:
|
||||||
|
latest_commit = 'dummy'
|
||||||
|
commit_details = requests.get(f"https://github.com/{username}/{repo}/commit/{latest_commit}.patch",
|
||||||
|
auth=HTTPBasicAuth(username, '')).text
|
||||||
|
email = re.search(r'<(.*)>', commit_details)
|
||||||
|
if email:
|
||||||
|
email = email.group(1)
|
||||||
|
return email
|
||||||
|
|
||||||
|
|
||||||
class Octosuite:
|
class Octosuite:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# API endpoint
|
# API endpoint
|
||||||
@@ -243,6 +261,7 @@ class Octosuite:
|
|||||||
("repo:issues", self.repo_issues),
|
("repo:issues", self.repo_issues),
|
||||||
("repo:releases", self.repo_releases),
|
("repo:releases", self.repo_releases),
|
||||||
("user", user),
|
("user", user),
|
||||||
|
("user:email", self.get_user_email),
|
||||||
("user:repos", self.user_repos),
|
("user:repos", self.user_repos),
|
||||||
("user:gists", self.user_gists),
|
("user:gists", self.user_gists),
|
||||||
("user:orgs", self.user_orgs),
|
("user:orgs", self.user_orgs),
|
||||||
@@ -271,6 +290,7 @@ class Octosuite:
|
|||||||
|
|
||||||
# Arguments map will be used to run Octosuite with argparse
|
# Arguments map will be used to run Octosuite with argparse
|
||||||
self.argument_map = [("user_profile", self.user_profile),
|
self.argument_map = [("user_profile", self.user_profile),
|
||||||
|
("user_email", self.get_user_email),
|
||||||
("user_repos", self.user_repos),
|
("user_repos", self.user_repos),
|
||||||
("user_gists", self.user_gists),
|
("user_gists", self.user_gists),
|
||||||
("user_orgs", self.user_orgs),
|
("user_orgs", self.user_orgs),
|
||||||
@@ -510,6 +530,28 @@ class Octosuite:
|
|||||||
'About.me': 'https://about.me/rly0nheart',
|
'About.me': 'https://about.me/rly0nheart',
|
||||||
'Buy Me A Coffee': 'https://buymeacoffee.com/189381184'}
|
'Buy Me A Coffee': 'https://buymeacoffee.com/189381184'}
|
||||||
|
|
||||||
|
def get_repos_from_username(self, username):
|
||||||
|
response = requests.get(f"{self.endpoint}/users/{username}/repos?per_page=100&sort=pushed",
|
||||||
|
auth=HTTPBasicAuth(username, '')).text
|
||||||
|
repositories = re.findall(rf'"full_name":"{username}/(.*?)",.*?"fork":(.*?),', response)
|
||||||
|
unforked_repos = []
|
||||||
|
for repository in repositories:
|
||||||
|
if repository[1] == 'false':
|
||||||
|
unforked_repos.append(repository[0])
|
||||||
|
return unforked_repos
|
||||||
|
|
||||||
|
def get_user_email(self):
|
||||||
|
if args.username:
|
||||||
|
username = args.username
|
||||||
|
else:
|
||||||
|
username = Prompt.ask(f"{white}@{green}Username{reset}")
|
||||||
|
repos = self.get_repos_from_username(username)
|
||||||
|
for repo in repos:
|
||||||
|
email = get_email_from_contributor(username, repo, username)
|
||||||
|
if email:
|
||||||
|
xprint(f"{username}: {email}")
|
||||||
|
break
|
||||||
|
|
||||||
# Fetching organization info
|
# Fetching organization info
|
||||||
def org_profile(self):
|
def org_profile(self):
|
||||||
if args.organization:
|
if args.organization:
|
||||||
@@ -769,8 +811,8 @@ class Octosuite:
|
|||||||
events_tree = Tree("\n" + event['id'])
|
events_tree = Tree("\n" + event['id'])
|
||||||
events_tree.add(f"Type: {event['type']}")
|
events_tree.add(f"Type: {event['type']}")
|
||||||
events_tree.add(f"Created at: {event['created_at']}")
|
events_tree.add(f"Created at: {event['created_at']}")
|
||||||
xprint(events_tree)
|
xprint(events_tree)
|
||||||
xprint(event['payload'])
|
xprint(event['payload'])
|
||||||
# log_org_events(event, organization)
|
# log_org_events(event, organization)
|
||||||
else:
|
else:
|
||||||
xprint(response.json())
|
xprint(response.json())
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as file:
|
|||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="octosuite",
|
name="octosuite",
|
||||||
version="3.0.3",
|
version="3.1.0",
|
||||||
author="Richard Mwewa",
|
author="Richard Mwewa",
|
||||||
author_email="rly0nheart@duck.com",
|
author_email="rly0nheart@duck.com",
|
||||||
packages=["octosuite"],
|
packages=["octosuite"],
|
||||||
|
|||||||
Reference in New Issue
Block a user