diff --git a/.env b/.env new file mode 100644 index 0000000..cf32153 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +# Google OAuth 설정 +GOOGLE_ID=bot.imnya.ng@gmail.com diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..cf32153 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# Google OAuth 설정 +GOOGLE_ID=bot.imnya.ng@gmail.com diff --git a/addon/GoogleLoginHint.py b/addon/GoogleLoginHint.py new file mode 100644 index 0000000..6d80669 --- /dev/null +++ b/addon/GoogleLoginHint.py @@ -0,0 +1,71 @@ +import lib.target as target +from lib.report import save_report +import os +from urllib.parse import urlparse, parse_qs, urlencode, urlunparse +from dotenv import load_dotenv + +# .env 파일 로드 +load_dotenv(override=True) + +class GoogleLoginHint: + def __init__(self): + self.google_id = os.getenv('GOOGLE_ID', '') + if not self.google_id: + print("⚠️ Warning: GOOGLE_ID not found in .env file") + + async def request(self, flow): + """Google OAuth 요청을 가로채서 login_hint를 추가하거나 수정""" + req = flow.request + method = req.method + url = req.pretty_url + + # Google OAuth 인증 URL인지 확인 + if self._is_google_oauth_url(url): + print(f"🔍 Google OAuth URL detected: {url}") + + # URL 파싱 + parsed_url = urlparse(url) + query_params = parse_qs(parsed_url.query) + + # login_hint 추가 또는 수정 + if self.google_id: + query_params['login_hint'] = [self.google_id] + print(f"✅ Added/Updated login_hint: {self.google_id}") + + # 새로운 쿼리 스트링 생성 + new_query = urlencode(query_params, doseq=True) + + # 새로운 URL 생성 + new_url = urlunparse(( + parsed_url.scheme, + parsed_url.netloc, + parsed_url.path, + parsed_url.params, + new_query, + parsed_url.fragment + )) + + # 요청 URL 수정 + flow.request.pretty_url = new_url + print(f"🔄 Modified URL: {new_url}") + + + def _is_google_oauth_url(self, url): + """Google OAuth URL인지 확인""" + google_oauth_domains = [ + 'accounts.google.com', + 'oauth2.googleapis.com' + ] + + parsed_url = urlparse(url) + domain = parsed_url.netloc.lower() + + # Google OAuth 도메인 확인 + for google_domain in google_oauth_domains: + if google_domain in domain: + # OAuth 관련 경로 확인 + path = parsed_url.path.lower() + if any(oauth_path in path for oauth_path in ['/oauth2', '/auth', '/login']): + return True + + return False \ No newline at end of file diff --git a/addon/init.py b/addon/init.py index 78e616a..afb3db8 100644 --- a/addon/init.py +++ b/addon/init.py @@ -6,6 +6,7 @@ from csrf_check import CsrfChecker from nonce_check import NonceChecker from redirect_uri_check import RedirectBypassChecker from access_token import AccessTokenScanner +from GoogleLoginHint import GoogleLoginHint class PKCEAddon: def __init__(self): @@ -87,4 +88,13 @@ class RedirectBypassAddon: except Exception as e: print(f"[ERROR] RedirectBypass Addon failed: {e}") -addons = [PKCEAddon(), ScopeAddon(), CsrfAddon(), NonceAddon(), AccessTokenAddon(), RedirectBypassAddon()] +class GoogleLoginHintAddon(): + def __init__(self) -> None: + self.checker = GoogleLoginHint() + def request(self, flow: http.HTTPFlow): + try: + asyncio.run(self.checker.request(flow)) + except Exception as e: + print(f"[ERROR] GoogleLoginHint Addon failed: {e}") + +addons = [PKCEAddon(), ScopeAddon(), CsrfAddon(), NonceAddon(), AccessTokenAddon(), RedirectBypassAddon(), GoogleLoginHintAddon()]