FailSpy / humble-steam-key-redeemer

Python script to extract all Humble Bundle keys and redeem them on Steam automagically.
132 stars 27 forks source link

Unable to get past login prompts #26

Closed Milzstream closed 1 year ago

Milzstream commented 2 years ago

After installing the requirements and running the .bat I am prompted to enter my email/pass and then told to press enter to close the terminal window. Below is what is in the error log.

Note I am running this on windows and I have python 3.9.0.

Traceback (most recent call last):
  File "C:\Users\ellio\Desktop\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 738, in <module>
    humble_login(humble_session)
  File "C:\Users\ellio\Desktop\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 146, in humble_login
    login_json = r.json()
  File "C:\Python39\lib\site-packages\requests\models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "C:\Python39\lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "C:\Python39\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python39\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
mcwnuq commented 2 years ago

Same here. ( Windows 10, Python 3.8 in WSL2 Ubuntu 20.04 )

marcoslonggo commented 2 years ago

Same here. Looks like we are getting a <Response [403]> on the call the API for login here r = session.post(HUMBLE_LOGIN_API, data=payload, headers=headers)
and then this gives the error when parsing the json login_json = r.json().

stinodes commented 2 years ago

The response contains a HTML-page, saying they are using a security service to protect themselves from online attacks.

psychicteeth commented 2 years ago

Any way around this?

metafarion commented 2 years ago

I think we might constitute an "online attack"

But c'mon Humble, how can y'all NOT expect us to have an insane backlog of keys? This is a very predictable problem.

SavageCore commented 2 years ago

Yup, it's a farce. Bundles of hundreds of keys need to be handled differently. 🤷

I created this quick and dirty userscript to export all keys from https://www.humblebundle.com/home/keys to a CSV file. Note: "reveal keys" does not work correctly. It "clicks" reveal and waits 2 seconds but usually, that isn't enough time to reveal, I need to use a MutationObserver or something to detect it being revealed.

Once I had all the keys I fed them to ASF and it's slowly redeeming them. (You get banned for an hour after 10 bad activations).

metafarion commented 2 years ago

Note: "reveal keys" does not work correctly. It "clicks" reveal and waits 2 seconds but usually, that isn't enough time to reveal, I need to use a MutationObserver or something to detect it being revealed.

Once I had all the keys I fed them to ASF and it's slowly redeeming them. (You get banned for an hour after 10 bad activations).

You know... I am 1000% ok with it taking a long long time for keys to get scraped and redeemed. I made this point in a different discussion about itch.io's giant bundles: It's not about clicking a button and instantly having 1000 games in our pocket, it's about saving our fingers and eyeballs from tedious busywork. Humble/itch/Steam/whoever has server capacity to consider, and they're right to do so. An automated system that redeemed one key every hour, hell even every six hours... That'd be FINE by me, just don't make me do more repetitive computing tasks. My RSI is bad enough already.

tobbetuna commented 2 years ago

Same problem here. Tried this tool a few months back without any succsess cause i have 3-4 years of unredeemed games, and as all other in here probably just got the Ukraine-pack.. :)

JonathanHarford commented 2 years ago

..."linked a pull request that will close this issue"? That's not what I intended.

FailSpy commented 2 years ago

FWIW, I'm investigating this issue. Been busy and quite frankly almost missed the Ukraine support bundle!

Seems cloudscraper isn't quite enough to get around the particular bot protection Humble Bundle has. Hopefully will have updates soon.

LimLims commented 2 years ago

I've had pretty good luck with pyppeteer to evade bot detection.

kerderf commented 2 years ago

It looks like cloudscraper has a newer version that what's listed in the requirements.txt 1.2.60 vs 1.2.58 in your requirements.txt. Do you know if they have fixed this issue with the new 1.2.60 release?

oneandonlyjason commented 2 years ago

It looks like cloudscraper has a newer version that what's listed in the requirements.txt 1.2.60 vs 1.2.58 in your requirements.txt. Do you know if they have fixed this issue with the new 1.2.60 release?

