I'm currently trying to create a Python script that, using only a steam username and (encrypted) password, will continually change the user's Steam profile picture to a random (sfw) image at a specified time interval.
I've accomplished this before using ValvePython, but using that library is very hard, as it constantly crashes when connections are lost and is only successful 1/2 times I run it, so I'm trying to make my own script isolating the specific requests I want to send and copy some code from the library.
Steam's /actions/dologin and /actions/FileUploader seem to be not very well documented, and after searching tirelessly and being unable to find an answer, I'm wondering if you guys could let me know if what I'm trying to do is possible or what I'm doing wrong. I'm trying to see if I can use the token_secure returned from /dologin combined with my own generated sessionid as cookies in the /FileUploader request.
Here's the code I have so far:
from urllib.request import urlopen
from urllib.request import Request
from urllib.parse import urlencode
from bs4 import BeautifulSoup
import json
import random
import os
import shutil
import time
import requests
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import http.cookiejar
from binascii import hexlify
import cryptography.hazmat.backends
from cryptography.hazmat.primitives.hashes import Hash, SHA1
# Will use getpass in the future
username = ""
password = ""
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
url = 'https://steamcommunity.com/login/getrsakey/'
values = {'username' : username, 'donotcache' : str(int(time.time()*1000))}
headers = { 'User-Agent' : user_agent }
post = urlencode(values).encode("utf-8")
req = Request(url, post, headers)
response = urlopen(req).read()
rsaData = json.loads(response)
mod = int(str(rsaData["publickey_mod"]), 16)
exp = int(str(rsaData["publickey_exp"]), 16)
rsa = RSA.construct((mod, exp))
cipher = PKCS1_v1_5.new(rsa)
url = 'https://steamcommunity.com/login/dologin/'
values = {
'username' : username,
"password": base64.b64encode(cipher.encrypt(password.encode("utf-8"))),
"emailauth": "",
"loginfriendlyname": "",
"captchagid": "-1",
"captcha_text": "",
"emailsteamid": "",
"rsatimestamp": rsaData["timestamp"],
"remember_login": False,
"donotcache": str(int(time.time()*1000)),
"twofactorcode": ""
}
headers = { 'User-Agent' : user_agent }
post = urlencode(values).encode("utf-8")
req = Request(url, post, headers)
response = urlopen(req).read()
data = json.loads(response)
if data["requires_twofactor"]:
values["twofactorcode"] = input("Enter 2FA code: ")
# Will simplify later
post = urlencode(values).encode("utf-8")
req = Request(url, post, headers)
response = urlopen(req).read()
data = json.loads(response)
# Copied from ValvePython to generate a session id
backend = cryptography.hazmat.backends.default_backend()
random_bytes = os.urandom(32)
sha = Hash(SHA1(), backend)
sha.update(random_bytes)
sessionid = hexlify(sha.finalize())[:24].decode('ascii')
STEAM_ID = data["transfer_parameters"]["steamid"]
cookies = {'steamLoginSecure': data["transfer_parameters"]["token_secure"],
'sessionid': sessionid}
wordsUrl = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain"
txt = urlopen(wordsUrl).read()
WORDS = txt.splitlines()
url = 'https://steamcommunity.com/actions/FileUploader'
data = {'sessionid': cookies.get('sessionid'),
'doSub': '1'}
DIR = os.getcwd() + "/images/test.jpg"
sleepTime = int(input("Enter time interval: "))
# Code to scrape images not really a concern for this question
while True:
searchQuery = str(random.choice(WORDS))
searchQuery = searchQuery[2:len(searchQuery)-1]
imageResultNum = random.randint(0,5)
googleUrl = "https://www.google.co.in/search?q=" + searchQuery + "&source=lnms&tbm=isch"
header={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"}
soup = BeautifulSoup(urlopen(Request(googleUrl,headers=header)), 'html.parser')
ActualImages=[]
imageResultCounter = 0
for a in soup.find_all("div",{"class":"rg_meta"}):
if imageResultCounter <= imageResultNum:
link, Type = json.loads(a.text)["ou"], json.loads(a.text)["ity"]
ActualImages.append((link,Type))
imageResultCounter += 1
for i,(img,Type) in enumerate(ActualImages[:imageResultNum]):
try:
raw_img = requests.get(img,stream=True)
with open(DIR, 'wb') as out_file:
shutil.copyfileobj(raw_img.raw, out_file)
except Exception as e:
print("could not load: " + img)
print(e)
image = open('images/test.jpg','rb')
params = {'type': 'player_avatar_image', 'sId': STEAM_ID}
r = requests.post(url=url,params=params,files={'avatar':image},data=data,cookies=cookies)
print(str(r) + " for: " + searchQuery)
# Always returns #Error_BadOrMissingSteamID
if "#Error_BadOrMissingSteamID" in r.text:
print("#Error_BadOrMissingSteamID")
time.sleep(sleepTime)
Here's an example response from /dologin (changed a few letters/numbers):
{'success': True,
'requires_twofactor': False,
'login_complete': True,
'transfer_urls': ['https://store.steampowered.com/login/transfer', 'https://help.steampowered.com/login/transfer'],
'transfer_parameters':
{'steamid': 'my steam id',
'token_secure': 'F61A90B78ADB0C496FA9EB13AF8F3CB87EAC85D2',
'auth': 'dce9fc3fcc1746b0df65fc1b5850a94d',
'remember_login': False,
'webcookie': 'DD692F1946AA29443CE3B71C5F7657C9DE174FD3'}
}
So trying to use a sessionid generated by me and the token_secure passed back don't work when passed into the /FileUploader request. Is the token_secure not valid for requests like changing my profile picture? Do I need to use webcookie at all? Would the steamLoginSecure need to be encoded at all (I notice that valid ones have %7C occur once or twice in most of them)?
Any help would be appreciated. Thanks.
Aucun commentaire:
Enregistrer un commentaire