Skip to content

Commit e8b0669

Browse files
committed
Merged
2 parents e261ae9 + 413b577 commit e8b0669

13 files changed

Lines changed: 322 additions & 175 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Then, use GHunt Companion to complete the login.
5252

5353
The extension is available on the following stores :\
5454
\
55-
[![Firefox](https://files.catbox.moe/5g2ld5.png)](https://addons.mozilla.org/en-US/firefox/addon/ghunt-companion/)   [![Chrome](https://storage.googleapis.com/web-dev-uploads/image/WlD8wC6g8khYWPJUsQceQkhXSlv1/UV4C4ybeBTsZt43U4xis.png)](https://chrome.google.com/webstore/detail/ghunt-companion/dpdcofblfbmmnikcbmmiakkclocadjab)
55+
[![Firefox](https://files.catbox.moe/5g2ld5.png)](https://addons.mozilla.org/en-US/firefox/addon/ghunt-companion/)   [![Chrome](https://developer.chrome.com/static/docs/webstore/branding/image/206x58-chrome-web-bcb82d15b2486.png)](https://chrome.google.com/webstore/detail/ghunt-companion/dpdcofblfbmmnikcbmmiakkclocadjab)
5656

5757
## Modules
5858

@@ -116,7 +116,7 @@ This project is under [AGPL Licence](https://choosealicense.com/licenses/agpl-3.
116116

117117
Thanks to these awesome people for supporting me !
118118

119-
<!-- sponsors --><a href="https://github.com/BlWasp"><img src="https://github.com/BlWasp.png" width="50px" alt="BlWasp" /></a>&nbsp;&nbsp;<a href="https://github.com/C3n7ral051nt4g3ncy"><img src="https://github.com/C3n7ral051nt4g3ncy.png" width="50px" alt="C3n7ral051nt4g3ncy" /></a>&nbsp;&nbsp;<a href="https://github.com/gingeleski"><img src="https://github.com/gingeleski.png" width="50px" alt="gingeleski" /></a>&nbsp;&nbsp;<!-- sponsors -->
119+
<!-- sponsors --><a href="https://github.com/BlWasp"><img src="https://github.com/BlWasp.png" width="50px" alt="BlWasp" /></a>&nbsp;&nbsp;<a href="https://github.com/gingeleski"><img src="https://github.com/gingeleski.png" width="50px" alt="gingeleski" /></a>&nbsp;&nbsp;<!-- sponsors -->
120120

121121
\
122122
You like my work ?\

examples/email_registered.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
import httpx
24
import asyncio
35

@@ -8,7 +10,8 @@
810

911
async def main():
1012
if not sys.argv[1:]:
11-
exit("Please give an email address.")
13+
print("Please give an email address.")
14+
exit()
1215

1316
as_client = httpx.AsyncClient() # Async Client
1417

ghunt/ghunt.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import sys
23

34

@@ -6,7 +7,7 @@ def main():
67
if (version < (3, 10)):
78
print('[-] GHunt only works with Python 3.10+.')
89
print(f'Your current Python version : {version.major}.{version.minor}.{version.micro}')
9-
sys.exit(1)
10+
sys.exit(os.EX_SOFTWARE)
1011

1112
from ghunt.cli import parse_and_run
1213
from ghunt.helpers.banner import show_banner

ghunt/helpers/auth.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import json
33
import base64
4+
import os
45
from typing import *
56

67
import httpx
@@ -174,7 +175,7 @@ def auth_dialog() -> Tuple[Dict[str, str], str] :
174175
"=> https://github.com/mxrch/ghunt_companion\n\n"
175176
"[1] (Companion) Put GHunt on listening mode (currently not compatible with docker)\n"
176177
"[2] (Companion) Paste base64-encoded authentication\n"
177-
"[3] Enter the oauth_token (stats with \"oauth2_4/\")\n"
178+
"[3] Enter the oauth_token (starts with \"oauth2_4/\")\n"
178179
"[4] Enter the master token (starts with \"aas_et/\")\n"
179180
"Choice => ")
180181

@@ -196,7 +197,8 @@ def auth_dialog() -> Tuple[Dict[str, str], str] :
196197
master_token = input(f"Master token => ").strip('" ')
197198

198199
else:
199-
exit("Please choose a valid choice. Exiting...")
200+
print("Please choose a valid choice. Exiting...")
201+
exit()
200202

201203
return oauth_token, master_token
202204

@@ -213,4 +215,4 @@ async def load_and_auth(as_client: httpx.AsyncClient, help=True) -> GHuntCreds:
213215

214216
await check_and_gen(as_client, creds)
215217

216-
return creds
218+
return creds

ghunt/helpers/ia.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from ghunt import globals as gb
24
from ghunt.apis.vision import VisionHttp
35

@@ -20,7 +22,8 @@ async def detect_face(vision_api: VisionHttp, as_client: httpx.AsyncClient, imag
2022
break
2123
await asyncio.sleep(0.5)
2224
else:
23-
exit("\n[-] Vision API keeps rate-limiting.")
25+
print("\n[-] Vision API keeps rate-limiting.")
26+
exit(os.EX_UNAVAILABLE)
2427

2528
if are_faces_found:
2629
if len(faces_results.face_annotations) > 1:

ghunt/helpers/listener.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from http.server import BaseHTTPRequestHandler, HTTPServer
23
from typing import *
34

@@ -45,7 +46,8 @@ def run(server_class=HTTPServer, handler_class=Server, port=60067):
4546
break
4647

4748
except KeyboardInterrupt:
48-
exit("[-] Exiting...")
49+
print("[-] Exiting...")
50+
exit(os.CLD_KILLED)
4951
else:
5052
if handler_class.data_bridge.data:
5153
print("[+] Received cookies !")

ghunt/modules/drive.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from ghunt.helpers.utils import *
24
from ghunt.objects.base import DriveExtractedUser, GHuntCreds
35
from ghunt.apis.drive import DriveHttp
@@ -38,7 +40,8 @@ async def hunt(as_client: httpx.AsyncClient, file_id: str, json_file: bool=Path)
3840
drive = DriveHttp(ghunt_creds)
3941
file_found, file = await drive.get_file(as_client, file_id)
4042
if not file_found:
41-
exit("[-] The file wasn't found.")
43+
print("[-] The file wasn't found.")
44+
exit()
4245

4346
is_folder = file.mime_type == "application/vnd.google-apps.folder"
4447
file_type = drive_knownledge.mime_types.get(file.mime_type)

ghunt/modules/email.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from ghunt import globals as gb
24
from ghunt.helpers.utils import get_httpx_client
35
from ghunt.objects.base import GHuntCreds
@@ -24,7 +26,8 @@ async def hunt(as_client: httpx.AsyncClient, email_address: str, json_file: Path
2426
# vision_api = VisionHttp(ghunt_creds)
2527
is_found, target = await people_pa.people_lookup(as_client, email_address, params_template="max_details")
2628
if not is_found:
27-
exit("[-] The target wasn't found.")
29+
print("[-] The target wasn't found.")
30+
exit()
2831

2932
if json_file:
3033
json_results = {}
@@ -37,7 +40,8 @@ async def hunt(as_client: httpx.AsyncClient, email_address: str, json_file: Path
3740
print(f"- {container.title()}")
3841

3942
if not "PROFILE" in containers:
40-
exit("[-] Given information does not match a public Google Account.")
43+
print("[-] Given information does not match a public Google Account.")
44+
exit()
4145

4246
container = "PROFILE"
4347

@@ -66,7 +70,10 @@ async def hunt(as_client: httpx.AsyncClient, email_address: str, json_file: Path
6670
# await ia.detect_face(vision_api, as_client, target.coverPhotos[container].url)
6771
print()
6872

69-
print(f"Last profile edit : {target.sourceIds[container].lastUpdated.strftime('%Y/%m/%d %H:%M:%S (UTC)')}\n")
73+
if target.sourceIds[container].lastUpdated:
74+
print(f"Last profile edit : {target.sourceIds[container].lastUpdated.strftime('%Y/%m/%d %H:%M:%S (UTC)')}\n")
75+
else:
76+
gb.rc.print(f"Last profile edit : [italic]Not found.[/italic]\n")
7077

7178
if container in target.emails:
7279
print(f"Email : {target.emails[container].value}")
@@ -160,4 +167,4 @@ async def hunt(as_client: httpx.AsyncClient, email_address: str, json_file: Path
160167
f.write(json.dumps(json_results, cls=GHuntEncoder, indent=4))
161168
gb.rc.print(f"\n[+] JSON output wrote to {json_file} !", style="italic")
162169

163-
await as_client.aclose()
170+
await as_client.aclose()

ghunt/modules/gaia.py

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from ghunt import globals as gb
24
from ghunt.objects.base import GHuntCreds
35
from ghunt.apis.peoplepa import PeoplePaHttp
@@ -16,108 +18,108 @@ async def hunt(as_client: httpx.AsyncClient, gaia_id: str, json_file: Path=None)
1618
if not as_client:
1719
as_client = get_httpx_client()
1820

19-
# ghunt_creds = await auth.load_and_auth(as_client)
21+
ghunt_creds = await auth.load_and_auth(as_client)
2022

2123
# #gb.rc.print("\n[+] Target found !", style="spring_green3")
2224

23-
# people_pa = PeoplePaHttp(ghunt_creds)
25+
people_pa = PeoplePaHttp(ghunt_creds)
2426
# # vision_api = VisionHttp(ghunt_creds)
25-
# is_found, target = await people_pa.people(as_client, gaia_id, params_template="max_details")
26-
# if not is_found:
27-
# exit("[-] The target wasn't found.")
27+
is_found, target = await people_pa.people(as_client, gaia_id, params_template="max_details")
28+
if not is_found:
29+
exit("[-] The target wasn't found.")
2830

29-
# if json_file:
30-
# json_results = {}
31+
if json_file:
32+
json_results = {}
3133

32-
# containers = target.sourceIds
34+
containers = target.sourceIds
3335

34-
# if len(containers) > 1 or not "PROFILE" in containers:
35-
# print("[!] You have this person in these containers :")
36-
# for container in containers:
37-
# print(f"- {container.title()}")
36+
if len(containers) > 1 or not "PROFILE" in containers:
37+
print("[!] You have this person in these containers :")
38+
for container in containers:
39+
print(f"- {container.title()}")
3840

39-
# if not "PROFILE" in containers:
40-
# exit("[-] Given information does not match a public Google Account.")
41+
if not "PROFILE" in containers:
42+
exit("[-] Given information does not match a public Google Account.")
4143

42-
# container = "PROFILE"
44+
container = "PROFILE"
4345

44-
# gb.rc.print("🙋 Google Account data\n", style="plum2")
46+
gb.rc.print("🙋 Google Account data\n", style="plum2")
4547

46-
# # if container in target.names:
47-
# # print(f"Name : {target.names[container].fullname}\n")
48+
# if container in target.names:
49+
# print(f"Name : {target.names[container].fullname}\n")
4850

49-
# if container in target.profilePhotos:
50-
# if target.profilePhotos[container].isDefault:
51-
# print("[-] Default profile picture")
52-
# else:
53-
# print("[+] Custom profile picture !")
54-
# print(f"=> {target.profilePhotos[container].url}")
51+
if container in target.profilePhotos:
52+
if target.profilePhotos[container].isDefault:
53+
print("[-] Default profile picture")
54+
else:
55+
print("[+] Custom profile picture !")
56+
print(f"=> {target.profilePhotos[container].url}")
5557

5658
# # await ia.detect_face(vision_api, as_client, target.profilePhotos[container].url)
5759
# print()
5860

59-
# if container in target.coverPhotos:
60-
# if target.coverPhotos[container].isDefault:
61-
# print("[-] Default cover picture\n")
62-
# else:
63-
# print("[+] Custom cover picture !")
64-
# print(f"=> {target.coverPhotos[container].url}")
61+
if container in target.coverPhotos:
62+
if target.coverPhotos[container].isDefault:
63+
print("[-] Default cover picture\n")
64+
else:
65+
print("[+] Custom cover picture !")
66+
print(f"=> {target.coverPhotos[container].url}")
6567

6668
# # await ia.detect_face(vision_api, as_client, target.coverPhotos[container].url)
67-
# print()
69+
print()
6870

69-
# print(f"Last profile edit : {target.sourceIds[container].lastUpdated.strftime('%Y/%m/%d %H:%M:%S (UTC)')}\n")
71+
print(f"Last profile edit : {target.sourceIds[container].lastUpdated.strftime('%Y/%m/%d %H:%M:%S (UTC)')}\n")
7072

71-
# print(f"Gaia ID : {target.personId}\n")
73+
print(f"Gaia ID : {target.personId}\n")
7274

73-
# if container in target.profileInfos:
74-
# print("User types :")
75-
# for user_type in target.profileInfos[container].userTypes:
76-
# definition = get_user_type_definition(user_type)
77-
# gb.rc.print(f"- {user_type} [italic]({definition})[/italic]")
75+
if container in target.profileInfos:
76+
print("User types :")
77+
for user_type in target.profileInfos[container].userTypes:
78+
definition = get_user_type_definition(user_type)
79+
gb.rc.print(f"- {user_type} [italic]({definition})[/italic]")
7880

79-
# gb.rc.print(f"\n📞 Google Chat Extended Data\n", style="light_salmon3")
81+
gb.rc.print(f"\n📞 Google Chat Extended Data\n", style="light_salmon3")
8082

81-
# #print(f"Presence : {target.extendedData.dynamiteData.presence}")
82-
# print(f"Entity Type : {target.extendedData.dynamiteData.entityType}")
83-
# #print(f"DND State : {target.extendedData.dynamiteData.dndState}")
84-
# gb.rc.print(f"Customer ID : {x if (x := target.extendedData.dynamiteData.customerId) else '[italic]Not found.[/italic]'}")
83+
#print(f"Presence : {target.extendedData.dynamiteData.presence}")
84+
print(f"Entity Type : {target.extendedData.dynamiteData.entityType}")
85+
#print(f"DND State : {target.extendedData.dynamiteData.dndState}")
86+
gb.rc.print(f"Customer ID : {x if (x := target.extendedData.dynamiteData.customerId) else '[italic]Not found.[/italic]'}")
8587

86-
# gb.rc.print(f"\n🌐 Google Plus Extended Data\n", style="cyan")
88+
gb.rc.print(f"\n🌐 Google Plus Extended Data\n", style="cyan")
8789

88-
# print(f"Entreprise User : {target.extendedData.gplusData.isEntrepriseUser}")
89-
# #print(f"Content Restriction : {target.extendedData.gplusData.contentRestriction}")
90+
print(f"Entreprise User : {target.extendedData.gplusData.isEntrepriseUser}")
91+
#print(f"Content Restriction : {target.extendedData.gplusData.contentRestriction}")
9092

91-
# if container in target.inAppReachability:
92-
# print("\n[+] Activated Google services :")
93-
# for app in target.inAppReachability[container].apps:
94-
# print(f"- {app}")
93+
if container in target.inAppReachability:
94+
print("\n[+] Activated Google services :")
95+
for app in target.inAppReachability[container].apps:
96+
print(f"- {app}")
9597

9698
gb.rc.print("\n🗺️ Maps data", style="green4")
9799

98100
err, stats = await gmaps.get_reviews(as_client, gaia_id)
99101
gmaps.output(err, stats, gaia_id)
100102

101-
# if json_file:
102-
# if container == "PROFILE":
103-
# json_results[f"{container}_CONTAINER"] = {
104-
# "profile": target,
105-
# "maps": {
106-
# "photos": photos,
107-
# "reviews": reviews,
108-
# "stats": stats
109-
# }
110-
# }
111-
# else:
112-
# json_results[f"{container}_CONTAINER"] = {
113-
# "profile": target
114-
# }
103+
if json_file:
104+
if container == "PROFILE":
105+
json_results[f"{container}_CONTAINER"] = {
106+
"profile": target,
107+
"maps": {
108+
# "photos": photos,
109+
# "reviews": reviews,
110+
"stats": stats
111+
}
112+
}
113+
else:
114+
json_results[f"{container}_CONTAINER"] = {
115+
"profile": target
116+
}
115117

116-
# if json_file:
117-
# import json
118-
# from ghunt.objects.encoders import GHuntEncoder;
119-
# with open(json_file, "w", encoding="utf-8") as f:
120-
# f.write(json.dumps(json_results, cls=GHuntEncoder, indent=4))
121-
# gb.rc.print(f"\n[+] JSON output wrote to {json_file} !", style="italic")
118+
if json_file:
119+
import json
120+
from ghunt.objects.encoders import GHuntEncoder;
121+
with open(json_file, "w", encoding="utf-8") as f:
122+
f.write(json.dumps(json_results, cls=GHuntEncoder, indent=4))
123+
gb.rc.print(f"\n[+] JSON output wrote to {json_file} !", style="italic")
122124

123125
await as_client.aclose()

ghunt/modules/geolocate.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from ghunt import globals as gb
24
from ghunt.helpers.utils import get_httpx_client
35
from ghunt.apis.geolocation import GeolocationHttp
@@ -16,12 +18,14 @@ async def main(as_client: httpx.AsyncClient, bssid: str, input_file: Path, json_
1618
body = None
1719
if input_file:
1820
if not input_file.exists():
19-
exit(f"[-] The input file \"{input_file}\" doesn't exist.")
21+
print(f"[-] The input file \"{input_file}\" doesn't exist.")
22+
exit()
2023
with open(input_file, "r", encoding="utf-8") as f:
2124
try:
2225
body = json.load(f)
2326
except json.JSONDecodeError:
24-
exit("[-] The input file is not a valid JSON file.")
27+
print(f"[-] The input file \"{input_file}\" is not a valid JSON file.")
28+
exit()
2529

2630
if not as_client:
2731
as_client = get_httpx_client()
@@ -31,7 +35,8 @@ async def main(as_client: httpx.AsyncClient, bssid: str, input_file: Path, json_
3135
geo_api = GeolocationHttp(ghunt_creds)
3236
found, resp = await geo_api.geolocate(as_client, bssid=bssid, body=body)
3337
if not found:
34-
exit("[-] The location wasn't found.")
38+
print("[-] The location wasn't found.")
39+
exit()
3540

3641
geolocator = Nominatim(user_agent="nominatim")
3742
location = geolocator.reverse(f"{resp.location.latitude}, {resp.location.longitude}", timeout=10)

0 commit comments

Comments
 (0)