forked from techrec13/Zen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzen.py
152 lines (135 loc) · 4.77 KB
/
zen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import re
import sys
import json
import argparse
import threading
from requests import get
from requests.auth import HTTPBasicAuth
parser = argparse.ArgumentParser()
parser.add_argument('target', help='target')
parser.add_argument('-o', help='output file', dest='output')
parser.add_argument('-u', help='your username', dest='uname')
parser.add_argument('-t', help='number of threads', dest='threads', type=int)
parser.add_argument('--org', help='organization', dest='org', action='store_true')
parser.add_argument('--breach', help='check emails for breach', dest='breach', action='store_true')
args = parser.parse_args()
inp = args.target
breach = args.target
output = args.output
organization = args.org
uname = args.uname or ''
thread_count = args.threads or 2
colors = True # Output should be colored
machine = sys.platform # Detecting the os of current system
if machine.lower().startswith(('os', 'win', 'darwin', 'ios')):
colors = False # Colors shouldn't be displayed in mac & windows
if not colors:
end = green = bad = info = ''
else:
end = '\033[1;m'
green = '\033[1;32m'
bad = '\033[1;31m[-]\033[1;m'
info = '\033[1;33m[!]\033[1;m'
print ('''%s
Z E N v1.0
%s''' % (green, end))
if inp.endswith('/'):
inp = inp[:-1]
targetOrganization = targetRepo = targetUser = False
jsonOutput = {}
if inp.count('/') < 4:
if '/' in inp:
username = inp.split('/')[-1]
else:
username = inp
if organization:
targetOrganization = True
else:
targetUser = True
elif inp.count('/') == 4:
targetRepo = inp.split('/')
username = targetRepo[-2]
repo = targetRepo[-1]
targetRepo = True
else:
print ('%s Invalid input' % bad)
quit()
def findContributorsFromRepo(username, repo):
response = get('https://api.github.com/repos/%s/%s/contributors?per_page=100' % (username, repo), auth=HTTPBasicAuth(uname, '')).text
contributors = re.findall(r'https://github\.com/(.*?)"', response)
return contributors
def findReposFromUsername(username):
response = get('https://api.github.com/users/%s/repos?per_page=100&sort=pushed' % username, auth=HTTPBasicAuth(uname, '')).text
repos = re.findall(r'"full_name":"%s/(.*?)",.*?"fork":(.*?),' % username, response)
nonForkedRepos = []
for repo in repos:
if repo[1] == 'false':
nonForkedRepos.append(repo[0])
return nonForkedRepos
def findEmailFromContributor(username, repo, contributor):
response = get('https://github.com/%s/%s/commits?author=%s' % (username, repo, contributor), auth=HTTPBasicAuth(uname, '')).text
latestCommit = re.search(r'href="/%s/%s/commit/(.*?)"' % (username, repo), response)
if latestCommit:
latestCommit = latestCommit.group(1)
else:
latestCommit = 'dummy'
commitDetails = get('https://github.com/%s/%s/commit/%s.patch' % (username, repo, latestCommit), auth=HTTPBasicAuth(uname, '')).text
email = re.search(r'<(.*)>', commitDetails)
if email:
email = email.group(1)
if breach:
jsonOutput[contributor] = {}
jsonOutput[contributor]['email'] = email
if get('https://haveibeenpwned.com/api/v2/breachedaccount/' + email).status_code == 200:
email = email + ' \033[1;31m[\033[0mpwned\033[1;31m]\033[0m'
jsonOutput[contributor]['pwned'] = True
else:
jsonOutput[contributor]['pwned'] = False
else:
jsonOutput[contributor] = email
return email
def findEmailFromUsername(username):
repos = findReposFromUsername(username)
for repo in repos:
email = findEmailFromContributor(username, repo, username)
if email:
print (username + ' : ' + email)
break
def findEmailsFromRepo(username, repo):
contributors = findContributorsFromRepo(username, repo)
print ('%s Total contributors: %s%i%s' % (info, green, len(contributors), end))
for contributor in contributors:
email = (findEmailFromContributor(username, repo, contributor))
if email:
print (contributor + ' : ' + email)
def findUsersFromOrganization(username):
response = get('https://api.github.com/orgs/%s/members?per_page=100' % username, auth=HTTPBasicAuth(uname, '')).text
members = re.findall(r'"login":"(.*?)"', response)
return members
def threader(function, arg):
threads = []
for i in arg:
task = threading.Thread(target=function, args=(i,))
threads.append(task)
for thread in threads:
thread.start()
for thread in threads:
thread.join()
del threads[:]
def flash(function, arg):
for begin in range(0, len(arg), thread_count):
end = begin + thread_count
splitted = arg[begin:end]
threader(function, splitted)
if targetOrganization:
usernames = findUsersFromOrganization(username)
flash(findEmailFromUsername, usernames)
elif targetUser:
findEmailFromUsername(username)
elif targetRepo:
findEmailsFromRepo(username, repo)
if output:
json_string = json.dumps(jsonOutput, indent=4)
savefile = open(output, 'w+')
savefile.write(json_string)
savefile.close()