I already switched it to the newer Version of Cloudscraper, same Problem

caraar12345 commented 2 years ago

Is it worth trying without CloudScraper? 🤔

I'm not sure how things are different with the login prompt, but I've got a Humble Choice script (caraar12345/humble-choice-database) which is able to scrape with just the requests library!

moonlightelite commented 2 years ago

I am pretty sure it's the SSL fingerprinting done by Cloudflare that trips the detection. I copied the POST request (using Chrome's Copy as mCurl) and used it in Bash, the request failed (403). But when I setup mitmproxy and set Curl to use mitmproxy as the HTTP proxy, the Curl request goes thru (401).

I tried to set CloudScraper to use mitmproxy but the request still doesn't work. If anyone has any additional insight I'd appreciate it.

LimLims commented 2 years ago

Cloudflare keeps a naughty list of ips and will challenge your requests a lot more if you meet some criteria that I haven't quite figured out. If you can get a clean ip, you should be able to set up a proxy server on it and funnel your requests through that. This has been working for me for some projects but ymmv.

LimLims commented 2 years ago

To clarify, I use puppeteer through a proxy, with header obfuscation. It requires a specific set of things to get past anti-bot measures, and if your requests don't look like they're coming from a real browser you might get flagged.

moonlightelite commented 2 years ago

I played around with the header a bit more, and I realized that Curl and mitmproxy was using HTTP2 . I forced Curl to downgrade to HTTP 1.1 and the request failed (403).

This would explain why humble-steam-key-redeemer failed as Requests/CloudScraper can only use HTTP1.1 .

As for IP blacklisting, I was using my home IP to do the testing. From my testing, the edge server doesn't care about the data in the request message. I was replaying login requests older than 1 hour and humblebundle's server accepted them as valid (and sent me 2-factor codes).

A headless client built on Chrome would, of course, support HTTP2.

moonlightelite commented 2 years ago

Ok since I quit my job yesterday, I have a lot of free time and I'd like to catch up on my humble bundle games.

I already have mitmproxy setup and installed mitmproxy's certificate into my Ubuntu CA store.

I set the env to use the proxy-

export HTTP_PROXY="http://192.168.1.122:8080" export HTTPS_PROXY="http://192.168.1.122:8080"

I installed httpx[http2] and replaced CloudScraper with it in the script.

//humble_session = cloudscraper.CloudScraper() humble_session = httpx.Client(http2=True)

I replaced the request-future/async routines with httpx/asyncio

order_details = []

async def hbrunner(orders): async with httpx.AsyncClient() as client: for order in orders: game = f"{HUMBLE_ORDER_DETAILS_API}{order['gamekey']}?all_tpkds=true" resp = await client.get(game) order_details.append(resp.json())

asyncio.run(hbrunner(orders))

I can confirm the script is working on my machine.

-=FailSpy's Humble Bundle Helper!=-

Humble Email: xxx@xxx.com Password: Please enter the Humble security code: XXXXXXX Successfully signed in on Humble. Getting 155 order details, please wait Welcome to the Humble Exporter! Which key export mode would you like to use?

[1] Auto-Redeem [2] Export keys [3] Humble Choice chooser

Choose 1, 2, or 3:

Now if you would excuse me, I have years of Humble Bundle Monthly games to activate.

kerderf commented 2 years ago

@moonlightelite Can you fork this with those changes? I think I made those same changes and it's still not working connecting for me. I'm wondering if I removed or changed too many lines .

moonlightelite commented 2 years ago

Done. I just tested the modified script again today (with mitmproxy) and it still work.

https://github.com/moonlightelite/humble-steam-key-redeemer

oneandonlyjason commented 2 years ago

Done. I just tested the modified script again today (with mitmproxy) and it still work.

I just testet it with your Fork (you forgot to also update the requirements.txt) and it still doesnt work for me

caraar12345 commented 2 years ago

Done. I just tested the modified script again today (with mitmproxy) and it still work.

