Last active
August 22, 2023 17:58
-
-
Save BitTheByte/88437dbb3e751aa1dc9b66401d45ccba to your computer and use it in GitHub Desktop.
Revisions
-
BitTheByte revised this gist
Apr 27, 2020 . 1 changed file with 60 additions and 58 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from base64 import b64decode,b64encode from urllib.parse import quote,parse_qs,urlsplit,urlparse from random import randint from bs4 import BeautifulSoup import calendar @@ -19,15 +19,12 @@ def __init__(self): self.session = requests.Session() self.access_token = None self.guest_token = None self.challenged = False self.challenge_type = None self.challenge = None self.on_challenge = None self.xauth = None def oauth_signature(self,request,oauth_secret): key = bytes(self.twitter_android_secret +"&"+ oauth_secret, 'UTF-8') message = bytes(request, 'UTF-8') @@ -69,29 +66,59 @@ def xauth_login(self,username,password): "ui_metrics":"" }).json() self.xauth = auth if "login_verification_request_url" in auth.keys(): self.challenged = True self.challenge = auth self.challenge_type = parse_qs(urlparse(auth["login_verification_request_url"]).query)['challenge_type'][0] return auth def challenge_access_token(self,user_id,request_id): oauth_nonce = ''.join([str(randint(0,9)) for n in range(31)]) oauth_timestamp = str(calendar.timegm(time.gmtime())) return self.session.post("https://api.twitter.com/oauth/access_token",data={ "x_auth_mode":"client_auth", "x_auth_login_verification":"1", "x_auth_login_challenge": "1", "send_error_codes":"true", "login_verification_user_id": user_id, "login_verification_request_id": request_id }, headers = { "Authorization":'OAuth realm="http://api.twitter.com/", oauth_version="1.0", oauth_nonce="{oauth_nonce}", oauth_timestamp="{oauth_timestamp}", oauth_signature="{oauth_signature}", oauth_consumer_key="{oauth_consumer_key}", oauth_signature_method="HMAC-SHA1"'.format( oauth_nonce = oauth_nonce, oauth_timestamp = oauth_timestamp, oauth_consumer_key = self.twitter_android_key, oauth_signature = self.signature_message(url="https://api.twitter.com/oauth/access_token",params={ "login_verification_request_id": request_id, "login_verification_user_id": user_id, "oauth_consumer_key":self.twitter_android_key, "oauth_nonce": oauth_nonce, "oauth_signature_method":"HMAC-SHA1", "oauth_timestamp": oauth_timestamp, "oauth_version":"1.0", "send_error_codes":"true", "x_auth_login_challenge":"1", "x_auth_login_verification":"1", "x_auth_mode":"client_auth", },oauth_secret="") ), "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", }).json() def solve_challenge(self,challenge,answer): self.has_challenge = True challenge_url = challenge["login_verification_request_url"] request_id = challenge["login_verification_request_id"] response = self.session.get(challenge_url) soup = BeautifulSoup(response.content, "lxml") authenticity_token = soup.select_one("input[name=authenticity_token]")["value"] challenge_id = soup.select_one("input[name=challenge_id]")["value"] user_id = soup.select_one("input[name=user_id]")["value"] self.challenge_type = soup.select_one("input[name=challenge_type]")["value"] data = { 'authenticity_token':authenticity_token, 'challenge_id':challenge_id, @@ -100,40 +127,13 @@ def solve_challenge(self,xauth): 'platform':'mobile', 'redirect_after_login':'', 'remember_me':'true', 'challenge_response':answer, } self.session.post("https://twitter.com/account/login_challenge",data=data) twitter_session = self.challenge_access_token(user_id, request_id) self.xauth = twitter_session return twitter_session def auth_headers(self,oauth_nonce,oauth_timestamp,oauth_signature,skip_token=False): @@ -186,9 +186,9 @@ def tweet(self, text): oauth_nonce= oauth_nonce, oauth_timestamp= oauth_timestamp, oauth_signature= self.signature_message( url= api_statuses, params= params, oauth_secret= self.xauth['oauth_token_secret'] ) ) @@ -197,9 +197,11 @@ def tweet(self, text): return self.session.post(api_statuses,headers=headers,data=post_params.encode('utf-8'),verify=False).json() api = Twitter() result = api.xauth_login("username","password") if api.challenged: answer = input("code:").strip() api.solve_challenge(result,answer) api.tweet("XXXXXXXXXXXXXXXXXXXXX") -
BitTheByte created this gist
Apr 27, 2020 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,205 @@ # -*- coding: utf-8 -*- from base64 import b64decode,b64encode from urllib.parse import quote,parse_qs,urlsplit from random import randint from bs4 import BeautifulSoup import calendar import requests import hashlib import base64 import time import hmac import types class Twitter(object): def __init__(self): self.twitter_android_secret = "Bcs59EFbbsdF6Sl9Ng71smgStWEGwXXKSjYvPVt7qys" self.twitter_android_key = "3nVuSoBZnx6U4vzUxf5w" self.session = requests.Session() self.access_token = None self.guest_token = None self.has_challenge = False self.challenge_type = None self.challenge = None self.on_challenge = None self.xauth = None def login(self,username,password): self.xauth = self.xauth_login(username,password) def oauth_signature(self,request,oauth_secret): key = bytes(self.twitter_android_secret +"&"+ oauth_secret, 'UTF-8') message = bytes(request, 'UTF-8') digester = hmac.new(key, message, hashlib.sha1) signature1 = digester.digest() signature2 = base64.urlsafe_b64encode(signature1) signature2 = str(signature2, 'UTF-8').replace("-","+").replace("_","/") return quote(signature2,safe='') def signature_message(self,url,params,oauth_secret,method="POST"): header = method + "&" + quote(url,safe='') + "&" body = bytes() for key,value in params.items(): body += bytes(key,"UTF-8") + b"=" + bytes(value,"UTF-8") + b"&" body = body[:-1] return self.oauth_signature(header + quote(body,safe=''),oauth_secret) def xauth_login(self,username,password): self.access_token = self.session.post("https://api.twitter.com/oauth2/token",params = {'grant_type':'client_credentials'}, headers = { "Accept": "application/json", "Authorization": "Basic " + b64encode((self.twitter_android_key + ":" + self.twitter_android_secret).encode("utf8")).decode("utf8") } ).json()["access_token"] self.guest_token = self.session.post("https://api.twitter.com/1.1/guest/activate.json",headers={"Authorization": "Bearer " + self.access_token}).json()["guest_token"] auth = self.session.post("https://api.twitter.com/auth/1/xauth_password.json",headers={ "Authorization": "Bearer " + self.access_token, "X-Guest-Token": self.guest_token }, params = { "x_auth_identifier":username, "x_auth_password":password, "send_error_codes":"true", "x_auth_login_challenge":"1", "x_auth_login_verification":"1", "x_auth_country_code":"US", "ui_metrics":"" }).json() if "login_verification_request_type" in auth.keys(): self.challenge = auth return self.solve_challenge(auth) return auth def solve_challenge(self,xauth): self.has_challenge = True oauth_nonce = ''.join([str(randint(0,9)) for n in range(31)]) oauth_timestamp = str(calendar.timegm(time.gmtime())) challenge = xauth["login_verification_request_url"] request_id = xauth["login_verification_request_id"] response = self.session.get(challenge) soup = BeautifulSoup(response.content, "lxml") authenticity_token = soup.select_one("input[name=authenticity_token]")["value"] challenge_id = soup.select_one("input[name=challenge_id]")["value"] user_id = soup.select_one("input[name=user_id]")["value"] self.challenge_type = soup.select_one("input[name=challenge_type]")["value"] if type(self.on_challenge) == types.FunctionType: challenge_response = self.on_challenge(self.challenge_type) else: challenge_response = input("[%s] Challenge Answer: " % self.challenge_type) data = { 'authenticity_token':authenticity_token, 'challenge_id':challenge_id, 'user_id':user_id, 'challenge_type':self.challenge_type, 'platform':'mobile', 'redirect_after_login':'', 'remember_me':'true', 'challenge_response':challenge_response, } self.session.post("https://twitter.com/account/login_challenge",data=data) return self.session.post("https://api.twitter.com/oauth/access_token",data={ "x_auth_mode":"client_auth", "x_auth_login_verification":"1", "x_auth_login_challenge": "1", "send_error_codes":"true", "login_verification_user_id": user_id, "login_verification_request_id": request_id }, headers = { "Authorization":'OAuth realm="http://api.twitter.com/", oauth_version="1.0", oauth_nonce="{oauth_nonce}", oauth_timestamp="{oauth_timestamp}", oauth_signature="{oauth_signature}", oauth_consumer_key="{oauth_consumer_key}", oauth_signature_method="HMAC-SHA1"'.format( oauth_nonce = oauth_nonce, oauth_timestamp = oauth_timestamp, oauth_consumer_key = self.twitter_android_key, oauth_signature = self.signature_message(url="https://api.twitter.com/oauth/access_token",params={ "login_verification_request_id": request_id, "login_verification_user_id": user_id, "oauth_consumer_key":self.twitter_android_key, "oauth_nonce": oauth_nonce, "oauth_signature_method":"HMAC-SHA1", "oauth_timestamp": oauth_timestamp, "oauth_version":"1.0", "send_error_codes":"true", "x_auth_login_challenge":"1", "x_auth_login_verification":"1", "x_auth_mode":"client_auth", },oauth_secret="") ), "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", }).json() def auth_headers(self,oauth_nonce,oauth_timestamp,oauth_signature,skip_token=False): return { "Authorization": 'OAuth realm="http://api.twitter.com/", oauth_version="1.0", oauth_token="{oauth_token}", oauth_nonce="{oauth_nonce}", oauth_timestamp="{oauth_timestamp}", oauth_signature="{oauth_signature}", oauth_consumer_key="{oauth_consumer_key}", oauth_signature_method="{oauth_signature_method}"'.format( oauth_token = self.xauth["oauth_token"] if not skip_token else "", oauth_nonce = oauth_nonce, oauth_timestamp = oauth_timestamp, oauth_signature = oauth_signature, oauth_consumer_key = self.twitter_android_key, oauth_signature_method = "HMAC-SHA1" ), "User-Agent": "TwitterAndroid/8.40.0-release.02 (18400002-r-2) Nexus 7/7.0 (asus;Nexus 7;google;nakasi;0;;0;2012)", "X-Twitter-Active-User": "yes", "X-Twitter-API-Version": "5", "X-Twitter-Client": "TwitterAndroid", "X-Twitter-Client-Language": "en-US", "Accept": "application/json", } def tweet(self, text): api_statuses = "https://api.twitter.com/1.1/statuses/update.json" oauth_nonce = ''.join([str(randint(0,9)) for n in range(31)]) oauth_timestamp = str(calendar.timegm(time.gmtime())) params = { "batch_mode":"off", "cards_platform":"Android-12", "earned_read":"true", "enable_dm_commands":"false", "ext":"mediaRestrictions%2CaltText%2CmediaStats%2CmediaColor%2Cinfo360%2CcameraMoment%2ChighlightedLabel%2Cmaster_playlist_only", "include_blocked_by":"true", "include_blocking":"true", "include_cards":"true", "include_entities":"true", "include_media_features":"true", "include_reply_count":"true", "oauth_consumer_key":self.twitter_android_key, "oauth_nonce": oauth_nonce, "oauth_signature_method":"HMAC-SHA1", "oauth_timestamp":oauth_timestamp, "oauth_token": self.xauth["oauth_token"], "oauth_version":"1.0", "send_error_codes":"true", "status": quote(text,safe=''), "tweet_mode":"extended" } headers = self.auth_headers( oauth_nonce= oauth_nonce, oauth_timestamp= oauth_timestamp, oauth_signature= self.signature_message( url = api_statuses, params = params, oauth_secret = self.xauth['oauth_token_secret'] ) ) headers["Content-Type"] = "application/x-www-form-urlencoded" post_params = '&'.join([k + u"=" + v for k,v in params.items()]) return self.session.post(api_statuses,headers=headers,data=post_params.encode('utf-8'),verify=False).json() t = Twitter() t.on_challenge = lambda type: "j75285eh" if t.has_challenge: print(t.challenge_type, t.challenge, t.xauth) t.login("[email protected]","password") t.tweet("Hello from python!")