Skip to content

Instantly share code, notes, and snippets.

@justhyped
Created April 21, 2024 13:09
Show Gist options
  • Select an option

  • Save justhyped/5c28e785642fccdf13265bf5d09e551a to your computer and use it in GitHub Desktop.

Select an option

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
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