Загрузка...

Скрипт Проблема с реверсом API

Тема в разделе Python создана пользователем TajikCoder 27 май 2025. 125 просмотров

Загрузка...
  1. TajikCoder
    TajikCoder Автор темы 27 май 2025 6 13 май 2025
    Делаю API для ⁡https://www.naturalreaders.com/commercial/ . Что-бы по блату генерировать голоса и пихать автоматически там куда мне нужно.
    После 5 минутного анализа выяснил что AccessKeyId, SecretKey, SessionToken получаются через https://cognito-identity.us-east-1.amazonaws.com/

    Python
    def get_creds():
    headers = {
    'x-amz-target': 'AWSCognitoIdentityService.GetCredentialsForIdentity',
    'content-type': 'application/x-amz-json-1.1'
    }
    payload = {"IdentityId": "us-east-1:012d266b-efc2-ce0d-a06c-693a3c72cd78"}

    try:
    response = requests.post("https://cognito-identity.us-east-1.amazonaws.com/",
    headers=headers, json=payload)
    response.raise_for_status()
    creds = response.json()['Credentials']
    return {
    'access_key': creds['AccessKeyId'],
    'secret_key': creds['SecretKey'],
    'session_token': creds['SessionToken']
    }
    except Exception as e:
    return "dalbaeb"
    Ответ сервера:
    Код
    {
    "access_key": "ASIAQCLJGNPX3OEGZ2CG",
    "secret_key": "+LpEWaAux2rZ5AhR8dQdfry/Q9oWgxiUXdFiLG7y",
    "session_token": "IQoJb3JpZ2luX2VjEJD//////////wEaCXVzLWVhc3QtMSJIMEYCIQDhhJpuiX+/Jmxpt+o7opVM6CVbNO1oHc6UUNqulzZJCQIhAKxu8QA70hL16Q9JPs5wqnpuZt2S0+aN+cgIwo5bfdYxKrEFCFkQABoMMDA1MDUyNDYwMDE1IgyNfPt4Uf0peqzA+xkqjgV5lUYkvnY/7SSVGAtU32r8JzX4U9anVOZxePU2yvZ4B1XQaNEoDX1EqyySIFpInDHfUKKGN4SDMLTHJTrZSYGYGcCtZqaBNGWvSbnpOB2rfqbd91Rc5Y3EdAJVaWfVPOVsV/2uwvKuMHKs+u7kRWu7sfQPn2B9FXdyqJ82MeKHzvNXfEEvz65R2xhdc146ITIBipedpNKIEjVj6BcQOAnvu+lNitD7MZWgzKClA72MFPCBoeqJDO/UtIHLMwcKy5/FMyCRx3qGjO+SVmdzPlE1U4ttTntFgZDQX7J+Pqx4bElKJc3TQilkmyKYjxjb/dnFcOFEnnsWOHsCPwQSwoROgJ6XGGUZHUDIz/IMmPe8GOwQcBHTY/qSGbTfeo3HlBmOjDo5/bH8jfpg0cHAa174pzCyHrZnXMevNKnjfL1E7A2CHGIjZzRRZEUYolmfqX0ymjwb5biDbyBKt3dy2xf7s48F319CVFD2J1vpAQZqFyL4CB3fEWMH8KFQBAg/psHnT7vsGLBoHParmrbmESymBIeENujLOi5nHEZQG3tt4lTBkASUTIORyVPszsRB39vJJfuLIQHE7nc0zwYsiNbx7NgxxauHqdbu2ciWhrO+oXCSwaG/AJC9cWk1HxpmUihAbcESrZRpkKyHJUvjol7SMIpPu88VGqZSaPo5G6eX9SabkS4PMKZ6yq7GlCh9bk/0e1n0zoJBbUoLCKIYXQEKZc8vf4E0emxLWOSBf/Fo3jkBWa9A8sxKdx1b9OxFTYv+tzffOO5AGq55S6JEElmGFtuFOntxxLf5DumPKtZHAC8sa9KriYTfZq6BmdLo/p7t8nqGW3sM4C7/r3HG4iSVLjaQJZB12QBQf7qmFjow6NfVwQY63AJKRaQbw3oHod84cR7avmID9BwPegmPy+4cUAUly5qrfNx99ISqjoseYrH0IDzUACuvyU5QTEbAY97apqmd2yrVC5z+OxypCUsC+W+w/y66uxMKSIFF8g2z/PtrwTIXkb7lGq+6hsU5q91006gwrrvOQup8qJplBQk4nOL8OEUfc1FgEjrb5Likl2s03PobHDP+VOKgWN4bOgLu/4ddKjXaCs5FkXLaLyAq1XMEAza0V4dkuH8HvwucIsA5gmFJaZdY/qZQPkBMfzj7X13KaKz5hem+vjAfVVVWDTv6Fk4CMofjoHYPQy49CgND4NomgS4aeEw02Zbi+yS05jaQEngP/zp47pWNcv6VB/qSZ4v6Jme7Q6w4fuio/Pw2Tyj4xPs7Y4BHPQx4jz3x7u0FB3nxJbctmT7Ys2B9szOLsK6gdq5Mv96h6Y7gi367impAkXmwo36+cdCai/Z1PWw="
    }
    Теперь кидаю запрос уже на сам API (https://l6m5prrx81.execute-api.us-east-1.amazonaws.com/prod220818/el/speakv2)

    Python
    class AWSSignatureV4:
    def __init__(self, access_key, secret_key, session_token, region='us-east-1'):
    self.access_key = access_key
    self.secret_key = secret_key
    self.session_token = session_token
    self.region = region

    def sign_request(self, method, url, headers, payload):
    parsed_url = urlparse(url)

    query_params = []
    if parsed_url.query:
    for param in parsed_url.query.split('&'):
    key, value = param.split('=', 1) if '=' in param else (param, '')
    query_params.append((key, value))
    query_params.sort()
    canonical_query_string = '&'.join([f'{k}={v}' for k, v in query_params])

    t = datetime.utcnow()
    amz_date = t.strftime('%Y%m%dT%H%M%SZ')
    date_stamp = t.strftime('%Y%m%d')

    headers.update({
    'host': parsed_url.netloc,
    'x-amz-date': amz_date,
    'x-amz-security-token': self.session_token
    })

    signed_headers = 'accept;content-type;host;x-amz-date;x-amz-security-token'
    canonical_headers = ''.join([f'{h}:{headers[k]}\n' for h in signed_headers.split(';')
    for k in headers if k.lower() == h])

    payload_hash = hashlib.sha256(payload.encode()).hexdigest()
    canonical_request = f'{method}\n{parsed_url.path}\n{canonical_query_string}\n{canonical_headers}\n{signed_headers}\n{payload_hash}'

    credential_scope = f'{date_stamp}/{self.region}/execute-api/aws4_request'
    string_to_sign = f'AWS4-HMAC-SHA256\n{amz_date}\n{credential_scope}\n{hashlib.sha256(canonical_request.encode()).hexdigest()}'

    k_date = hmac.new(f'AWS4{self.secret_key}'.encode(), date_stamp.encode(), hashlib.sha256).digest()
    k_region = hmac.new(k_date, self.region.encode(), hashlib.sha256).digest()
    k_service = hmac.new(k_region, b'execute-api', hashlib.sha256).digest()
    k_signing = hmac.new(k_service, b'aws4_request', hashlib.sha256).digest()

    signature = hmac.new(k_signing, string_to_sign.encode(), hashlib.sha256).hexdigest()

    headers['Authorization'] = f'AWS4-HMAC-SHA256 Credential={self.access_key}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}'
    return headers


    def tts(text_array, voice_params=None):
    creds = get_cognito_credentials()

    defaults = {
    'display_name': 'Larisa Actrisa',
    'speed': '180',
    'style': '',
    'locale': 'standard',
    'model': 'v2',
    'voice_id': 'AB9XsbSA4eLG12t2myjN'
    }
    voice_params = {k: str(v) for k, v in (voice_params or defaults).items() if v}

    base_url = (
    "https://l6m5prrx81.execute-api.us-east-1.amazonaws.com/prod220818/el/speakv2"
    )
    query = '&'.join(f"{quote(k, safe='')}={quote(v, safe='')}"
    for k, v in sorted(voice_params.items()))
    url = f"{base_url}?{query}"

    headers = {
    'Accept': 'audio/mpeg',
    'Content-Type': 'application/json',
    'sec-ch-ua-platform': '"Windows"',
    'Referer': 'https://www.naturalreaders.com/',
    'sec-ch-ua': '"Chromium";v="136", "Microsoft Edge";v="136", "Not.A/Brand";v="99"',
    'sec-ch-ua-mobile': '?0',
    'User-Agent': (
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
    'AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0'
    )
    }
    payload = json.dumps({'textArray': text_array})

    signer = AWSSignatureV4(
    access_key=creds['access_key'],
    secret_key=creds['secret_key'],
    session_token=creds['session_token'],
    region='us-east-1'
    )
    signed = signer.sign_request('POST', url, headers, payload)

    response = requests.post(url, headers=signed, data=payload)
    print(f"Status -> {response.status_code}")
    print(f"Headers -> {dict(response.headers)}")
    if response.status_code == 200 and response.headers.get('content-type', '').startswith('audio/'):
    with open('test.mp3', 'wb') as f:
    f.write(response.content)
    print("ok")
    else:
    print(f"Body -> {response.text}")
    return response
    Получаю статус 200 иии... Вместо ожидаемого mp3 файла получаю хуй на рыло :smile_hookah: в виде "Thank You"


    Код
    Status -> 200
    Headers -> {'Content-Type': 'application/json', 'Content-Length': '11', 'Connection': 'keep-alive', 'Date': 'Tue, 27 May 2025 07:48:53 GMT', 'X-Amzn-Trace-Id': 'Root=1-68356e65-123e2d573e7a93fb755faf5b;Parent=490fa183c66525f4;Sampled=0;Lineage=1:31c24b2b:0', 'x-amzn-RequestId': 'a3c648c8-b3c8-473f-9b40-472ff3ea5f73', 'Access-Control-Allow-Origin': 'noOrigin', 'Access-Control-Allow-Headers': 'Content-Type', 'x-amz-apigw-id': 'LN4v8HtJoAMEoTg=', 'Access-Control-Allow-Methods': 'OPTIONS', 'X-Cache': 'Miss from cloudfront', 'Via': '1.1 41fc52a84466debf784d2dbdb0b64b36.cloudfront.net (CloudFront)', 'X-Amz-Cf-Pop': 'ARN53-P2', 'X-Amz-Cf-Id': 'Hyun1yFeThA2_d_UYlyzXxOycjqgvjfSHjFvOgQtp2_bW4JbokH-Pg=='}
    Body -> "Thank you"
    Смутило то что когда запрос отправляется с браузера то ответный заголовок access-control-allow-methods у меня совсем другой:
    Браузер: access-control-allow-methods: POST, GET, OPTIONS, DELETE
    Скрипт: access-control-allow-methods: OPTIONS
     
    27 май 2025 Изменено
  2. s3th
  3. s3th
    (70 строка)
    а почему у тебя тут нету x-amz-date и x-amz-security-token?
     
    27 май 2025 Изменено
    1. Посмотреть предыдущие комментарии (7)
    2. TajikCoder Автор темы
      s3th, Вот что скрипт по итогу передает в заголовках:


      Код
      {
      "Accept": "audio/mpeg",
      "Content-Type": "application/json",
      "sec-ch-ua-platform": "\"Windows\"",
      "Referer": "https://www.naturalreaders.com/",
      "sec-ch-ua": "\"Chromium\";v=\"136\", \"Microsoft Edge\";v=\"136\", \"Not.A/Brand\";v=\"99\"",
      "sec-ch-ua-mobile": "?0",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0",
      "host": "l6m5prrx81.execute-api.us-east-1.amazonaws.com",
      "x-amz-date": "20250527T080840Z",
      "x-amz-security-token": "IQoJb3JpZ2luX2VjEJH//////////wEaCXVzLWVhc3QtMSJHMEUCIE5iVjOcJ603nr1uUNOhw9D48IpvxqvJVWn8sIQha/VNAiEA/gLxpFdb8e5uJ7hOrK+0zn8uaYq9foooK7E2NnjahGUqsQUIWRAAGgwwMDUwNTI0NjAwMTUiDO00aKSLZiXzQ6gU0SqOBW5DT/kKonyiAh/ADE8SHqXhM8/GsxSeuiA9Ud/SEn65VW97UCo7Rbpl+T/DvD1CVFJIdxUaM35LqSA6hqtKEWVHcP4WwZjbMEx+nfNmRpfSAlmL2CKGIBccXcGtTVvX3Ob+m6rxlIDl3uAui6yGBKXFcdxTH7SJNouTMlFf0270qCNjt4+mKd9Jz8Q9NzYkKoL5yq18nCMr3PhvIZnKu8Kqm2E8j3BsRoAJW/E1MfetosUxQcZRoME6n7IJZWj5srST4omBp2Mdgb/Bz/DaIlGLrT//6dVVbCLRbDS2TZhdT497mHl24KOelt5hZSQMRipNhfn7SDNnkhQUrp1L9+lyT5IzcFZauqCZXweNsoolqFFFSvxMuxIM0fk/B0HlremDLgW+vu1r15f7zIO+bUbU8Kvz3Ji/3+GfDEUfw/V+FUQJq9pQEBGec0TTaFYcWvx/QDQK8jOqXCudffu9/TXSGAgmX4Fhe/4NUu2QoR+BB+CjFTGS3Xnb758iOqltf+wTMIIyWnjyTpJNh3EwDrv3d2/m526D63cho5eHqLilwVUOtTcDk9ubLcrcCvDGpGYKAHGBl7BN+q8KDBpptRU8K//Rc7JeV7YmyTwX9HNdZYZfQRRnTwJq8OkBsWWuXxaZkfAoy6l/5w5pbzOx7Wd2XkSuUyGIbJzswN0feoRXgOzTzLcCLWFA7Ksz2v3rKzmTB8ysoNTcDfpsouB+Go5lwMyqYtZ9d7Xw5HWu0nlSReai8g+lLtdHyE/Dm011UotwxRM34qI+QtYQ0m6d0qWVuLa1Ze5wDAx4Jz1xNlA7qkpkWRWDiFbQoyjrE9ro87BEkzV0LgCj56BX2HSAHZ6nLGVhARuV+H5Tm4cM+TCG5tXBBjrdAvJkAukOxL1VswiNAj3d+rMa9xHian+0kUVwAAD8mPzdQB8tlx7NTFUG4kNCZihrsMb/lpn7MWzrx52tgy74Z6Vd/FWgH+6HXQzeDqreEhf7Lh4a4F6qDn569ORs8YOyN+378rbjLkVA0qHrXHxM88w2e19bywRCNP1qcSHGE7HLvIjGtbGVqJ2cp+6crHgMAVYF4CM5ilJoVYC1Ph8FuKARY7EShQx3yV9R5/58ReLM76gVo+Zk4U1Dfn0xR6/NSUZocCtNU+G7dpfhHAGHNZiwSCp5dqY7RTMmAzi2/j2UeafSlUlSeOvNi1i/fS0TrQC4CuxZRMROD0OhuPjr7igD85uZ1n+g6LSE5PRtVlgA9xgM7zrf/xnBOBASRxIa17oNCh20Ko7ADNiYjyDnvx/J7nBIDBWALty7w6o+FYtawMyuxn1nnx14GoFjKpAVkdYoWKMEwc4TXWvWQ/g=",
      "Authorization": "AWS4-HMAC-SHA256 Credential=ASIAQCLJGNPX7OSZKXQW/20250527/us-east-1/execute-api/aws4_request, SignedHeaders=accept;content-type;host;x-amz-date;x-amz-security-token, Signature=ca1abbb16c1cb5a3069e8db57809b614d79b52e0fa771500fb5798e5b0bff640"
      }
    3. s3th
      TajikCoder, выведи print(signed), payload в массив строк засунь, voice_params проверь, может криво запонил, сделай тестовый запрос, вместо текущего пайлоада, отдай ему кривой - payload = {'textArray': 'test'}, посмотри че отдаст
      27 май 2025 Изменено
    4. TajikCoder Автор темы
      s3th,
      Вывод print(signed) выше
      Был проеб, не указывался style, исправил - все тот же 200, все тот же "Thank You"
      Отправил "кривой" пейлоад - таже самая хуйня
Top