I've just had a crack at using this and it didn't seem to be working (even with mitmproxy) - but auth did work so that's a good start!

mitmproxy started showing a heck of a lot of 401s when it went to access the order details however; a separate async httpx client was being created for the order detail collection, meaning it had none of the session data we'd just worked so hard to get 😄

Taking the async out seems to do some good however 👀


I've forked your repo with my changes:

https://github.com/caraar12345/humble-steam-key-redeemer

oneandonlyjason commented 2 years ago

I've forked your repo with my changes:

https://github.com/caraar12345/humble-steam-key-redeemer

This also doesnt workes for me. I suspect that mitmproxy could make the Difference in this Case, but I don't think it should be the goal to install more external software. Especially software that triggers a security warning under Windows.

Could you try without mitmproxy too see if it still works for you then?

caraar12345 commented 2 years ago

I suspect that mitmproxy could make the Difference in this Case, but I don't think it should be the goal to install more external software.

mitmproxy is 100% making the difference. Something about how mitmproxy connects to Humble Bundle/Cloudflare is different compared to direct Python http libraries, and CF seems to let that through.

Fully agree that the goals shouldn't be having to run the script through a proxy - but it definitely works!

NeonLightning commented 2 years ago

Traceback (most recent call last): File "D:\programs\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 740, in humble_login(humble_session) File "D:\programs\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 147, in humble_login login_json = r.json() File "C:\Python310\lib\site-packages\httpx_models.py", line 743, in json return jsonlib.loads(self.text, **kwargs) File "C:\Python310\lib\json__init__.py", line 346, in loads return _default_decoder.decode(s) File "C:\Python310\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Python310\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Done. I just tested the modified script again today (with mitmproxy) and it still work.

https://github.com/moonlightelite/humble-steam-key-redeemer

although tbh idk how to setup mitmproxy properly

DavidSnider commented 2 years ago

@caraar12345 I've got mitmproxy set up and I'm using your fork, but I'm still getting errors trying to log into humble. I've confirmed that logging in to humble bundle via my browser is caught by mtmproxy and works successfully, but trying to use the script just gives me this. Any thoughts? @moonlightelite maybe something I'm doing wrong during script invocation to not successfully hit the proxy?

