Created
April 21, 2024 13:09
-
-
Save justhyped/5c28e785642fccdf13265bf5d09e551a to your computer and use it in GitHub Desktop.
This script shows how to solve Akamai's Crypto Challenge using the Hyper Solutions SDK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import time | |
| from typing import Optional | |
| from urllib.parse import urlparse | |
| from tls_client import Session | |
| from tls_client.response import Response | |
| from hyper_sdk.akamai import SecCptChallenge | |
| USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" | |
| CLIENT_HINTS = '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' | |
| class Challenge: | |
| def __init__(self, page_url: str, client: Session): | |
| self.client = client | |
| self.challenge: Optional[SecCptChallenge] = None | |
| self.page_url = page_url | |
| self.base_url = "" | |
| def solve_sec_cpt(self) -> None: | |
| self._make_initial_request() | |
| self.challenge.sleep() | |
| self._post_pow() | |
| self._verify_challenge() | |
| sec_cpt_cookie = self._get_cookie("sec_cpt") | |
| if not sec_cpt_cookie or "~3~" not in sec_cpt_cookie: | |
| raise Exception("Invalid sec_cpt cookie returned") | |
| def _make_initial_request(self) -> None: | |
| headers = { | |
| "sec-ch-ua": CLIENT_HINTS, | |
| "sec-ch-ua-mobile": "?0", | |
| "sec-ch-ua-platform": '"Windows"', | |
| "upgrade-insecure-requests": "1", | |
| "user-agent": USER_AGENT, | |
| "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", | |
| "sec-fetch-site": "none", | |
| "sec-fetch-mode": "navigate", | |
| "sec-fetch-user": "?1", | |
| "sec-fetch-dest": "document", | |
| "accept-encoding": "gzip, deflate, br", | |
| "accept-language": "en-US,en;q=0.9", | |
| } | |
| self.client.header_order = ["sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "upgrade-insecure-requests", "user-agent", "accept", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "accept-encoding", "accept-language"] | |
| response = self.client.get(self.page_url, headers=headers, allow_redirects=False) | |
| self._handle_response(response) | |
| parsed_url = urlparse(self.page_url) | |
| self.base_url = f"{parsed_url.scheme}://{parsed_url.netloc}" | |
| self.challenge = SecCptChallenge.parse(response.text) | |
| def _post_pow(self) -> None: | |
| payload = self.challenge.generate_sec_cpt_payload(self._get_cookie("sec_cpt")) | |
| url = f"{self.base_url}/_sec/verify?provider=crypto" | |
| headers = { | |
| "sec-ch-ua": CLIENT_HINTS, | |
| "sec-ch-ua-platform": '"Windows"', | |
| "sec-ch-ua-mobile": "?0", | |
| "user-agent": USER_AGENT, | |
| "content-type": "text/plain;charset=UTF-8", | |
| "accept": "*/*", | |
| "origin": self.base_url, | |
| "sec-fetch-site": "same-origin", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-dest": "empty", | |
| "referer": f"{self.base_url}{self.challenge.challenge_path}", | |
| "accept-encoding": "gzip, deflate, br, zstd", | |
| "accept-language": "en-US,en;q=0.9", | |
| } | |
| self.client.header_order = ["content-length", "sec-ch-ua", "sec-ch-ua-platform", "sec-ch-ua-mobile", "user-agent", "content-type", "accept", "origin", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-dest", "referer", "accept-encoding", "accept-language", "cookie"] | |
| response = self.client.post(url, headers=headers, data=payload) | |
| self._handle_response(response) | |
| def _verify_challenge(self) -> None: | |
| url = f"{self.base_url}/_sec/cp_challenge/verify" | |
| headers = { | |
| "user-agent": USER_AGENT, | |
| "accept": "*/*", | |
| "sec-gpc": "1", | |
| "sec-fetch-site": "same-origin", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-dest": "empty", | |
| "referer": self.page_url, | |
| "accept-encoding": "gzip, deflate, br", | |
| "accept-language": "en-US,en;q=0.9", | |
| } | |
| self.client.header_order = ["user-agent", "accept", "sec-gpc", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-dest", "referer", "accept-encoding", "accept-language", "cookie"] | |
| response = self.client.get(url, headers=headers) | |
| self._handle_response(response) | |
| def _get_cookie(self, cookie_name: str) -> Optional[str]: | |
| for cookie in self.client.cookies: | |
| if cookie.name == cookie_name: | |
| return cookie.value | |
| return None | |
| @staticmethod | |
| def _handle_response(response: Response) -> None: | |
| if response.status_code != 200: | |
| raise Exception(f"Request failed with status code: {response.status_code}") | |
| if __name__ == "__main__": | |
| client = Session(client_identifier="chrome_120") | |
| client.proxies = "http://127.0.0.1:8888" | |
| challenge = Challenge("https://www.similarweb.com/website/google.com", client) | |
| challenge.solve_sec_cpt() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment