get_session.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #!/usr/bin/env python3
  2. import requests
  3. import json
  4. import sys
  5. import pyotp
  6. import cloudscraper
  7. # NOTE: pyotp, requests and cloudscraper are dependencies
  8. # > pip install pyotp requests cloudscraper
  9. TW_CONSUMER_KEY = '3nVuSoBZnx6U4vzUxf5w'
  10. TW_CONSUMER_SECRET = 'Bcs59EFbbsdF6Sl9Ng71smgStWEGwXXKSjYvPVt7qys'
  11. def auth(username, password, otp_secret):
  12. bearer_token_req = requests.post("https://api.twitter.com/oauth2/token",
  13. auth=(TW_CONSUMER_KEY, TW_CONSUMER_SECRET),
  14. headers={"Content-Type": "application/x-www-form-urlencoded"},
  15. data='grant_type=client_credentials'
  16. ).json()
  17. bearer_token = ' '.join(str(x) for x in bearer_token_req.values())
  18. guest_token = requests.post(
  19. "https://api.twitter.com/1.1/guest/activate.json",
  20. headers={
  21. 'Authorization': bearer_token,
  22. "User-Agent": "TwitterAndroid/10.21.0-release.0 (310210000-r-0) ONEPLUS+A3010/9"
  23. }
  24. ).json().get('guest_token')
  25. if not guest_token:
  26. print("Failed to obtain guest token.")
  27. sys.exit(1)
  28. twitter_header = {
  29. 'Authorization': bearer_token,
  30. "Content-Type": "application/json",
  31. "User-Agent": "TwitterAndroid/10.21.0-release.0 (310210000-r-0) ONEPLUS+A3010/9 (OnePlus;ONEPLUS+A3010;OnePlus;OnePlus3;0;;1;2016)",
  32. "X-Twitter-API-Version": '5',
  33. "X-Twitter-Client": "TwitterAndroid",
  34. "X-Twitter-Client-Version": "10.21.0-release.0",
  35. "OS-Version": "28",
  36. "System-User-Agent": "Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3010 Build/PKQ1.181203.001)",
  37. "X-Twitter-Active-User": "yes",
  38. "X-Guest-Token": guest_token,
  39. "X-Twitter-Client-DeviceID": ""
  40. }
  41. scraper = cloudscraper.create_scraper()
  42. scraper.headers = twitter_header
  43. task1 = scraper.post(
  44. 'https://api.twitter.com/1.1/onboarding/task.json',
  45. params={
  46. 'flow_name': 'login',
  47. 'api_version': '1',
  48. 'known_device_token': '',
  49. 'sim_country_code': 'us'
  50. },
  51. json={
  52. "flow_token": None,
  53. "input_flow_data": {
  54. "country_code": None,
  55. "flow_context": {
  56. "referrer_context": {
  57. "referral_details": "utm_source=google-play&utm_medium=organic",
  58. "referrer_url": ""
  59. },
  60. "start_location": {
  61. "location": "deeplink"
  62. }
  63. },
  64. "requested_variant": None,
  65. "target_user_id": 0
  66. }
  67. }
  68. )
  69. scraper.headers['att'] = task1.headers.get('att')
  70. task2 = scraper.post(
  71. 'https://api.twitter.com/1.1/onboarding/task.json',
  72. json={
  73. "flow_token": task1.json().get('flow_token'),
  74. "subtask_inputs": [{
  75. "enter_text": {
  76. "suggestion_id": None,
  77. "text": username,
  78. "link": "next_link"
  79. },
  80. "subtask_id": "LoginEnterUserIdentifier"
  81. }]
  82. }
  83. )
  84. task3 = scraper.post(
  85. 'https://api.twitter.com/1.1/onboarding/task.json',
  86. json={
  87. "flow_token": task2.json().get('flow_token'),
  88. "subtask_inputs": [{
  89. "enter_password": {
  90. "password": password,
  91. "link": "next_link"
  92. },
  93. "subtask_id": "LoginEnterPassword"
  94. }],
  95. }
  96. )
  97. for t3_subtask in task3.json().get('subtasks', []):
  98. if "open_account" in t3_subtask:
  99. return t3_subtask["open_account"]
  100. elif "enter_text" in t3_subtask:
  101. response_text = t3_subtask["enter_text"]["hint_text"]
  102. totp = pyotp.TOTP(otp_secret)
  103. generated_code = totp.now()
  104. task4resp = scraper.post(
  105. "https://api.twitter.com/1.1/onboarding/task.json",
  106. json={
  107. "flow_token": task3.json().get("flow_token"),
  108. "subtask_inputs": [
  109. {
  110. "enter_text": {
  111. "suggestion_id": None,
  112. "text": generated_code,
  113. "link": "next_link",
  114. },
  115. "subtask_id": "LoginTwoFactorAuthChallenge",
  116. }
  117. ],
  118. }
  119. )
  120. task4 = task4resp.json()
  121. for t4_subtask in task4.get("subtasks", []):
  122. if "open_account" in t4_subtask:
  123. return t4_subtask["open_account"]
  124. return None
  125. if __name__ == "__main__":
  126. if len(sys.argv) != 5:
  127. print("Usage: python3 get_session.py <username> <password> <2fa secret> <path>")
  128. sys.exit(1)
  129. username = sys.argv[1]
  130. password = sys.argv[2]
  131. otp_secret = sys.argv[3]
  132. path = sys.argv[4]
  133. result = auth(username, password, otp_secret)
  134. if result is None:
  135. print("Authentication failed.")
  136. sys.exit(1)
  137. session_entry = {
  138. "oauth_token": result.get("oauth_token"),
  139. "oauth_token_secret": result.get("oauth_token_secret")
  140. }
  141. try:
  142. with open(path, "a") as f:
  143. f.write(json.dumps(session_entry) + "\n")
  144. print("Authentication successful. Session appended to", path)
  145. except Exception as e:
  146. print(f"Failed to write session information: {e}")
  147. sys.exit(1)