Password:
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_exceptions.py", line 8, in map_exceptions
    yield
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/backends/sync.py", line 86, in connect_tcp
    sock = socket.create_connection(
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socket.py", line 844, in create_connection
    raise err
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socket.py", line 832, in create_connection
    sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_transports/default.py", line 60, in map_httpcore_exceptions
    yield
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_transports/default.py", line 218, in handle_request
    resp = self._pool.handle_request(req)
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 253, in handle_request
    raise exc
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 237, in handle_request
    response = connection.handle_request(request)
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/http_proxy.py", line 258, in handle_request
    connect_response = self._connection.handle_request(
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 86, in handle_request
    raise exc
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 63, in handle_request
    stream = self._connect(request)
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 111, in _connect
    stream = self._network_backend.connect_tcp(**kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/backends/sync.py", line 86, in connect_tcp
    sock = socket.create_connection(
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/opt/homebrew/lib/python3.9/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
    raise to_exc(exc)
httpcore.ConnectTimeout: timed out

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/doraia/Desktop/humble-steam-key-redeemer-main/humblesteamkeysredeemer.py", line 759, in <module>
    humble_login(humble_session)
  File "/Users/doraia/Desktop/humble-steam-key-redeemer-main/humblesteamkeysredeemer.py", line 145, in humble_login
    csrf_req = session.get(HUMBLE_LOGIN_PAGE)
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 1039, in get
    return self.request(
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 815, in request
    return self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 902, in send
    response = self._send_handling_auth(
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 930, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 967, in _send_handling_redirects
    response = self._send_single_request(request)
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_client.py", line 1003, in _send_single_request
    response = transport.handle_request(request)
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_transports/default.py", line 218, in handle_request
    resp = self._pool.handle_request(req)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/opt/homebrew/lib/python3.9/site-packages/httpx/_transports/default.py", line 77, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.ConnectTimeout: timed out
metafarion commented 2 years ago

Traceback (most recent call last): File "D:\programs\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 740, in humble_login(humble_session) File "D:\programs\humble-steam-key-redeemer-main\humblesteamkeysredeemer.py", line 147, in humble_login login_json = r.json() File "C:\Python310\lib\site-packages\httpx_models.py", line 743, in json return jsonlib.loads(self.text, **kwargs) File "C:\Python310\lib\jsoninit.py", line 346, in loads return _default_decoder.decode(s) File "C:\Python310\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Python310\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

although tbh idk how to setup mitmproxy properly

This is exactly how it's failing for me as well, and I can see simultaneously in the mitmproxy log, a corresponding 403 response to POST https://www.humblebundle.com/processlogin HTTP/2.0 This happens after entering an email/password but before the Humble security code prompt. Is there more configuration that needs to be done in mitmproxy, or should it be enough to simply route the traffic through it?

metafarion commented 1 year ago

Wow @KaiserBh, nice work! #32 fixes the login issue for me and I can actually use the tool now.

oneandonlyjason commented 1 year ago

Yeah tried the #32 Fix a time Ago. This works for me aswell. But i needed to Setup an Ubuntu VM for it. It didnt run on Windows for me. Cant tell why tho

kaiserbh commented 1 year ago

Yeah tried the #32 Fix a time Ago. This works for me aswell. But i needed to Setup an Ubuntu VM for it. It didnt run on Windows for me. Cant tell why tho

Maybe geckodriver wasn't installed properly? Or it wasn't in PATH? Otherwise, check the logs for more information.

DavidSnider commented 1 year ago

This unblocked the login issue, but I'm still running into cloudflare issues. @KaiserBh it seems like this is something you've had to work through as well, do you have any thoughts?

Screenshot 2023-05-01 at 10 13 45 AM
kaiserbh commented 1 year ago

This unblocked the login issue, but I'm still running into cloudflare issues. @KaiserBh it seems like this is something you've had to work through as well, do you have any thoughts?

Screenshot 2023-05-01 at 10 13 45 AM

Hello, I just checked it myself, I believe that's specific to you. I am assuming it's blocked by country/ip address. Try using vpn just to confirm it. I myself don't run into that but it does look like region block or ip address by the looks of it at least. @DavidSnider

DavidSnider commented 1 year ago

Yeah I tried it both with and without a VPN and nothing. I would be surprised if it's a region block - I'm in the northern United States.

oneandonlyjason commented 1 year ago

Hey, 1020 is the Access Denied Error Code Cloudflare hands out when the Website Operator blocked you. This doesnt need to be a IP Address Thing Tho

Edit:

Could be anything really.

Bot Block IP Address Country Browser User-Agent Thread-Score and more...

kaiserbh commented 1 year ago

Yeah I tried it both with and without a VPN and nothing. I would be surprised if it's a region block - I'm in the northern United States.

hmm, have you tried anything else? private mode? Also maybe use a proxy to test it? Then the last thing I think you can do is using TOR

Clear your browser's cache and cookies: Sometimes, old or corrupt data in your browser can trigger false positives.

Otherwise your best shot it's just to contact them.

DavidSnider commented 1 year ago

Switched to a clean browser and nothing - How do I get the steam redeemer to use private mode?

kaiserbh commented 1 year ago

Switched to a clean browser and nothing - How do I get the steam redeemer to use private mode?

Okay I just pushed an update not sure if it will work for you but should try it #32 added option to use tor network also we can't use private browser I realised that we can't save the cookies otherwise. @DavidSnider

DavidSnider commented 1 year ago

I left a comment on your PR because it needed some additional plumbing to get TOR actually utilized for the piece that was failing for me.

However, unfortunately, I'm stiil getting the 1020 somehow, which feels insane.

FailSpy commented 1 year ago

The cloudflare protection that was causing this has been circumvented now. Closing.